html: $(HTML)
%.eps: %.fig
- -fig2dev -Leps $< $@
+ fig2dev -Leps $< $@
%.jpeg: %.fig
- -fig2dev -Ljpeg $< $@
+ fig2dev -Ljpeg $< $@
%.sgml: %.c
echo "<programlisting>" > $@
$(PERL) $(TOPDIR)/scripts/split-man $(TOPDIR)/Documentation/man
parportbook: $(JPG-parportbook)
-parportbook.ps: $(EPS-parportbook)
+parportbook.ps parportbook.pdf: $(EPS-parportbook)
parportbook.sgml: parportbook.tmpl $(TOPDIR)/drivers/parport/init.c
$(TOPDIR)/scripts/docgen $(TOPDIR)/drivers/parport/init.c <$< >$@
</listitem></varlistentry>
+ <varlistentry><term><constant>PPGETMODE</constant></term>
+ <listitem>
+
+ <para>
+ Retrieves the current IEEE 1284 mode to use for
+ <function>read</function> and <function>write</function>.
+ </para>
+
+ </listitem></varlistentry>
+
<varlistentry><term><constant>PPGETTIME</constant></term>
<listitem>
</listitem></varlistentry>
+ <varlistentry><term><constant>PPGETMODES</constant></term>
+ <listitem>
+
+ <para>
+ Retrieves the capabilities of the hardware (i.e. the
+ <structfield>modes</structfield> field of the
+ <structname>parport</structname> structure).
+ </para>
+
+ </listitem></varlistentry>
+
+ <varlistentry><term><constant>PPSETFLAGS</constant></term>
+ <listitem>
+
+ <para>
+ Sets flags on the <literal>ppdev</literal> device which can
+ affect future I/O operations. Available flags are:
+ </para>
+
+ <itemizedlist spacing=compact>
+ <listitem><para>
+ <constant>PP_FASTWRITE</constant></para></listitem>
+ <listitem><para>
+ <constant>PP_FASTREAD</constant></para></listitem>
+ <listitem><para>
+ <constant>PP_W91284PIC</constant></para></listitem>
+ </itemizedlist>
+
+ </listitem></varlistentry>
+
<varlistentry><term><constant>PPWCONTROL</constant></term>
<listitem>
http://www.cs.cmu.edu/~wearable/software/assabet.html
-To build the kernel:
+Building the kernel
+-------------------
+
+To build the kernel with current defaults:
make assabet_config
- make config
- [accept all defaults]
+ make oldconfig
make dep
make zImage
-Typically, you'll need angelboot to load the kernel.
-The following angelboot.opt file should be used:
+The resulting kernel image should be available in linux/arch/arm/boot/zImage.
+
+
+Installing a bootloader
+-----------------------
+
+A couple of bootloaders able to boot Linux on Assabet are available:
+
+BLOB (http://www.lart.tudelft.nl/lartware/blob/)
+
+ BLOB is a bootloader used within the LART project. Some contributed
+ patches were merged into BLOB to add support for Assabet.
+
+Compaq's Bootldr + John Dorsey's patch for Assabet support
+(http://www.handhelds.org/Compaq/bootldr.html)
+(http://www.wearablegroup.org/software/bootldr/)
+
+ Bootldr is the bootloader developed by Compaq for the iPAQ Pocket PC.
+ John Dorsey has produced add-on patches to add support for Assabet and
+ the JFFS filesystem.
+
+RedBoot (http://sources.redhat.com/redboot/)
+
+ RedBoot is a bootloader developed by Red Hat based on the eCos RTOS
+ hardware abstraction layer. It supports Assabet amongst many other
+ hardware platforms.
+
+RedBoot is currently the recommended choice since it's the only one to have
+networking support, and is the most actively maintained.
+
+Brief examples on how to boot Linux with RedBoot are shown below. But first
+you need to have RedBoot installed in your flash memory. A known to work
+precompiled RedBoot binary is available from the following location:
+
+ftp://ftp.netwinder.org/users/n/nico/
+ftp://ftp.arm.linux.org.uk/pub/linux/arm/people/nico/
+ftp://ftp.handhelds.org/pub/linux/arm/sa-1100-patches/
+
+Look for redboot-assabet*.tgz. Some installation infos are provided in
+redboot-assabet*.txt.
+
+
+Initial RedBoot configuration
+-----------------------------
+
+The commands used here are explained in The RedBoot User's Guide available
+on-line at http://sources.redhat.com/ecos/docs-latest/redboot/redboot.html.
+Please refer to it for explanations.
+
+If you have a CF network card (my Assabet kit contained a CF+ LP-E from
+Socket Communications Inc.), you should strongly consider using it for TFTP
+file transfers. You must insert it before RedBoot runs since it can't detect
+it dynamically.
+
+To initialize the flash directory:
+
+ fis init -f
+
+To initialize the non-volatile settings, like whether you want to use BOOTP or
+a static IP address, etc, use this command:
+
+ fconfig -i
+
+
+Writing a kernel image into flash
+---------------------------------
+
+First, the kernel image must be loaded into RAM. If you have the zImage file
+available on a TFTP server:
+
+ load zImage -r -b 0x100000
+
+If you rather want to use Y-Modem upload over the serial port:
+
+ load -m ymodem -r -b 0x100000
+
+To write it to flash:
+
+ fis create "Linux kernel" -b 0x100000 -l 0xc0000
+
+
+Booting the kernel
+------------------
+
+The kernel still requires a filesystem to boot. A ramdisk image can be loaded
+as follows:
+
+ load ramdisk_image.gz -r -b 0x800000
+
+Again, Y-Modem upload can be used instead of TFTP by replacing the file name
+by '-y ymodem'.
+
+Now the kernel can be retrieved from flash like this:
+
+ fis load "Linux kernel"
+
+or loaded as described previously. To boot the kernel:
+
+ exec -b 0x100000 -l 0xc0000
+
+The ramdisk image could be stored into flash as well, but there are better
+solutions for on-flash filesystems as mentioned below.
+
+
+Using JFFS2
+-----------
+
+Using JFFS2 (the Second Journaling Flash File System) is probably the most
+convenient way to store a writable filesystem into flash. JFFS2 is used in
+conjunction with the MTD layer which is responsible for low-level flash
+management. More information on the Linux MTD can be found on-line at:
+http://www.linux-mtd.infradead.org/. A JFFS howto with some infos about
+creating JFFS/JFFS2 images is available from the same site.
+
+For instance, a sample JFFS2 image can be retrieved from the same FTP sites
+mentioned below for the precompiled RedBoot image.
+
+To load this file:
+
+ load sample_img.jffs2 -r -b 0x100000
+
+The result should look like:
+
+RedBoot> load sample_img.jffs2 -r -b 0x100000
+Raw file loaded 0x00100000-0x00377424
+
+Now we must know the size of the unallocated flash:
+
+ fis free
+
+Result:
+
+RedBoot> fis free
+ 0x500E0000 .. 0x503C0000
+
+The values above may be different depending on the size of the filesystem and
+the type of flash. See their usage below as an example and take care of
+substituting yours appropriately.
+
+We must determine some values:
+
+size of unallocated flash: 0x503c0000 - 0x500e0000 = 0x2e0000
+size of the filesystem image: 0x00377424 - 0x00100000 = 0x277424
+
+We want to fit the filesystem image of course, but we also want to give it all
+the remaining flash space as well. To write it:
+
+ fis unlock -f 0x500E0000 -l 0x2e0000
+ fis erase -f 0x500E0000 -l 0x2e0000
+ fis write -b 0x100000 -l 0x277424 -f 0x500E0000
+ fis create "JFFS2" -n -f 0x500E0000 -l 0x2e0000
+
+Now the filesystem is associated to a MTD "partition" once Linux has discovered
+what they are in the boot process. From Redboot, the 'fis list' command
+displays them:
+
+RedBoot> fis list
+Name FLASH addr Mem addr Length Entry point
+RedBoot 0x50000000 0x50000000 0x00020000 0x00000000
+RedBoot config 0x503C0000 0x503C0000 0x00020000 0x00000000
+FIS directory 0x503E0000 0x503E0000 0x00020000 0x00000000
+Linux kernel 0x50020000 0x00100000 0x000C0000 0x00000000
+JFFS2 0x500E0000 0x500E0000 0x002E0000 0x00000000
+
+However Linux should display something like:
+
+SA1100 flash: probing 32-bit flash bus
+SA1100 flash: Found 2 x16 devices at 0x0 in 32-bit mode
+Using RedBoot partition definition
+Creating 5 MTD partitions on "SA1100 flash":
+0x00000000-0x00020000 : "RedBoot"
+0x00020000-0x000e0000 : "Linux kernel"
+0x000e0000-0x003c0000 : "JFFS2"
+0x003c0000-0x003e0000 : "RedBoot config"
+0x003e0000-0x00400000 : "FIS directory"
+
+What's important here is the position of the partition we are interested in,
+which is the third one. Within Linux, this correspond to /dev/mtdblock2.
+Therefore to boot Linux with the kernel and its root filesystem in flash, we
+need this RedBoot command:
+
+ fis load "Linux kernel"
+ exec -b 0x100000 -l 0xc0000 -c "root=/dev/mtdblock2"
+
+Of course other filesystems than JFFS might be used, like cramfs for example.
+You might want to boot with a root filesystem over NFS, etc. It is also
+possible, and sometimes more convenient, to flash a filesystem directly from
+within Linux while booted from a ramdisk or NFS. The Linux MTD repository has
+many tools to deal with flash memory as well, to erase it for example. JFFS2
+can then be mounted directly on a freshly erased partition and files can be
+copied over directly. Etc...
+
+
+RedBoot scripting
+-----------------
+
+All the commands above aren't so useful if they have to be typed in every
+time the Assabet is rebooted. Therefore it's possible to automatize the boot
+process using RedBoot's scripting capability.
+
+For example, I use this to boot Linux with both the kernel and the ramdisk
+images retrieved from a TFTP server on the network:
+
+RedBoot> fconfig
+Run script at boot: false true
+Boot script:
+Enter script, terminate with empty line
+>> load zImage -r -b 0x100000
+>> load ramdisk_ks.gz -r -b 0x800000
+>> exec -b 0x100000 -l 0xc0000
+>>
+Boot script timeout (1000ms resolution): 3
+Use BOOTP for network configuration: true
+GDB connection port: 9000
+Network debug at boot time: false
+Update RedBoot non-volatile configuration - are you sure (y/n)? y
+
+Then, rebooting the Assabet is just a matter of waiting for the login prompt.
+
+
+
+Nicolas Pitre
+nico@cam.org
+June 12, 2001
+
+
+Status of peripherals in -rmk tree
+----------------------------------
+
+Assabet:
+ Serial ports:
+ Radio: TX, RX, CTS, DSR, DCD, RI
+ COM: TX, RX, CTS, DSR, DCD, RTS, DTR, PM
+ I2C: TX, RX
+ L3: No
------ begin angelboot.opt -----
-base 0xc0008000
-entry 0xc0008000
-r0 0x00000000
-r1 0x00000019
-device /dev/ttyS1
-options "9600 8N1"
-baud 115200
-otherfile ramdisk_img.gz
-otherbase 0xc0800000
-exec minicom
------ end angelboot.opt -----
+ Video:
+ LCD: PM
+ Video out: Not fully
+ Touchscreen: No
-Then load the kernel and ramdisk with:
+ Audio:
+ Codec: No
+ POTS: No
- angelboot -f angelboot.opt zImage
+ Other:
+ PCMCIA: Yes
+ USB: No
-Here it is assumed that your Assabet is connected to ttyS1 and that
-minicom is preconfigured with /dev/ttyS1, 9600 baud, 8N1, no flow control
-by default.
+Neponset:
+ Serial ports:
+ COM1,2: TX, RX, CTS, DSR, DCD, RTS, DTR
-This is work in progress...
+More stuff can be found in the -np (Nicolas Pitre's) tree.
-Please send any patches to nico@cam.org.
--- /dev/null
+Support functions for the SA11x0 internal DMA channels
+======================================================
+
+Nicolas Pitre <nico@cam.org>
+Last updated: 2001/07/15
+
+
+The DMA controller consists of six independent DMA channels. Each channel
+can be configured to service any of the serial controllers. Two channels
+are required to service a full-duplex serial controller. The DMA
+controller is intended to relieve the processor of the interrupt overhead
+in servicing these ports with programmed I/ O.
+
+If desired, any or all peripherals (except the UDC) may be serviced with
+programmed I/ O instead of DMA. Each peripheral is capable of requesting
+processor service through its own interrupt lines or through a DMA
+request.
+
+A set of functions is provided to support drivers working with DMA buffers
+through a generic interface for (wishfully) all DMA usages. Those
+functions will take care of buffer queueing and splitting, DMA register
+management, interrupt handling, etc.
+
+
+SA11x0 DMA API
+--------------
+
+Here is the description for the DMA API.
+
+
+int sa1100_request_dma( dmach_t *channel, const char *device_id,
+ dma_device_t device );
+
+This function will search for a free DMA channel and returns the channel
+number in '*channel'. 'device_id' should point to a string identifying
+the DMA usage or device (mainly for /proc). 'device' is the SA11x0
+peripheral's ports. Note that reading from a port and writing to the
+same port are actually considered as two different streams requiring
+two DMA channels with their own device type. All possible dma_device_t
+are defined in include/asm-arm/arch-sa1100/dma.h. If no channel is
+available, or if the desired device is already in use by another DMA
+channel, then an error code is returned. This function must be called
+before any other DMA calls.
+
+
+int sa1100_dma_queue_buffer( dmach_t channel, void *buf_id,
+ dma_addr_t data, int size );
+
+This function enqueue the specified buffer for DMA processing. The buffer
+will be transmitted or filled with incoming data depending on the channel
+configuration made through sa1100_dma_set_device(). If the queue is
+empty, DMA starts immediately on the given buffer.
+
+Arguments are:
+
+dmach_t channel: the channel number.
+void *buf_id: a buffer identification known by the caller.
+dma_addr_t data: the buffer's physical address.
+int size: the buffer size in bytes.
+
+Note here the dma_addr_t which is not the same as the virtual address as
+returned by kmalloc() and friends. The DMA controller must be given a
+physical address to a buffer which is not cached bye the CPU data cache.
+To get such address, the DMA mapping functions (see
+Documentation/DMA-mapping.txt) are recommended. The only relevant
+functions are pci_alloc_consistent(), pci_map_single() and their unmap
+counterparts. The PCI dev argument is NULL of course.
+
+There is no restriction on the buffer size. The DMA code will split it up
+internally to acommodate the DMA controller as needed. If the buffer
+can't be enqueued the appropriate error code is returned.
+
+
+int sa1100_dma_set_callback( dmach_t channel, dma_callback_t cb );
+
+As soon as the DMa completes with a buffer, a callback function is used to
+notify the driver which would have registered one. The callback function
+is prototyped as:
+
+void dma_callback( void *buf_id, int size );
+
+The 'buf_id' argument is the buffer identifier as passed to
+sa1100_dma_queue_buffer(). The 'size' argument is the number of bytes the
+DMA processed (should be the same as the buffer size).
+
+Note that this callback function is called while in interrupt context.
+So it has to be small and efficient while posponing more complex
+processing to a bottom-half function or similar. All
+restrictions for interrupt handlers still apply.
+
+
+int sa1100_dma_get_current( dmach_t channel, void **buf_id,
+ dma_addr_t *addr );
+
+This returns the buffer ID and the DMA address pointer within the buffer
+currently being processed. If no such buffer is currently processed, an
+error code is returned. This is useful for mmap()'ed buffers like in
+audio drivers.
+
+
+int sa1100_dma_stop( dmach_t channel );
+
+This call stops any DMA transfer on the given channel.
+
+
+int sa1100_dma_resume( dmach_t channel );
+
+This call resumes a DMA transfer which would have been stopped through
+sa1100_dma_stop().
+
+
+int sa1100_dma_flush_all( dmach_t channel );
+
+This completely flushes all queued buffers and on-going DMA transfers on a
+given channel. The next enqueued buffer following this call will be
+processed right away.
+
+
+int sa1100_dma_set_spin( dmach_t channel, dma_addr_t addr, int size );
+
+Because there is at least one device out there that uses its receive
+signal for its transmit clock reference, we need a mecanism to make the
+DMA "spin" on a certain buffer for when there is no more actual buffer to
+process. The 'addr' argument is the physical memory address to use, and
+the 'size' argument determines the spin DMA chunk. This size can't be
+larger than 8191 (if so, it is clamped to 4096). When the size is 0,
+the spin function is turned off.
+
+When activated, DMA will "spin" until there is any buffer in the queue.
+The current DMA chunk will terminate before a newly queued buffer is
+processed. The spin buffer will only be reused when there is no more
+acctual buffer to process.
+
+It is important not to choose a too small 'size' value since it will
+greatly increase the interrupt load required to restart the spin. Since
+this feature will typically be used on transmit DMAs, and because a buffer
+full of zeros is probably the best thing to spin out, the 'addr' argument
+may well be used with FLUSH_BASE_PHYS for which no allocation nor memory
+bus request are needed.
+
+The spinning DMA is affected by sa1100_dma_stop() and sa1100_dma_resume()
+but not bu sa1100_dma_flush_all().
+
+
+void sa1100_free_dma( dmach_t channel );
+
+This clears all activities on a given DMA channel and releases it for
+future requests.
+
+
+Buffer allocation
+-----------------
+
+Like mentionned above, it is the driver's responsibility to allocate, free
+and keep track of buffer space with dma_addr_t type addresses. However the
+driver must not change the state of any buffer after it has been sent to
+sa1100-dma_queue_buffer(). When that function has been called, the buffer
+becomes the DMA's ownership until one of these events occur:
+
+- The callback function is called by the DMA code with a buffer ID to
+ indicate that DMA processing terminated on that buffer. Then the
+ driver owns the buffer again.
+- The sa1100-dma_flush_all() function is called by the driver at which
+ point *all* queued buffers are owned by the driver again.
+- The sa1100-free_dma() does the same as sa1100-dma_flush_all().
+
+This doesn't mean that you can't change the content of a queued buffer in
+conjonction with the usage of pci_map_consistent() and
+sa1100_dma_get_current()... but then you must be sure you know what you're
+doing (this doesn't work with pci_map_single()).
+
+
+Examples
+--------
+
+A real example of audio ring buffers is implemented in the
+drivers/sound/sa1100-audio.c driver. The SA1110 USB client and the
+SA11x0 FIR drivers are also using this interface to implement packetized
+DMA.
+
+A transmit DMA for network packets could look like this (largely simplified):
+
+struct sk_buff *tx_ring_skb[RING_SIZE];
+dma_addr_t tx_ring_dma[RING_SIZE];
+int cur_tx;
+...
+
+transmit function:
+
+ tx_ring_skb[cur_tx] = skb;
+ tx_ring_dma[cur_tx] = pci_map_single(NULL, skb->data, skb->len,
+ PCI_DMA_TODEVICE);
+ sa1100_dma_queue_buffer(channel, (void*)cur_tx,
+ tx_ring_dma[cur_tx], skb->len);
+ cur_tx++; cur_tx %= RING_SIZE;
+ ...
+
+and the callback function:
+
+void tx_done_callback( void *buf_id, int size ) {
+ int done_tx = (int) buf_id;
+ struct sk_buff *skb = tx_ring_skb[done_tx];
+ pci_unmap_single(NULL, tx_ring_dma[done_tx], skb->len,
+ PCI_DMA_TODEVICE);
+ stats.tx_packets++;
+ stats.tx_bytes += size;
+ dev_kfree_skb_irq(skb);
+ tx_ring_skb[done_tx] = NULL;
+}
+
+
+For drivers expecting variable length packets i.e. USB client, it is
+necessary to register the appropriate IRQ to be notified when the receiver
+is idle, the packet is complete, etc. We could use one buffer at a time
+with its ID being the virtual address of the buffer.
+
+Then the sequence:
+
+ /* be sure DMA won't continue under our feet */
+ sa1100_dma_stop(channel);
+ /* get the actual DMA length */
+ sa1100_get_current(channel, &data, &dma_ptr);
+ /* acquire ownership for the buffer */
+ sa1100_dma_flush_all(channel);
+ /* unmap the DMA buffer (actually doing cache coherency on ARM) */
+ pci_unmap_single (NULL, dma_addr, MAX_PKT_SIZE, PCI_DMA_FROMDEVICE);
+ /* get remaining bytes from the fifo */
+ ptr = data + dma_ptr - dma_addr;
+ while (fifo_not_empty)
+ *ptr++ = get_byte_from_fifo;
+ /* feed another free buffer for the next packet */
+ dma_addr2 = pci_map_single(NULL, data2, MAX_PKT_SIZE,
+ PCI_DMA_FROMDEVICE);
+ sa1100_dma_queue_buffer(channel, data2, dma_addr2, MAX_PKT_SIZE);
+ /* process the current packet */
+ ...
+
+might do the trick. This looks a bit ugly but that's a starting point for
+improvements.
+
+
+TODO
+----
+
+- Create kernel-doc comments in the source to document the API and
+ let the documentation be generated automatically.
+
+
--- /dev/null
+Freebird-1.1 is produced by Legned(C) ,Inc.
+(http://www.legend.com.cn)
+and software/linux mainatined by Coventive(C),Inc.
+(http://www.coventive.com)
+
+Based on the Nicolas's strongarm kernel tree.
+
+===============================================================
+Maintainer:
+
+Chester Kuo <chester@coventive.com>
+ <chester@linux.org.tw>
+
+Author :
+Tim wu <timwu@coventive.com>
+CIH <cih@coventive.com>
+Eric Peng <ericpeng@coventive.com>
+Jeff Lee <jeff_lee@coventive.com>
+Allen Cheng
+Tony Liu <tonyliu@coventive.com>
+
-ADS GraphicsClient/ThinClient Single Board Computer
+ADS GraphicsClient Plus Single Board Computer
For more details, contact Applied Data Systems or see
-http://www.flatpanels.com/products.html
+http://www.applieddata.net/products.html
The original Linux support for this product has been provided by
-Nicolas Pitre <nico@cam.org>.
+Nicolas Pitre <nico@cam.org>. Continued development work by
+Woojung Huh <whuh@applieddata.net>
It's currently possible to mount a root filesystem via NFS providing a
-complete Linux environment. Otherwise a ramdisk image may be used. Use
-'make graphicsclient_config' before any 'make config'. This will set up
-defaults for GraphicsClient/ThinClient support.
+complete Linux environment. Otherwise a ramdisk image may be used. The
+board supports MTD/JFFS, so you could also mount something on there.
+
+Use 'make graphicsclient_config' before any 'make config'. This will set up
+defaults for GraphicsClient Plus support.
The kernel zImage is linked to be loaded and executed at 0xc0200000.
Also the following registers should have the specified values upon entry:
r0 = 0
r1 = 29 (this is the GraphicsClient architecture number)
-Here is a tipical angel.opt option file if the kernel is loaded through
-the Angel Debug Monitor:
+Linux can be used with the ADS BootLoader that ships with the
+newer rev boards. See their documentation on how to load Linux.
+Angel is not available for the GraphicsClient Plus AFAIK.
+
+There is a board known as just the GraphicsClient that ADS used to
+produce but has end of lifed. This code will not work on the older
+board with the ADS bootloader, but should still work with Angel,
+as outlined below. In any case, if you're planning on deploying
+something en masse, you should probably get the newer board.
+
+If using Angel on the older boards, here is a typical angel.opt option file
+if the kernel is loaded through the Angel Debug Monitor:
----- begin angelboot.opt -----
base 0xc0200000
r0 0x00000000
r1 0x0000001d
device /dev/ttyS1
-options "9600 8N1"
+options "38400 8N1"
baud 115200
#otherfile ramdisk.gz
#otherbase 0xc0800000
angelboot -f angelboot.opt zImage
Here it is assumed that the board is connected to ttyS1 on your PC
-and that minicom is preconfigured with /dev/ttyS1, 9600 baud, 8N1, no flow
+and that minicom is preconfigured with /dev/ttyS1, 38400 baud, 8N1, no flow
control by default.
If any other bootloader is used, ensure it accomplish the same, especially
Supported peripherals:
-- SA1100 LCD frame buffer (only 8bpp yet)
-- on-board SMC 92C94 ethernet NIC
+- SA1100 LCD frame buffer (8/16bpp...sort of)
+- on-board SMC 92C96 ethernet NIC
- SA1100 serial port
-- flash memory access
+- flash memory access (MTD/JFFS)
- pcmcia
-- possibly UCB1200 audio (not tested yet)
+- touchscreen(ucb1200)
+- ps/2 keyboard
+- console on LCD screen
+- serial ports (ttyS[0-2])
+ - ttyS0 is default for serial console
+- Smart I/O (ADC, keypad, digital inputs, etc)
+ See http://www.applieddata.com/developers/linux for IOCTL documentation
+ and example user space code. ps/2 keybd is multiplexed through this driver
To do:
-- touchscreen driver
-- 16bpp frame buffer support
-- extra (external) serial port driver
-- some console keyboard support (maybe IR?)
+- UCB1200 audio with new ucb_generic layer
- everything else! :-)
+Notes:
+
+- The flash on board is divided into 3 partitions. mtd0 is where
+ the ADS boot ROM and zImage is stored. It's been marked as
+ read-only to keep you from blasting over the bootloader. :) mtd1 is
+ for the ramdisk.gz image. mtd2 is user flash space and can be
+ utilized for either JFFS or if you're feeling crazy, running ext2
+ on top of it. If you're not using the ADS bootloader, you're
+ welcome to blast over the mtd1 partition also.
+
+- 16bpp mode requires a different cable than what ships with the board.
+ Contact ADS or look through the manual to wire your own. Currently,
+ if you compile with 16bit mode support and switch into a lower bpp
+ mode, the timing is off so the image is corrupted. This will be
+ fixed soon.
+
Any contribution can be sent to nico@cam.org and will be greatly welcome!
--- /dev/null
+The HUW_WEBPANEL is a product of the german company Hoeft & Wessel AG
+
+If you want more information, please visit
+http://www.hoeft-wessel.de
+
+To build the kernel:
+ make huw_webpanel_config
+ make oldconfig
+ [accept all defaults]
+ make dep
+ make zImage
+
+Mostly of the work is done by:
+Roman Jordan jor@hoeft-wessel.de
+Christoph Schulz schu@hoeft-wessel.de
+
+2000/12/18/
+
Research Center in Palo Alto, CA. The Itsy project is one of several
research projects at Compaq that are related to pocket computing.
-Itsy support has yet to be fully integrated in this kernel. Linux 2.0.x
-support is available though.
-
For more information, see:
http://www.research.digital.com/wrl/itsy/index.html
+Notes on initial 2.4 Itsy support (8/27/2000) :
+The port was done on an Itsy version 1.5 machine with a daughtercard with
+64 Meg of DRAM and 32 Meg of Flash. The initial work includes support for
+serial console (to see what you're doing). No other devices have been
+enabled.
+
+To build, do a "make menuconfig" (or xmenuconfig) and select Itsy support.
+Disable Flash and LCD support. and then do a make dep and a make zImage.
+Finally, you will need to cd to arch/arm/boot/tools and execute a make there
+to build the params-itsy program used to boot the kernel.
+
+In order to install the port of 2.4 to the itsy, You will need to set the
+configuration parameters in the monitor as follows:
+Arg 1:0x08340000, Arg2: 0xC0000000, Arg3:18 (0x12), Arg4:0
+Make sure the start-routine address is set to 0x00060000.
+
+Next, flash the params-itsy program to 0x00060000 ("p 1 0x00060000" in the
+flash menu) Flash the kernel in arch/arm/boot/zImage into 0x08340000
+("p 1 0x00340000"). Finally flash an initial ramdisk into 0xC8000000
+("p 2 0x0") We used ramdisk-2-30.gz from the 0.11 version directory on
+handhelds.org.
+
+The serial connection we established was at:
+ 8-bit data, no parity, 1 stop bit(s), 115200.00 b/s. in the monitor, in the
+params-itsy program, and in the kernel itself. This can be changed, but
+not easily. The monitor parameters are easily changed, the params program
+setup is assembly outl's, and the kernel is a configuration item specific to
+the itsy. (i.e. grep for CONFIG_SA1100_ITSY and you'll find where it is.)
+
+This should get you a properly booting 2.4 kernel on the itsy.
--- /dev/null
+Kernel Low-Level PCMCIA Interface Documentation
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+John G Dorsey <john+@cs.cmu.edu>
+Updated: 30 June, 2000
+
+
+Note: this interface has not been finalized!
+See also: http://www.cs.cmu.edu/~wearable/software/pcmcia-arm.html
+
+
+Introduction
+
+Early versions of PCMCIA Card Services for StrongARM were designed to
+permit a single socket driver to run on a variety of SA-1100 boards by
+using a userland configuration process. During the conversion to the 2.3
+kernel series, all of the configuration has moved into sub-drivers in the
+kernel proper (see linux/drivers/pcmcia/sa1100*). This document describes
+the low-level interface between those sub-drivers and the sa1100 socket
+driver module.
+
+Presently, there are six operations which must be provided by the
+board-specific code. Only functions whose implementation is likely to
+differ across board designs are required at this level. Some examples
+include:
+
+ - configuring card detect lines to generate interrupts
+ - sensing the legal voltage levels for inserted cards
+ - asserting the reset signal for a card
+
+Functions which are assumed to be the same across all designs are
+performed within the generic socket driver itself. Some examples of these
+kinds of operations include:
+
+ - configuring memory access times based on the core clock frequency
+ - reads/writes on memory, byte swizzling, ...
+
+The current implementation allows the specific per-board set of low-level
+operations to be determined at run time. For each specific board, the
+following structure should be filled in:
+
+ struct pcmcia_low_level {
+ int (*init)(struct pcmcia_init *);
+ int (*shutdown)(void);
+ int (*socket_state)(struct pcmcia_state_array *);
+ int (*get_irq_info)(struct pcmcia_irq_info *);
+ int (*configure_socket)(const struct pcmcia_configure *);
+ };
+
+The component functions are described in detail below. Using the
+machine_is_*() tests, the pointer `pcmcia_low_level' should be assigned to
+the location of the table for your board.
+
+
+0. init(struct pcmcia_init *init)
+
+This operation has three responsibilities:
+
+ - perform any board-specific initialization tasks
+ - associate the given handler with any interrupt-generating signals
+ such as card detection, or battery voltage detection
+ - set up any necessary edge detection for card ready signals
+
+Argument passing for this operation is implemented by the following
+structure:
+
+ struct pcmcia_init {
+ void (*handler)(int irq, void *dev, struct pt_regs *regs);
+ struct pcmcia_maps *maps;
+ };
+
+Here, `handler' is provided by the socket driver, and `maps' must be
+modified if the default mapping isn't appropriate. This operation should
+return one of two values:
+
+ - the highest-numbered socket available, plus one
+ - a negative number, indicating an error in configuration
+
+Note that the former case is _not_ the same as "the number of sockets
+available." In particular, if your design uses SA-1100 slot "one" but
+not slot "zero," you MUST report "2" to the socket driver.
+
+
+1. shutdown(void)
+
+This operation takes no arguments, and will be called during cleanup for
+the socket driver module. Any state associated with the socket controller,
+including allocated data structures, reserved IRQs, etc. should be
+released in this routine.
+
+The return value for this operation is not examined.
+
+
+2. socket_state(struct pcmcia_state_array *state_array)
+
+This operation will be invoked from the interrupt handler which was set up
+in the earlier call to init(). Note, however, that it should not include
+any side effects which would be inappropriate if the operation were to
+occur when no interrupt is pending. (An extra invocation of this operation
+currently takes place to initialize state in the socket driver.)
+
+Argument passing for this operation is handled by a structure which
+contains an array of the following type:
+
+ struct pcmcia_state {
+ unsigned detect: 1,
+ ready: 1,
+ bvd1: 1,
+ bvd2: 1,
+ wrprot: 1,
+ vs_3v: 1,
+ vs_Xv: 1;
+ };
+
+Upon return from the operation, a struct pcmcia_state should be filled in
+for each socket available in the hardware. For every array element (up to
+`size' in the struct pcmcia_state_saarray) which does not correspond to an
+available socket, zero the element bits. (This includes element [0] if
+socket zero is not used.)
+
+Regardless of how the various signals are routed to the SA-1100, the bits
+in struct pcmcia_state always have the following semantics:
+
+ detect - 1 if a card is fully inserted, 0 otherwise
+ ready - 1 if the card ready signal is asserted, 0 otherwise
+ bvd1 - the value of the Battery Voltage Detect 1 signal
+ bvd2 - the value of the Battery Voltage Detect 2 signal
+ wrprot - 1 if the card is write-protected, 0 otherwise
+ vs_3v - 1 if the card must be operated at 3.3V, 0 otherwise
+ vs_Xv - 1 if the card must be operated at X.XV, 0 otherwise
+
+A note about the BVD signals: if your board does not make both lines
+directly observable to the processor, just return reasonable values. The
+standard interpretation of the BVD signals is:
+
+ BVD1 BVD2
+
+ 0 x battery is dead
+ 1 0 battery warning
+ 1 1 battery ok
+
+Regarding the voltage sense flags (vs_3v, vs_Xv), these bits should be set
+based on a sampling of the Voltage Sense pins, if available. The standard
+interpretation of the VS signals (for a "low-voltage" socket) is:
+
+ VS1 VS2
+
+ 0 0 X.XV, else 3.3V, else none
+ 0 1 3.3V, else none
+ 1 0 X.XV, else none
+ 1 1 5V, else none
+
+More information about the BVD and VS conventions is available in chapter
+5 of "PCMCIA System Architecture," 2nd ed., by Don Anderson.
+
+This operation should return 1 if an IRQ is actually pending for the
+socket controller, 0 if no IRQ is pending (but no error condition exists,
+such as an undersized state array), or -1 on any error.
+
+
+3. get_irq_info(struct pcmcia_irq_info *info)
+
+This operation obtains the IRQ assignment which is legal for the given
+socket. An argument of the following type is passed:
+
+ struct pcmcia_irq_info {
+ unsigned int sock;
+ unsigned int irq ;
+ };
+
+The `sock' field contains the socket index being queried. The `irq' field
+should contain the IRQ number corresponding to the card ready signal from
+the device.
+
+This operation should return 0 on success, or -1 on any error.
+
+
+4. configure_socket(const struct pcmcia_configure *configure)
+
+This operation allows the caller to apply power to the socket, issue a
+reset, or enable various outputs. The argument is of the following type:
+
+ struct pcmcia_configure {
+ unsigned sock: 8,
+ vcc: 8,
+ vpp: 8,
+ output: 1,
+ speaker: 1,
+ reset: 1;
+ };
+
+The `sock' field contains the index of the socket to be configured. The
+`vcc' and `vpp' fields contain the voltages to be applied for Vcc and Vpp,
+respectively, in units of 0.1V. (Note that vpp==120 indicates that
+programming voltage should be applied.)
+
+The two output enables, `output' and `speaker', refer to the card data
+signal enable and the card speaker enable, respectively. The `reset' bit,
+when set, indicates that the card reset should be asserted.
+
+This operation should return 0 on success, or -1 on any error.
+
+
+Board-Specific Notes
+
+The following information is known about various SA-11x0 board designs
+which may be used as reference while adding support to the kernel.
+
+
+Carnegie Mellon Itsy/Cue (http://www.cs.cmu.edu/~wearable/itsy/)
+
+ Itsy Chip Select 3 (CS3) Interface
+ ("ITSY MEMORY/PCMCIA ADD-ON BOARD with BATTERY and CHARGER CIRCUITRY,"
+ memo dated 5-20-99, from Tim Manns to Richard Martin, et. al)
+
+ Read:
+ ABVD2 (SS)D0 A slot, Battery Voltage Detect
+ ABVD1 (SS)D1
+ AVSS2 (SS)D2 A slot, Voltage Sense
+ AVSS1 (SS)D3
+ GND (SS)D4
+ GND (SS)D5
+ GND (SS)D6
+ GND (SS)D7
+
+ BBVD2 (SS)D8 B slot, Battery Voltage Detect
+ BBVD1 (SS)D9
+ BVSS2 (SS)D10 B slot, Voltage Sense
+ BVSS1 (SS)D11
+ GND (SS)D12
+ GND (SS)D13
+ GND (SS)D14
+ GND (SS)D15
+
+ Write:
+ (SS)D0 A_VPP_VCC LTC1472 VPPEN1
+ (SS)D1 A_VPP_PGM LTC1472 VPPEN0
+ (SS)D2 A_VCC_3 LTC1472 VCCEN0
+ (SS)D3 A_VCC_5 LTC1472 VCCEN1
+ (SS)D4 RESET (A SLOT)
+ (SS)D5 GND
+ (SS)D6 GND
+ (SS)D7 GND
+
+ (SS)D8 B_VPP_VCC LTC1472 VPPEN1
+ (SS)D9 B_VPP_PGM LTC1472 VPPEN0
+ (SS)D10 B_VCC_3 LTC1472 VCCEN0
+ (SS)D11 B_VCC_5 LTC1472 VCCEN1
+ (SS)D12 RESET (B SLOT)
+ (SS)D13 GND
+ (SS)D14 GND
+ (SS)D15 GND
+
+ GPIO pin assignments are as follows: (from schematics)
+
+ GPIO 10 Slot 0 Card Detect
+ GPIO 11 Slot 1 Card Detect
+ GPIO 12 Slot 0 Ready/Interrupt
+ GPIO 13 Slot 1 Ready/Interrupt
+
+
+
+Intel SA-1100 Multimedia Board (http://developer.intel.com/design/strong/)
+
+ CPLD Registers
+ SA-1100 Multimedia Development Board with Companion SA-1101 Development
+ Board User's Guide, p.4-42
+
+ This SA-1100/1101 development package uses only one GPIO pin (24) to
+ signal changes in card status, and requires software to inspect a
+ PCMCIA status register to determine the source.
+
+ Read: (PCMCIA Power Sense Register - 0x19400000)
+ S0VS1 0 Slot 0 voltage sense
+ S0VS2 1
+ S0BVD1 2 Slot 0 battery voltage sense
+ S0BVD2 3
+ S1VS1 4 Slot 1 voltage sense
+ S1VS2 5
+ S1BVD1 6 Slot 1 battery voltage sense
+ S1BVD2 7
+
+ Read/Write: (PCMCIA Power Control Register - 0x19400002)
+ S0VPP0 0 Slot 0 Vpp
+ S0VPP1 1
+ S0VCC0 2 Slot 0 Vcc
+ S0VCC1 3
+ S1VPP0 4 Slot 1 Vpp
+ S1VPP1 5
+ S1VCC0 6 Slot 1 Vcc
+ S1VCC1 7
+
+ Read: (PCMCIA Status Register - 0x19400004)
+ S0CD1 0 Slot 0 Card Detect 1
+ S0RDY 1 Slot 0 Ready/Interrupt
+ S0STSCHG 2 Slot 0 Status Change
+ S0Reset 3 Slot 0 Reset (RW)
+ S1CD1 4 Slot 1 Card Detect 1
+ S1RDY 5 Slot 1 Ready/Interrupt
+ S1STSCHG 6 Slot 1 Status Change
+ S1Reset 7 Slot 1 Reset (RW)
+
+
+
+Intel SA-1100 Evaluation Platform (http://developer.intel.com/design/strong/)
+
+ Brutus I/O Pins and Chipselect Register
+ pcmcia-brutus.c, by Ivo Clarysse
+ (What's the official reference for this info?)
+
+ This SA-1100 development board uses more GPIO pins than say, the Itsy
+ or the SA-1100/1101 multimedia package. The pin assignments are as
+ follows:
+
+ GPIO 2 Slot 0 Battery Voltage Detect 1
+ GPIO 3 Slot 0 Ready/Interrupt
+ GPIO 4 Slot 0 Card Detect
+ GPIO 5 Slot 1 Battery Voltage Detect 1
+ GPIO 6 Slot 1 Ready/Interrupt
+ GPIO 7 Slot 1 Card Detect
+
+ Like the Itsy, Brutus uses a chipselect register in static memory
+ bank 3 for the other signals, such as voltage sense or reset:
+
+ Read:
+ P0_VS1 8 Slot 0 Voltage Sense
+ P0_VS2 9
+ P0_STSCHG 10 Slot 0 Status Change
+ P1_VS1 12 Slot 1 Voltage Sense
+ P1_VS2 13
+ P1_STSCHG 14 Slot 1 Status Change
+
+ Read/Write:
+ P0_ 16 Slot 0 MAX1600EAI control line
+ P0_ 17 Slot 0 MAX1600EAI control line
+ P0_ 18 Slot 0 MAX1600EAI control line
+ P0_ 19 Slot 0 MAX1600EAI control line
+ P0_ 20 Slot 0 12V
+ P0_ 21 Slot 0 Vpp to Vcc (CONFIRM?)
+ P0_ 22 Slot 0 enable fan-out drivers & xcvrs
+ P0_SW_RST 23 Slot 0 Reset
+ P1_ 24 Slot 1 MAX1600EAI control line
+ P1_ 25 Slot 1 MAX1600EAI control line
+ P1_ 26 Slot 1 MAX1600EAI control line
+ P1_ 27 Slot 1 MAX1600EAI control line
+ P1_ 28 Slot 1 12V
+ P1_ 29 Slot 1 Vpp to Vcc (CONFIRM?)
+ P1_ 30 Slot 1 enable fan-out drivers & xcvrs
+ P1_SW_RST 31 Slot 1 Reset
+
+ For each slot, the bits labelled "MAX1600EAI" should (apparently)
+ be written with the value 0101 for Vcc 3.3V, and 1001 for Vcc 5V.
+
+
+
+Intel SA-1110 Development Platform (http://developer.intel.com/design/strong/)
+
+ GPIO Pin Descriptions and Board Control Register
+ SA-1110 Microprocessor Development Board User's Guide, p.4-7, 4-10
+
+ The Assabet board contains only a single Compact Flash slot,
+ attached to slot 1 on the SA-1110. Card detect, ready, and BVD
+ signals are routed through GPIO, with power and reset placed in a
+ control register. Note that the CF bus must be enabled before use.
+
+ GPIO 21 Slot 1 Compact Flash interrupt
+ GPIO 22 Slot 1 card detect (CD1 NOR CD2)
+ GPIO 24 Slot 1 Battery Voltage Detect 2
+ GPIO 25 Slot 1 Battery Voltage Detect 1
+
+ Write-only: (Board Control Register - 0x12000000)
+ CF_PWR 0 CF bus power (3.3V)
+ CF_RST 1 CF reset
+ CF_Bus_On 7 CF bus enable
+
-Pangolin is a StrongARM 1110-based evaluation platform produced
-by Dialogue Technoloy (http://www.dialogue.com.tw/).
+Pangolin is a StrongARM 1110-based evaluation platform produced
+by Dialogue Technology (http://www.dialogue.com.tw/).
It has EISA slots for ease of configuration with SDRAM/Flash
memory card, USB/Serial/Audio card, Compact Flash card,
and TFT-LCD card.
-This platform is currently under development.
To compile for Pangolin, you must issue the following commands:
make pangolin_config
- make config
- [accept all defaults]
+ make oldconfig
make dep
make zImage
Supported peripherals:
-- SA1110 serial port
+- SA1110 serial port (UART1/UART2/UART3)
- flash memory access
-
-Testing:
-- pcmcia driver
-- sound driver
-
-To do:
-- MQ-200 driver
+- compact flash driver
+- UDA1341 sound driver
+- SA1100 LCD controller for 800x600 16bpp TFT-LCD
+- MQ-200 driver for 800x600 16bpp TFT-LCD
--- /dev/null
+See http://www.yopydeveloper.org for more.
+
"nanoEngine" is a SA1110 based single board computer from
Bright Star Engineering Inc. See www.brightstareng.com/arm
for more info.
+(Ref: Stuart Adams <sja@brightstareng.com>)
-Ref: Stuart Adams <sja@brightstareng.com>
+Also visit Larry Doolittle's "Linux for the nanoEngine" site:
+http://recycle.lbl.gov/~ldoolitt/bse/
-The SA1100 serial port finally had its major/minor numbers officially
-assigned:
+The SA1100 serial port had its major/minor numbers officially assigned:
> Date: Sun, 24 Sep 2000 21:40:27 -0700
> From: H. Peter Anvin <hpa@transmeta.com>
> 7 = /dev/cusa2 Callout device for ttySA2
>
-So, if you're not using devfs, you must create those inodes in /dev
+If you're not using devfs, you must create those inodes in /dev
on the root filesystem used by your SA1100-based device:
mknod ttySA0 c 204 5
mknod cusa1 c 205 6
mknod cusa2 c 205 7
-Note that the old incorrect use of /dev/ttyS0 in order to use the serial port
-won't work anymore. This device node is reserved to the conventionnal 16x50
-UART which may appear on devices like PCMCIA modem, etc.
+In addition to the creation of the appropriate device nodes above, you
+must ensure your user space applications make use of the correct device
+name. The classic example is the content of the /etc/inittab file where
+you might have a getty process started on ttyS0. In this case:
-In addition to the creation of the appropriate device nodes above, you must
-ensure your user space applications make use of the correct device name.
-The classic example is the content of the /etc/inittab where you might have
-a getty process started on ttyS0. In this case you have two choices:
+- replace occurences of ttyS0 with ttySA0, ttyS1 with ttySA1, etc.
-1- replace occurences of ttyS0 with ttySA0, ttyS1 with ttySA1, etc.
+- don't forget to add 'ttySA0', 'console', or the appropriate tty name
+ in /etc/securetty for root to be allowed to login as well.
-2- in the occurence of 'ttyS0', you may consider replacing it with 'console'.
- as in "T0:12345:respawn:/sbin/getty -L console 9600 vt100"
-
-(don't forget to add 'ttySA0', 'console', or the appropriate tty name
- in /etc/securetty for root to be allowed to login as well.)
-
-The use of /dev/console has the advantage of being independent of the real
-serial device used. The kernel automatically forward all operations on
-/dev/console to the apropriate serial device. The nature of the console may
-also be modified with a kernel command line parameter (see
-Documentation/serial-console.txt for the details). Of course,
-/dev/console must have been created as a char device with major 5 minor 1.
-
-Using /dev/console is also compatible with older kernels that used /dev/ttyS0.
-Therefore it is handy for ramdisk images which are targetted for different
-StrongARM platforms and older kernels.
--- /dev/null
+
+Introduction
+
+ This is a frame buffer device driver for 3dfx' Voodoo Graphics
+ (aka voodoo 1, aka sst1) and Voodoo² (aka Voodoo 2, aka CVG) based
+ video boards. It's highly experimental code, but is guaranteed to work
+ on my computer, with my "Maxi Gamer 3D" and "Maxi Gamer 3d²" boards,
+ and with me "between chair and keyboard". Some people tested other
+ combinations and it seems that it works.
+ The main page is located at <http://sstfb.sourceforge.net>, and if
+ you want the latest version, check out the CVS, as the driver is a work
+ in progress, i feel incomfortable with releasing tarballs of something
+ not completely working...Don't worry, it's still more than useable
+ (I eat my own dog food)
+
+ Please read the Bug section, and report any success or failure to me
+ (Ghozlane Toumi <gtoumi@messel.emse.fr>).
+ BTW, If you have only one monitor , and you don't feel like playing
+ with the vga passthrou cable, I can only suggest borrowing a screen
+ somewhere...
+
+
+Installation
+
+ This driver (should) work on ix86, with any 2.2.x kernel (tested
+ with x = 19) and "recent" 2.4.x kernel, as a module or compiled in.
+ You can apply the patches found in sstfb/kernel/*-2.{2|4}.x.patch,
+ and copy sstfb.c to linux/drivers/video/, or apply a single patch,
+ sstfb/patch-2.{2|4}.x-sstfb-yymmdd to your linux source tree.
+
+ Then configure your kernel as usual: choose "m" or "y" to 3Dfx Voodoo
+ Graphics in section "console". Compile, install, have fun... and please
+ drop me a report :)
+
+
+Module Usage
+
+ Warnings.
+ # You should read completely this section before issuing any command.
+ # If you have only one monitor to play with, once you insmod the
+ module, the 3dfx takes control of the output, so you'll have to
+ plug the monitor to the "normal" video board in order to issue
+ the commands, or you can blindly use sst_dbg_vgapass
+ in the tools directory (See Tools). The latest option is pass the
+ parameter vgapass=1 when insmodding the driver. (See Kernel/Modules
+ Options)
+
+ Module insertion:
+ # insmod sstfb.o
+ you should see some strange output frome the board:
+ a big blue square, a green and a red small squares and a vertical
+ white rectangle. why ? the function's name is self explanatory :
+ "sstfb_test()"...
+ (if you don't have a second monitor, you'll have to plug your monitor
+ directely to the 2D videocard to see what you're typing)
+ # con2fb /dev/fbx /dev/ttyx
+ bind a tty to the new frame buffer. if you already have a frame
+ buffer driver, the voodoo fb will likely be /dev/fb1. if not,
+ the device will be /dev/fb0. You can check this by doing a
+ cat /proc/fb. You can find a copy of con2fb in tools/ directory.
+ if you don't have another fb device, this step is superfluous,
+ as the console subsystem automagicaly binds ttys to the fb.
+ # switch to the virtual console you just mapped. "tadaaa" ...
+
+ Module removal:
+ # con2fb /dev/fbx /dev/ttyx
+ bind the tty to the old frame buffer so the module can be removed.
+ (how does it work with vgacon ? short answer : it doesn't work)
+ # rmmod sstfb
+
+
+Kernel/Modules Options
+
+ You can pass some otions to sstfb module, and via the kernel command
+ line when the driver is compiled in :
+ for module : insmod sstfb.o option1=value1 option2=value2 ...
+ in kernel : video=sstfb:option1,option2:value2,option3 ...
+
+ sstfb supports the folowing options :
+ module kernel description
+
+ vgapass=1 vgapass enable or disable VGA passthrou cable
+ vgapass=0 vganopass when enabled, the monitor will
+ get the signal from the VGA board
+ and not from the voodoo. default nopass
+
+ mem=x mem:x force frame buffer memory in MiB
+ allowed values: 1, 2, 4. default detect
+
+ inverse=1 inverse suposed to enable inverse console.
+ doesn't work ...
+
+ clipping=1 clipping enable or disable clipping . with
+ clipping=0 noclipping clipping enabled, all offscreen reads
+ and writes are disgarded. default:
+ enable clipping.
+
+ gfxclk=x gfxclk:x force graphic clock frequency (in MHz)
+ becarefull with this option .
+ default is 50Mhz for voodoo1, 75MHz
+ for voodoo2. Be carefull, this one is
+ dangerous. default=auto
+
+ slowpci=0 slowpci enable or disable fast PCI read/writes
+ slowpci=1 fastpci default : fastpci
+
+ dev=x dev:x attach the driver to device number x
+ 0 is the first compatible board (in
+ lspci order)
+
+Tools
+
+ These tools are mostly for debugging purposes, but you can
+ find some of these interesting :
+ - con2fb , maps a tty to a fbramebuffer .
+ con2fb /dev/fb1 /dev/tty5
+ - sst_dbg_vgapass , changes vga passthrou. You have to recompile the
+ driver with SST_DEBUG and SST_DEBUG_IOCTL set to 1
+ sst_dbg_vgapass /dev/fb1 1 (enables vga cable)
+ sst_dbg_vgapass /dev/fb1 0 (disables vga cable)
+ - glide_reset , resets the voodoo using glide
+ use this after rmmoding sstfb, if the module refuses to
+ reinsert .
+
+Bugs
+
+ - DO NOT use glide while the sstfb module is in, you'll most likely
+ hang your computer.
+ - if you see some artefacts (pixels not cleaning and stuff like that),
+ try turning off clipping (clipping=0)
+ - the driver don't detect the 4Mb frame buffer voodoos, it seems that
+ the 2 last Mbs wrap around. looking into that .
+ - The driver is 16 bpp only, 24/32 won't work.
+ - The driver is not your_favorite_toy-safe. this includes SMP...
+ [Actually from inspection it seems to be safe - Alan]
+ - when using XFree86 FBdev (X over fbdev) you may see strange color
+ patterns at the border of your windows (the pixels loose the lowest
+ byte -> basicaly the blue component nd some of the green) . I'm unable
+ to reproduce this with XFree86-3.3, but one of the testers has this
+ problem with XFree86-4. I don't know yet if this is the drivers fault
+ or X's (most likely the driver, of course).
+ - I didn't really test changing the palette, so you may find some weird
+ things when playing with that.
+ - Sometimes the driver will not recognise the DAC , and the
+ initialisation will fail. this is specificaly true for
+ voodoo 2 boards , but it should be solved in recent versions. please
+ contact me .
+ - the 24/32 is not likely to work anytime soon , knowing that the
+ hardware does ... unusual thigs in 24/32 bpp
+
+Todo
+
+ - Get rid of the previous paragraph.
+ - Buy more coffee.
+ - test/port to other arch.
+ - try to add panning using tweeks with front and back buffer .
+ - try to implement accel en voodoo2 , this board can actualy do a
+ lot in 2D even if it was sold as a 3D only board ...
+
+ghoz.
+
+--
+Ghozlane Toumi <gtoumi@messel.emse.fr>
+
+
+$Date: 2001/08/29 00:21:11 $
+http://sstfb.sourceforge.net/README
"ide0=ht6560b" : probe/support HT6560B interface
"ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip
(not for PCI -- automatically detected)
- "ide0=qd6580" : probe/support qd6580 interface
+ "ide0=qd65xx" : probe/support qd65xx interface
"ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439/M1445)
"ide0=umc8672" : probe/support umc8672 chipsets
- Makefile
- The targets 'sgmldocs', 'psdocs', and 'pdfdocs' are used to build
- DocBook files, PostScript files, and PDF files in
- Documentation/DocBook.
+ The targets 'sgmldocs', 'psdocs', 'pdfdocs', and 'htmldocs' are used
+ to build DocBook files, PostScript files, PDF files, and html files
+ in Documentation/DocBook.
- Documentation/DocBook/Makefile
If you just want to read the ready-made books on the various
subsystems (see Documentation/DocBook/*.tmpl), just type 'make
-psdocs', or 'make pdfdocs', depending on your preference. If you
-would rather read a different format, you can type 'make sgmldocs' and
-then use DocBook tools to convert Documentation/DocBook/*.sgml to a
-format of your choice (for example, 'db2html ...').
+psdocs', or 'make pdfdocs', or 'make htmldocs', depending on your
+preference. If you would rather read a different format, you can type
+'make sgmldocs' and then use DocBook tools to convert
+Documentation/DocBook/*.sgml to a format of your choice (for example,
+'db2html ...' if 'make htmldocs' was not defined).
If you want to see man pages instead, you can do this:
(*)?*/
The short function description cannot be multiline, but the other
-descriptions can be.
+descriptions can be (and they can contain blank lines). Avoid putting a
+spurious blank line after the function name, or else the description will
+be repeated!
All descriptive text is further processed, scanning for the following special
patterns, which are highlighted appropriately.
dialed-in x3270.
-HELP !!!
-
-The device name of e.g. /dev/3270/tty620 noted below is at variance
-with "standard" Linux device names. What should it be? The portion
-"/dev/3270" was recommended by H. Peter Anvin, maintainer of the
-official Linux major-numbers list; the portion "tty620" was recommended
-by me. Please send your thoughts on this issue at least to me at
-rbh00@utsglobal.com. Even if you think it's okay as is, please let me
-know. Thanks.
-
-
INSTALLATION.
You install the driver by installing a patch, doing a kernel build, and
If you have chosen to make tub3270 a module, you add a line to
/etc/modules.conf. If you are working on a VM virtual machine, you
-can use DEF GRAF to define virtual 3270 devices. If you generate 3270
-console support, the driver automatically converts your console at boot
-time to a 3270 if it is a 3215.
+can use DEF GRAF to define virtual 3270 devices.
+
+You may generate both 3270 and 3215 console support, or one or the
+other, or neither. If you generate both, the console type under VM is
+not changed. Use #CP Q TERM to see what the current console type is.
+Use #CP TERM CONMODE 3270 to change it to 3270. If you generate only
+3270 console support, then the driver automatically converts your console
+at boot time to a 3270 if it is a 3215.
In brief, these are the steps:
1. Install the tub3270 patch
Here are the installation steps in detail:
- 0. Retrieve the patch file via anonymous ftp from
- ftp://ftp.utsglobal.com/pub/tub3270. The patch is designed
- to apply smoothly to an IBM 2.4.0 system with no other
- UTS-Global patches applied. We know of some easily resolvable
- conflicts between this and other of our patches.
-
- 1. Apply the patch. Then do
+ 1. The 3270 driver is a part of the official Linux kernel
+ source. Build a tree with the kernel source and any necessary
+ patches. Then do
make oldconfig
- (Reply "y" or "m" for CONFIG_3270; if "y",
- reply "y" or "n" for CONFIG_3270_CONSOLE)
+ (If you wish to disable 3215 console support, edit
+ .config; change CONFIG_TN3215's value to "n";
+ and rerun "make oldconfig".)
make dep
make image
make modules
make modules_install
- <run silo in the usual way>
2. (Perform this step only if you have configured tub3270 as a
module.) Add a line to /etc/modules.conf to automatically
config3270.sh. Inspect the output script it produces,
/tmp/mkdev3270, and then run that script. This will create the
necessary character special device files and make the necessary
- changes to /etc/inittab. Then notify /sbin/init that /etc/inittab
- has changed, by issuing the telinit command with the q operand:
+ changes to /etc/inittab. If you have selected DEVFS, the driver
+ itself creates the device files, and /tmp/mkdev3270 only changes
+ /etc/inittab.
+
+ Then notify /sbin/init that /etc/inittab has changed, by issuing
+ the telinit command with the q operand:
cd /usr/src/linux/Documentation/s390
sh config3270.sh
sh /tmp/mkdev3270
telinit q
+
This should be sufficient for your first time. If your 3270
configuration has changed and you're reusing config3270, you
should follow these steps:
echo "#!/bin/sh" > $SCR || exit 1
echo " " >> $SCR
echo "# Script built by /sbin/config3270" >> $SCR
-echo rm -rf "$D/$SUBD/*" >> $SCR
+if [ ! -d /dev/dasd ]; then
+ echo rm -rf "$D/$SUBD/*" >> $SCR
+fi
echo "grep -v $TTY $INITTAB > $NINITTAB" > $SCRTMP || exit 1
echo "echo $ADDNOTE >> $NINITTAB" >> $SCRTMP
-echo mkdir -p $D/$SUBD >> $SCR
+if [ ! -d /dev/dasd ]; then
+ echo mkdir -p $D/$SUBD >> $SCR
+fi
# Now query the tub3270 driver for 3270 device information
# and add appropriate mknod and mingetty lines to our files
while read devno maj min;do
if [ $min = 0 ]; then
fsmaj=$maj
- echo mknod $D/$TUB c $fsmaj 0 >> $SCR
- echo chmod 666 $D/$TUB >> $SCR
+ if [ ! -d /dev/dasd ]; then
+ echo mknod $D/$TUB c $fsmaj 0 >> $SCR
+ echo chmod 666 $D/$TUB >> $SCR
+ fi
elif [ $maj = CONSOLE ]; then
- echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+ if [ ! -d /dev/dasd ]; then
+ echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+ fi
else
- echo mknod $D/$TTY$devno c $maj $min >>$SCR
- echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+ if [ ! -d /dev/dasd ]; then
+ echo mknod $D/$TTY$devno c $maj $min >>$SCR
+ echo mknod $D/$TUB$devno c $fsmaj $min >> $SCR
+ fi
echo "echo t$min$GETTYLINE $TTY$devno >> $NINITTAB" >> $SCRTMP
fi
done < $P
Some functions for the cm8738 can be configured in Kernel Configuration
or modules parameters. Set these parameters to 1 to enable.
- mpu_io: I/O ports base for MPU-401, 0 if disabled.
- fm_io: I/O ports base for OPL-3, 0 if disabled.
+ mpuio: I/O ports base for MPU-401, 0 if disabled.
+ fmio: I/O ports base for OPL-3, 0 if disabled.
spdif_inverse:Inverse the S/PDIF-in signal, this depends on your
CD-ROM or DVD-ROM.
spdif_loop: Enable S/PDIF loop, this route S/PDIF-in to S/PDIF-out
rear-out.
use_line_as_bass:Enable this if you want to use line-in as
bass-out.
- modem: You will need to set this parameter if you want to use
- the HSP modem. You need install the pctel.o, the modem
- driver itself.
joystick: Enable joystick. You will need to install Linux joystick
driver.
+
--- /dev/null
+
+ (the following is from the armlinux CVS)
+
+ WaveArtist mixer and volume levels can be accessed via these commands:
+
+ nn30 read registers nn, where nn = 00 - 09 for mixer settings
+ 0a - 13 for channel volumes
+ mm31 write the volume setting in pairs, where mm = (nn - 10) / 2
+ rr32 write the mixer settings in pairs, where rr = nn/2
+ xx33 reset all settings to default
+ 0y34 select mono source, y=0 = left, y=1 = right
+
+ bits
+ nn 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 00 | 0 | 0 0 1 1 | left line mixer gain | left aux1 mixer gain |lmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 01 | 0 | 0 1 0 1 | left aux2 mixer gain | right 2 left mic gain |mmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 02 | 0 | 0 1 1 1 | left mic mixer gain | left mic | left mixer gain |dith |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 03 | 0 | 1 0 0 1 | left mixer input select |lrfg | left ADC gain |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 04 | 0 | 1 0 1 1 | right line mixer gain | right aux1 mixer gain |rmute|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 05 | 0 | 1 1 0 1 | right aux2 mixer gain | left 2 right mic gain |test |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 06 | 0 | 1 1 1 1 | right mic mixer gain | right mic |right mixer gain |rbyps|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 07 | 1 | 0 0 0 1 | right mixer select |rrfg | right ADC gain |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 08 | 1 | 0 0 1 1 | mono mixer gain |right ADC mux sel|left ADC mux sel |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 09 | 1 | 0 1 0 1 |loopb|left linout|loop|ADCch|TxFch|OffCD|test |loopb|loopb|osamp|
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0a | 0 | left PCM channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0b | 0 | right PCM channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0c | 0 | left FM channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0d | 0 | right FM channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0e | 0 | left wavetable channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 0f | 0 | right wavetable channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 10 | 0 | left PCM expansion channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 11 | 0 | right PCM expansion channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 12 | 0 | left FM expansion channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+ 13 | 0 | right FM expansion channel volume |
+----+---+------------+-----+-----+-----+----+-----+-----+-----+-----+-----+-----+-----+
+
+ lmute: left mute
+ mmute: mono mute
+ dith: dithds
+ lrfg:
+ rmute: right mute
+ rbyps: right bypass
+ rrfg:
+ ADCch:
+ TxFch:
+ OffCD:
+ osamp:
+
+ And the following diagram is derived from the description in the CVS archive:
+
+ MIC L (mouthpiece)
+ +------+
+ -->PreAmp>-\
+ +--^---+ |
+ | |
+ r2b4-5 | +--------+
+ /----*-------------------------------->5 |
+ | | |
+ | /----------------------------------->4 |
+ | | | |
+ | | /--------------------------------->3 1of5 | +---+
+ | | | | mux >-->AMP>--> ADC L
+ | | | /------------------------------->2 | +-^-+
+ | | | | | | |
+ Line | | | | +----+ +------+ +---+ /---->1 | r3b3-0
+ ------------*->mute>--> Gain >--> | | | |
+ L | | | +----+ +------+ | | | *->0 |
+ | | | | | | +---^----+
+ Aux2 | | | +----+ +------+ | | | |
+ ----------*--->mute>--> Gain >--> M | | r8b0-2
+ L | | +----+ +------+ | | |
+ | | | | \------\
+ Aux1 | | +----+ +------+ | | |
+ --------*----->mute>--> Gain >--> I | |
+ L | +----+ +------+ | | |
+ | | | |
+ | +----+ +------+ | | +---+ |
+ *------->mute>--> Gain >--> X >-->AMP>--*
+ | +----+ +------+ | | +-^-+ |
+ | | | | |
+ | +----+ +------+ | | r2b1-3 |
+ | /----->mute>--> Gain >--> E | |
+ | | +----+ +------+ | | |
+ | | | | |
+ | | +----+ +------+ | | |
+ | | /--->mute>--> Gain >--> R | |
+ | | | +----+ +------+ | | |
+ | | | | | | r9b8-9
+ | | | +----+ +------+ | | | |
+ | | | /->mute>--> Gain >--> | | +---v---+
+ | | | | +----+ +------+ +---+ /-*->0 |
+ DAC | | | | | | |
+ ------------*----------------------------------->? | +----+
+ L | | | | | Mux >-->mute>--> L output
+ | | | | /->? | +--^-+
+ | | | | | | | |
+ | | | /--------->? | r0b0
+ | | | | | | +-------+
+ | | | | | |
+ Mono | | | | | | +-------+
+ ----------* | \---> | +----+
+ | | | | | | Mix >-->mute>--> Mono output
+ | | | | *-> | +--^-+
+ | | | | | +-------+ |
+ | | | | | r1b0
+ DAC | | | | | +-------+
+ ------------*-------------------------*--------->1 | +----+
+ R | | | | | | Mux >-->mute>--> R output
+ | | | | +----+ +------+ +---+ *->0 | +--^-+
+ | | | \->mute>--> Gain >--> | | +---^---+ |
+ | | | +----+ +------+ | | | | r5b0
+ | | | | | | r6b0
+ | | | +----+ +------+ | | |
+ | | \--->mute>--> Gain >--> M | |
+ | | +----+ +------+ | | |
+ | | | | |
+ | | +----+ +------+ | | |
+ | *----->mute>--> Gain >--> I | |
+ | | +----+ +------+ | | |
+ | | | | |
+ | | +----+ +------+ | | +---+ |
+ \------->mute>--> Gain >--> X >-->AMP>--*
+ | +----+ +------+ | | +-^-+ |
+ /--/ | | | |
+ Aux1 | +----+ +------+ | | r6b1-3 |
+ -------*------>mute>--> Gain >--> E | |
+ R | | +----+ +------+ | | |
+ | | | | |
+ Aux2 | | +----+ +------+ | | /------/
+ ---------*---->mute>--> Gain >--> R | |
+ R | | | +----+ +------+ | | |
+ | | | | | | +--------+
+ Line | | | +----+ +------+ | | | *->0 |
+ -----------*-->mute>--> Gain >--> | | | |
+ R | | | | +----+ +------+ +---+ \---->1 |
+ | | | | | |
+ | | | \-------------------------------->2 | +---+
+ | | | | Mux >-->AMP>--> ADC R
+ | | \---------------------------------->3 | +-^-+
+ | | | | |
+ | \------------------------------------>4 | r7b3-0
+ | | |
+ \-----*-------------------------------->5 |
+ | +---^----+
+ r6b4-5 | |
+ | | r8b3-5
+ +--v---+ |
+ -->PreAmp>-/
+ +------+
+ MIC R (electret mic)
ICS WDT501-P (no fan tachometer)
ICS WDT500-P
Software Only
+ SA1100 Internal Watchdog
Berkshire Products PC Watchdog Revision A & C (by Ken Hollis)
The wdt card cannot be safely probed for. Instead you need to pass
wdt=ioaddr,irq as a boot parameter - eg "wdt=0x240,11".
+The SA1100 watchdog module can be configured with the "sa1100_margin"
+commandline argument which specifies timeout value in seconds.
+
The i810 TCO watchdog modules can be configured with the "i810_margin"
commandline argument which specifies the counter initial value. The counter
is decremented every 0.6 seconds and default to 50 (30 seconds). Values can
Features
--------
- WDT501P WDT500P Software Berkshire i810 TCO
-Reboot Timer X X X X X
-External Reboot X X o o o
-I/O Port Monitor o o o X o
-Temperature X o o X o
-Fan Speed X o o o o
-Power Under X o o o o
-Power Over X o o o o
-Overheat X o o o o
+ WDT501P WDT500P Software Berkshire i810 TCO SA1100WD
+Reboot Timer X X X X X X
+External Reboot X X o o o X
+I/O Port Monitor o o o X o o
+Temperature X o o X o o
+Fan Speed X o o o o o
+Power Under X o o o o o
+Power Over X o o o o o
+Overheat X o o o o o
The external event interfaces on the WDT boards are not currently supported.
Minor numbers are however allocated for it.
W: http://alpha.dyndns.org/ov511/
S: Maintained
+USB SE401 DRIVER
+P: Jeroen Vreeken
+M: pe1rxq@amsat.org
+L: linux-usb-users@lists.sourceforge.net
+L: linux-usb-devel@lists.sourceforge.net
+W: http://www.chello.nl/~j.vreeken/se401/
+S: Maintained
+
USB PEGASUS DRIVER
P: Petko Manolov
M: petkan@dce.bg
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 10
-EXTRAVERSION =-pre4
+EXTRAVERSION =-pre5
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
/*
* linux/arch/arm/kernel/arthur.c
*
- * Copyright (C) 1998, 1999, 2000 Philip Blundell
+ * Copyright (C) 1998, 1999, 2000, 2001 Philip Blundell
*
* Arthur personality
*/
{
struct siginfo info;
info.si_signo = SIGSWI;
- info.si_code = nr;
+ info.si_errno = nr;
/* Bounce it to the emulator */
send_sig_info(SIGSWI, &info, current);
}
pm_power_off();
}
-void machine_restart(void * __unused)
+void machine_restart(char * __unused)
{
/*
* Clean and disable cache, and turn off interrupts
strne ip, [r1], #4
movne ip, r3, lsr #8
bne 7b
- strb ip, [r1], #1
- mov ip, ip, lsr #8
strh ip, [r1], #2
+ mov ip, ip, lsr #16
+ strb ip, [r1]
mov pc, lr
2: bic r1, r1, #3
cmp ip, #2
- ldr ip, [r1], #4
- mov ip, ip, lsr #16
- blt 4f
- bgt 5f
+ ldr r3, [r1], #4
+ bgt 4f
+ blt 5f
-3: ldr r3, [r1], #4
+3: mov ip, r3, lsr #16
+ ldr r3, [r1], #4
orr ip, ip, r3, lsl #16
str ip, [r0]
- mov ip, r3, lsr #16
subs r2, r2, #1
bne 3b
mov pc, lr
-4: ldr r3, [r1], #4
+4: mov ip, r3, lsr #24
+ ldr r3, [r1], #4
orr ip, ip, r3, lsl #8
str ip, [r0]
- mov ip, r3, lsr #24
subs r2, r2, #1
bne 4b
mov pc, lr
-5: ldr r3, [r1], #4
+5: mov ip, r3, lsr #8
+ ldr r3, [r1], #4
orr ip, ip, r3, lsl #24
str ip, [r0]
- mov ip, r3, lsr #8
subs r2, r2, #1
bne 5b
mov pc, lr
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
+#include <linux/bitops.h>
#include <linux/init.h>
#include <asm/system.h>
ai_multi += 1;
/* count the number of registers in the mask to be transferred */
- for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
- nr_regs += 4;
+ nr_regs = hweight16(REGMASK_BITS(instr)) * 4;
rn = RN_BITS(instr);
newaddr = eaddr = regs->uregs[rn];
* This is a "hint" - we already have eaddr worked out by the
* processor for us.
*/
- if (addr != eaddr)
+ if (addr != eaddr) {
printk(KERN_ERR "LDMSTM: PC = %08lx, instr = %08lx, "
"addr = %08lx, eaddr = %08lx\n",
instruction_pointer(regs), instr, addr, eaddr);
+ show_regs(regs);
+ }
for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
if (regbits & 1) {
# directories
dep:
- $(TOPDIR)/scripts/mkdep getconstants.c | sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
+ $(TOPDIR)/scripts/mkdep $(CFLAGS) $(EXTRA_CFLAGS) -- getconstants.c |\
+ sed s,getconstants.o,$(TOPDIR)/include/asm-arm/constants.h, > .depend
$(MAKE) all
.PHONY: all dep
# To add an entry into this database, please see Documentation/arm/README,
# or contact rmk@arm.linux.org.uk
#
-# Last update: Thu Aug 9 22:46:02 2001
+# Last update: Thu Aug 23 12:38:13 2001
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
l7200 ARCH_L7200 L7200 19
pleb SA1100_PLEB PLEB 20
integrator ARCH_INTEGRATOR INTEGRATOR 21
-bitsy SA1100_BITSY BITSY 22
+h3600 SA1100_H3600 H3600 22
ixp1200 ARCH_IXP1200 IXP1200 23
p720t ARCH_P720T P720T 24
assabet SA1100_ASSABET ASSABET 25
tardis ARCH_TARDIS TARDIS 77
mercury ARCH_MERCURY MERCURY 78
empeg SA1100_EMPEG EMPEG 79
-adi_eb ARCH_I80200FCC I80200FCC 80
+adi_evb ARCH_I80200FCC I80200FCC 80
itt_cpb SA1100_ITT_CPB ITT_CPB 81
svc SA1100_SVC SVC 82
alpha2 SA1100_ALPHA2 ALPHA2 84
granite ARCH_GRANITE GRANITE 104
consus SA1100_CONSUS CONSUS 105
aaec2000_aaed20 ARCH_AAEC2000_AAED2000 AAEC2000_AAED2000 106
+cdb89712 ARCH_CDB89712 CDB89712 107
+graphicsmaster SA1100_GRAPHICSMASTER GRAPHICSMASTER 108
+adsbitsy SA1100_ADSBITSY ADSBITSY 109
+cotulla_idp ARCH_COTULLA_IDP COTULLA_IDP 110
+plce ARCH_PLCE PLCE 111
+pt_system3 SA1100_PT_SYSTEM3 PT_SYSTEM3 112
+medalb ARCH_MEDALB MEDALB 113
#
# CONFIG_PHONE is not set
# CONFIG_PHONE_IXJ is not set
+# CONFIG_PHONE_IXJ_PCMCIA is not set
#
# ATA/IDE/MFM/RLL support
}
}
+
+
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
+
+/*
+ * 128MB for vmalloc and initrd
+ */
+#define VMALLOC_RESERVE (unsigned long)(128 << 20)
+#define MAXMEM (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
+#define MAXMEM_PFN PFN_DOWN(MAXMEM)
+#define MAX_NONPAE_PFN (1 << 20)
+
+/* On x86 for 1GB low mem the bootmem_bitmap is at worst 32k
+ * that is big but nothing to worry about. This must be in the kernels
+ * initial page tables so don't even try to get fancy where we allocate it.
+ * This data must be aligned on a page boundary so since I don't
+ * have a handlig __aligned_page_size attribute I allocate an extra
+ * PAGE_SIZE -1 bytes.
+ */
+static unsigned char bootmem_bitmap[((MAXMEM_PFN +7)/8) + PAGE_SIZE -1] __initdata = { 0 };
+
void __init setup_arch(char **cmdline_p)
{
- unsigned long bootmap_size, low_mem_size;
+ unsigned long bootmap_pfn, low_mem_size;
unsigned long start_pfn, max_pfn, max_low_pfn;
int i;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
- code_resource.start = virt_to_bus(&_text);
- code_resource.end = virt_to_bus(&_etext)-1;
- data_resource.start = virt_to_bus(&_etext);
- data_resource.end = virt_to_bus(&_edata)-1;
+ code_resource.start = virt_to_phys(&_text);
+ code_resource.end = virt_to_phys(&_etext)-1;
+ data_resource.start = virt_to_phys(&_etext);
+ data_resource.end = virt_to_phys(&_edata)-1;
parse_mem_cmdline(cmdline_p);
-#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
-#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
-
-/*
- * 128MB for vmalloc and initrd
- */
-#define VMALLOC_RESERVE (unsigned long)(128 << 20)
-#define MAXMEM (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
-#define MAXMEM_PFN PFN_DOWN(MAXMEM)
-#define MAX_NONPAE_PFN (1 << 20)
-
/*
* partially used pages are not usable - thus
* we are rounding upwards:
*/
- start_pfn = PFN_UP(__pa(&_end));
+ start_pfn = PFN_UP(virt_to_phys(&_end));
/*
* Find the highest page frame number we have available
/*
* Initialize the boot-time allocator (with low memory only):
*/
- bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+ bootmap_pfn = PFN_UP(virt_to_phys(&bootmem_bitmap));
+ init_bootmem(bootmap_pfn, max_low_pfn);
/*
* Register fully available low RAM pages with the bootmem allocator.
size = last_pfn - curr_pfn;
free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
}
- /*
- * Reserve the bootmem bitmap itself as well. We do this in two
- * steps (first step was init_bootmem()) because this catches
- * the (very unlikely) case of us accidentally initializing the
- * bootmem allocator with an invalid RAM area.
+ /*
+ * Reserve the kernel memory.
+ */
+ reserve_bootmem(HIGH_MEMORY, PFN_PHYS(start_pfn) +
+ PAGE_SIZE-1 - (HIGH_MEMORY));
+
+ /*
+ * Reserve the initrd
*/
- reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
- bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = 0;
+ initrd_end = 0;
+ if (LOADER_TYPE && INITRD_START && INITRD_SIZE) {
+ if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
+ reserve_bootmem(INITRD_START, INITRD_SIZE);
+ initrd_start = INITRD_START + PAGE_OFFSET;
+ initrd_end = initrd_start + INITRD_SIZE;
+ }
+ else {
+ printk(KERN_ERR "initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ INITRD_START + INITRD_SIZE,
+ max_low_pfn << PAGE_SHIFT);
+ }
+ }
+#endif
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
init_apic_mappings();
#endif
-#ifdef CONFIG_BLK_DEV_INITRD
- if (LOADER_TYPE && INITRD_START) {
- if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
- reserve_bootmem(INITRD_START, INITRD_SIZE);
- initrd_start =
- INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
- initrd_end = initrd_start+INITRD_SIZE;
- }
- else {
- printk(KERN_ERR "initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- INITRD_START + INITRD_SIZE,
- max_low_pfn << PAGE_SHIFT);
- initrd_start = 0;
- }
- }
-#endif
/*
* Request address space for all standard RAM and ROM resources
tsk->thread.cr2 = address;
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 14;
- info.si_code = SIGBUS;
+ info.si_signo = SIGBUS;
info.si_errno = 0;
info.si_code = BUS_ADRERR;
info.si_addr = (void *)address;
unsigned char amiga_psfreq;
struct amiga_hw_present amiga_hw_present;
-static const char s_a500[] __initdata = "A500";
-static const char s_a500p[] __initdata = "A500+";
-static const char s_a600[] __initdata = "A600";
-static const char s_a1000[] __initdata = "A1000";
-static const char s_a1200[] __initdata = "A1200";
-static const char s_a2000[] __initdata = "A2000";
-static const char s_a2500[] __initdata = "A2500";
-static const char s_a3000[] __initdata = "A3000";
-static const char s_a3000t[] __initdata = "A3000T";
-static const char s_a3000p[] __initdata = "A3000+";
-static const char s_a4000[] __initdata = "A4000";
-static const char s_a4000t[] __initdata = "A4000T";
-static const char s_cdtv[] __initdata = "CDTV";
-static const char s_cd32[] __initdata = "CD32";
-static const char s_draco[] __initdata = "Draco";
-static const char *amiga_models[] __initdata = {
+static char s_a500[] __initdata = "A500";
+static char s_a500p[] __initdata = "A500+";
+static char s_a600[] __initdata = "A600";
+static char s_a1000[] __initdata = "A1000";
+static char s_a1200[] __initdata = "A1200";
+static char s_a2000[] __initdata = "A2000";
+static char s_a2500[] __initdata = "A2500";
+static char s_a3000[] __initdata = "A3000";
+static char s_a3000t[] __initdata = "A3000T";
+static char s_a3000p[] __initdata = "A3000+";
+static char s_a4000[] __initdata = "A4000";
+static char s_a4000t[] __initdata = "A4000T";
+static char s_cdtv[] __initdata = "CDTV";
+static char s_cd32[] __initdata = "CD32";
+static char s_draco[] __initdata = "Draco";
+static char *amiga_models[] __initdata = {
s_a500, s_a500p, s_a600, s_a1000, s_a1200, s_a2000, s_a2500, s_a3000,
s_a3000t, s_a3000p, s_a4000, s_a4000t, s_cdtv, s_cd32, s_draco,
};
CONFIG_USB_STORAGE=m
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
#
# USB Network adaptors
#
-CONFIG_USB_PLUSB=m
CONFIG_USB_PEGASUS=m
CONFIG_USB_CATC=m
-CONFIG_USB_NET1080=m
+CONFIG_USB_KAWETH=m
+CONFIG_USB_USBNET=m
#
# USB port drivers
-/* $Id: head.S,v 1.77 2001/04/05 12:44:34 davem Exp $
+/* $Id: head.S,v 1.78 2001/08/30 03:22:00 kanoj Exp $
* head.S: Initial boot code for the Sparc64 port of Linux.
*
* Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
call __bzero
sub %o1, %o0, %o1
- /* Now clear empty_zero_page */
- sethi %hi(8192), %o1
- or %o1, %lo(8192), %o1
- sethi %hi(KERNBASE), %g3
- call __bzero
- or %g3, %lo(KERNBASE), %o0
-
mov %l6, %o1 ! OpenPROM stack
call prom_init
mov %l7, %o0 ! OpenPROM cif handler
ret
restore
+/*
+ * The following skips make sure the trap table in ttable.S is aligned
+ * on a 32K boundary as required by the v9 specs for TBA register.
+ */
sparc64_boot_end:
.skip 0x2000 + _start - sparc64_boot_end
bootup_user_stack_end:
-
- .globl empty_bad_page
-empty_bad_page:
.skip 0x2000
#ifdef CONFIG_SBUS
-/* $Id: ioctl32.c,v 1.121 2001/08/03 14:27:21 davem Exp $
+/* $Id: ioctl32.c,v 1.123 2001/09/02 03:52:07 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com)
COMPATIBLE_IOCTL(KDGKBSENT)
COMPATIBLE_IOCTL(KDSKBSENT)
COMPATIBLE_IOCTL(KDGKBDIACR)
+COMPATIBLE_IOCTL(KDKBDREP)
COMPATIBLE_IOCTL(KDSKBDIACR)
COMPATIBLE_IOCTL(KDGKBLED)
COMPATIBLE_IOCTL(KDSKBLED)
-/* $Id: sparc64_ksyms.c,v 1.110 2001/08/18 08:08:13 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.111 2001/08/30 03:22:00 kanoj Exp $
* arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
EXPORT_SYMBOL(ebus_chain);
EXPORT_SYMBOL(isa_chain);
EXPORT_SYMBOL(pci_memspace_mask);
-EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(outsb);
EXPORT_SYMBOL(outsw);
EXPORT_SYMBOL(outsl);
-/* $Id: blockops.S,v 1.31 2001/04/05 11:08:12 davem Exp $
+/* $Id: blockops.S,v 1.34 2001/09/03 01:34:18 kanoj Exp $
* blockops.S: UltraSparc block zero optimized routines.
*
* Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com)
-/* $Id: fault.c,v 1.56 2001/08/27 18:42:07 kanoj Exp $
+/* $Id: fault.c,v 1.58 2001/09/01 00:11:16 kanoj Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/uaccess.h>
+#include <asm/asi.h>
+#include <asm/lsu.h>
#define ELEMENTS(arr) (sizeof (arr)/sizeof (arr[0]))
extern struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS];
+/*
+ * To debug kernel during syscall entry.
+ */
void syscall_trace_entry(struct pt_regs *regs)
{
printk("scall entry: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
}
+/*
+ * To debug kernel during syscall exit.
+ */
void syscall_trace_exit(struct pt_regs *regs)
{
printk("scall exit: %s[%d]/cpu%d: %d\n", current->comm, current->pid, smp_processor_id(), (int) regs->u_regs[UREG_G1]);
}
+/*
+ * To debug kernel to catch accesses to certain virtual/physical addresses.
+ * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
+ * flags = VM_READ watches memread accesses, flags = VM_WRITE watches memwrite accesses.
+ * Caller passes in a 64bit aligned addr, with mask set to the bytes that need to be
+ * watched. This is only useful on a single cpu machine for now. After the watchpoint
+ * is detected, the process causing it will be killed, thus preventing an infinite loop.
+ */
+void set_brkpt(unsigned long addr, unsigned char mask, int flags, int mode)
+{
+ unsigned long lsubits = LSU_CONTROL_IC|LSU_CONTROL_DC|LSU_CONTROL_IM|LSU_CONTROL_DM;
+
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (addr), "r" (mode ? VIRT_WATCHPOINT : PHYS_WATCHPOINT),
+ "i" (ASI_DMMU));
+ lsubits |= ((unsigned long)mask << (mode ? 25 : 33));
+ if (flags & VM_READ)
+ lsubits |= (mode ? LSU_CONTROL_VR : LSU_CONTROL_PR);
+ if (flags & VM_WRITE)
+ lsubits |= (mode ? LSU_CONTROL_VW : LSU_CONTROL_PW);
+ __asm__ __volatile__("stxa %0, [%%g0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (lsubits), "i" (ASI_LSU_CONTROL)
+ : "memory");
+}
+
/* Nice, simple, prom library does all the sweating for us. ;) */
unsigned long __init prom_probe_memory (void)
{
unsigned long g2;
unsigned char asi = ASI_P;
- if (!insn)
+ if ((!insn) && (regs->tstate & TSTATE_PRIV))
goto cannot_handle;
/* If user insn could be read (thus insn is zero), that
-/* $Id: init.c,v 1.186 2001/08/23 05:14:57 kanoj Exp $
+/* $Id: init.c,v 1.189 2001/09/02 23:27:18 kanoj Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
extern unsigned int sparc_ramdisk_image;
extern unsigned int sparc_ramdisk_size;
+struct page *mem_map_zero;
+
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
}
}
-/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving an inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
- */
-pte_t __bad_page(void)
-{
- memset((void *) &empty_bad_page, 0, PAGE_SIZE);
- return pte_mkdirty(mk_pte_phys((((unsigned long) &empty_bad_page)
- - ((unsigned long)&empty_zero_page)
- + phys_base),
- PAGE_SHARED));
-}
-
void show_mem(void)
{
printk("Mem-info:\n");
phys_page &= _PAGE_PADDR;
phys_page += ((unsigned long)&prom_boot_page -
- (unsigned long)&empty_zero_page);
+ (unsigned long)KERNBASE);
if (tlb_type == spitfire) {
/* Lock this into i/d tlb entry 59 */
BUG();
}
- tte_vaddr = (unsigned long) &empty_zero_page;
+ tte_vaddr = (unsigned long) KERNBASE;
/* Spitfire Errata #32 workaround */
__asm__ __volatile__("stxa %0, [%1] %2\n\t"
remap_func((tlb_type == spitfire ?
(spitfire_get_dtlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR) :
(cheetah_get_litlb_data(sparc64_highest_locked_tlbent()) & _PAGE_PADDR)),
- (unsigned long) &empty_zero_page,
+ (unsigned long) KERNBASE,
prom_get_mmu_ihandle());
/* Flush out that temporary mapping. */
unsigned long size = trans[i].size;
if (vaddr < 0xf0000000UL) {
- unsigned long avoid_start = (unsigned long) &empty_zero_page;
+ unsigned long avoid_start = (unsigned long) KERNBASE;
unsigned long avoid_end = avoid_start + (4 * 1024 * 1024);
if (vaddr < avoid_start) {
* 4MB locked TLB translation.
*/
start_pfn = PAGE_ALIGN((unsigned long) &_end) -
- ((unsigned long) &empty_zero_page);
+ ((unsigned long) KERNBASE);
/* Adjust up to the physical address where the kernel begins. */
start_pfn += phys_base;
unsigned long alias_base = phys_base + PAGE_OFFSET;
unsigned long second_alias_page = 0;
unsigned long pt, flags, end_pfn, pages_avail;
- unsigned long shift = alias_base - ((unsigned long)&empty_zero_page);
+ unsigned long shift = alias_base - ((unsigned long)KERNBASE);
unsigned long real_end;
set_bit(0, mmu_context_bmap);
addr = PAGE_OFFSET + phys_base;
last = PAGE_ALIGN((unsigned long)&_end) -
- ((unsigned long) &empty_zero_page);
+ ((unsigned long) KERNBASE);
last += PAGE_OFFSET + phys_base;
while (addr < last) {
set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap);
max_mapnr = last_valid_pfn - (phys_base >> PAGE_SHIFT);
high_memory = __va(last_valid_pfn << PAGE_SHIFT);
- num_physpages = free_all_bootmem();
+ num_physpages = free_all_bootmem() - 1;
+
+ /*
+ * Set up the zero page, mark it reserved, so that page count
+ * is not manipulated when freeing the page from user ptes.
+ */
+ mem_map_zero = _alloc_pages(GFP_KERNEL, 0);
+ if (mem_map_zero == NULL) {
+ prom_printf("paging_init: Cannot alloc zero page.\n");
+ prom_halt();
+ }
+ SetPageReserved(mem_map_zero);
+ clear_page(page_address(mem_map_zero));
+
codepages = (((unsigned long) &etext) - ((unsigned long)&_start));
codepages = PAGE_ALIGN(codepages) >> PAGE_SHIFT;
datapages = (((unsigned long) &edata) - ((unsigned long)&etext));
extern pgd_t empty_pg_dir[1024];
unsigned long addr = (unsigned long)empty_pg_dir;
unsigned long alias_base = phys_base + PAGE_OFFSET -
- (long)(&empty_zero_page);
+ (long)(KERNBASE);
memset(empty_pg_dir, 0, sizeof(empty_pg_dir));
addr += alias_base;
void free_initmem (void)
{
- unsigned long addr;
+ unsigned long addr, initend;
- addr = (unsigned long)(&__init_begin);
- for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+ /*
+ * The init section is aligned to 8k in vmlinux.lds. Page align for >8k pagesizes.
+ */
+ addr = PAGE_ALIGN((unsigned long)(&__init_begin));
+ initend = (unsigned long)(&__init_end) & PAGE_MASK;
+ for (; addr < initend; addr += PAGE_SIZE) {
unsigned long page;
struct page *p;
page = (addr +
((unsigned long) __va(phys_base)) -
- ((unsigned long) &empty_zero_page));
+ ((unsigned long) KERNBASE));
p = virt_to_page(page);
ClearPageReserved(p);
-/* $Id: ultra.S,v 1.54 2001/03/22 07:26:04 davem Exp $
+/* $Id: ultra.S,v 1.56 2001/08/30 10:10:32 davem Exp $
* ultra.S: Don't expand these all over the place...
*
* Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com)
nop
flush_dcpage_cheetah:
- sethi %hi(8192), %o4
+ sethi %hi(PAGE_SIZE), %o4
1: subcc %o4, (1 << 5), %o4
stxa %g0, [%o0 + %o4] ASI_DCACHE_INVALIDATE
membar #Sync
retry
xcall_flush_tlb_range:
- sethi %hi(8192 - 1), %g2
- or %g2, %lo(8192 - 1), %g2
+ sethi %hi(PAGE_SIZE - 1), %g2
+ or %g2, %lo(PAGE_SIZE - 1), %g2
andn %g1, %g2, %g1
andn %g7, %g2, %g7
sub %g7, %g1, %g3
add %g2, 1, %g2
- srlx %g3, 13, %g4
+ srlx %g3, PAGE_SHIFT, %g4
cmp %g4, 96
bgu,pn %icc, xcall_flush_tlb_mm
SECTIONS
{
- empty_zero_page = 0x0000000000400000;
swapper_pmd_dir = 0x0000000000402000;
empty_pg_dir = 0x0000000000403000;
. = 0x4000;
* - s/suser/capable/
*/
+/*
+ * 2001/08/26 -- Paul Gortmaker - fix insmod oops on machines with no
+ * floppy controller (lingering task on list after module is gone... boom.)
+ */
+
#define FLOPPY_SANITY_CHECK
#undef FLOPPY_SILENT_DCL_CLEAR
return 0;
}
-static int have_no_fdc= -EIO;
+static int have_no_fdc= -ENODEV;
int __init floppy_init(void)
del_timer(&fd_timeout);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
devfs_unregister_blkdev(MAJOR_NR,"fd");
- del_timer(&fd_timeout);
return -EBUSY;
}
if (have_no_fdc)
{
DPRINT("no floppy controllers found\n");
- floppy_tq.routine = (void *)(void *) empty;
- mark_bh(IMMEDIATE_BH);
- schedule();
+ run_task_queue(&tq_immediate);
if (usage_count)
floppy_release_irq_and_dma();
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
MODULE_PARM(FLOPPY_DMA,"i");
MODULE_AUTHOR("Alain L. Knaff");
MODULE_SUPPORTED_DEVICE("fd");
+MODULE_LICENSE("GPL");
#else
static u8 ppc6_rd_data_byte(PPC *ppc);
static u8 ppc6_rd_port(PPC *ppc, u8 port);
static void ppc6_wr_port(PPC *ppc, u8 port, u8 data);
-static u8 ppc6_rd_reg(PPC *ppc, u8 reg);
-static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data);
-static u8 ppc6_version(PPC *ppc);
static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count);
static void ppc6_wait_for_fifo(PPC *ppc);
static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count);
static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static u16 ppc6_rd_port16(PPC *ppc, u8 port);
-static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data);
static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static u8 ppc6_rd_eeprom_reg(PPC *ppc);
-static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data);
-static void ppc6_eeprom_start(PPC *ppc);
-static void ppc6_eeprom_end(PPC *ppc);
-static void ppc6_set_cs(PPC *ppc);
-static void ppc6_reset_cs(PPC *ppc);
-static u8 ppc6_rd_eeprom_bit(PPC *ppc);
-static void ppc6_eeprom_ready_wait(PPC *ppc);
-static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit);
-static u16 ppc6_eeprom_read(PPC *ppc, u8 addr);
-static u8 ppc6_irq_test(PPC *ppc);
-static u8 ppc6_rd_extout(PPC *ppc);
static void ppc6_wr_extout(PPC *ppc, u8 regdata);
static int ppc6_open(PPC *ppc);
static void ppc6_close(PPC *ppc);
static u8 ppc6_rd_data_byte(PPC *ppc)
{
- u8 data;
+ u8 data = 0;
switch(ppc->mode)
{
//***************************************************************************
-static u8 ppc6_rd_reg(PPC *ppc, u8 reg)
-{
- ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_READ));
-
- return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_reg(PPC *ppc, u8 reg, u8 data)
-{
- ppc6_send_cmd(ppc,(u8)(reg | ACCESS_REG | ACCESS_WRITE));
-
- ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_version(PPC *ppc)
-{
- ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
-
- return(ppc6_rd_data_byte(ppc) & 0x3F);
-}
-
-//***************************************************************************
-
static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count)
{
switch(ppc->mode)
//***************************************************************************
-static u16 ppc6_rd_port16(PPC *ppc, u8 port)
-{
- u16 data;
-
- ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
-
- ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
- data = ppc6_rd_data_byte(ppc);
-
- ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_READ));
-
- data += (u16)ppc6_rd_data_byte(ppc) << 8;
-
- ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
-
- return(data);
-}
-
-//***************************************************************************
-
-static void ppc6_wr_port16(PPC *ppc, u8 port, u16 data)
-{
- ppc6_send_cmd(ppc, (CMD_PREFIX_SET | PREFIX_IO16));
-
- ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
- ppc6_wr_data_byte(ppc, (u8)data);
-
- ppc6_send_cmd(ppc, (u8)(port | ACCESS_PORT | ACCESS_WRITE));
-
- ppc6_wr_data_byte(ppc, (u8)(data >> 8));
-
- ppc6_send_cmd(ppc, (CMD_PREFIX_RESET | PREFIX_IO16));
-}
-
-//***************************************************************************
-
static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
{
length = length << 1;
//***************************************************************************
-static u8 ppc6_rd_eeprom_reg(PPC *ppc)
-{
- ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_READ));
-
- return(ppc6_rd_data_byte(ppc));
-}
-
-//***************************************************************************
-
-static void ppc6_wr_eeprom_reg(PPC *ppc, u8 data)
-{
- ppc6_send_cmd(ppc, (REG_EEPROM | ACCESS_REG | ACCESS_WRITE));
-
- ppc6_wr_data_byte(ppc, data);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_start(PPC *ppc)
-{
- ppc6_wr_eeprom_reg(ppc, EEPROM_EN);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_end(PPC *ppc)
-{
- ppc6_wr_eeprom_reg(ppc, 0);
-}
-
-//***************************************************************************
-
-static void ppc6_set_cs(PPC *ppc)
-{
- ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) | EEPROM_CS));
-}
-
-//***************************************************************************
-
-static void ppc6_reset_cs(PPC *ppc)
-{
- ppc6_wr_eeprom_reg(ppc, (u8)(ppc6_rd_eeprom_reg(ppc) & ~EEPROM_CS));
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_eeprom_bit(PPC *ppc)
-{
- ppc6_send_cmd(ppc, (REG_STATUS | ACCESS_REG | ACCESS_READ));
-
- if (ppc6_rd_data_byte(ppc) & STATUS_EEPROM_DO)
- return(1);
- else
- return(0);
-}
-
-//***************************************************************************
-
-static void ppc6_eeprom_ready_wait(PPC *ppc)
-{
- ppc6_set_cs(ppc);
-
- while(ppc6_rd_eeprom_bit(ppc));
-
- ppc6_reset_cs(ppc);
-}
-
-//***************************************************************************
-
-static void ppc6_wr_eeprom_bit(PPC *ppc, u8 bit)
-{
- u8 eereg;
-
- eereg = ppc6_rd_eeprom_reg(ppc);
-
- eereg &= ~(EEPROM_SK | EEPROM_DI);
-
- if (bit & 1)
- eereg |= EEPROM_DI;
-
- ppc6_wr_eeprom_reg(ppc, eereg);
-
- eereg |= EEPROM_SK;
-
- ppc6_wr_eeprom_reg(ppc, eereg);
-
- eereg &= ~EEPROM_SK;
-
- ppc6_wr_eeprom_reg(ppc, eereg);
-}
-
-//***************************************************************************
-
-static u16 ppc6_eeprom_read(PPC *ppc, u8 addr)
-{
- int i;
- u16 data;
-
- ppc6_set_cs(ppc);
-
- ppc6_wr_eeprom_bit(ppc, 1); // Start bit
-
- ppc6_wr_eeprom_bit(ppc, 1); // opcode 10 (read)
- ppc6_wr_eeprom_bit(ppc, 0);
-
- for(i=0; i<6; i++)
- ppc6_wr_eeprom_bit(ppc, (u8)((addr >> (5 - i)) & 1));
-
- data = 0;
-
- for(i=0; i<16; i++)
- {
- ppc6_wr_eeprom_bit(ppc,0);
-
- data = (data << 1) | ppc6_rd_eeprom_bit(ppc);
- }
-
- ppc6_reset_cs(ppc);
-
- return(data);
-}
-
-//***************************************************************************
-
-static u8 ppc6_irq_test(PPC *ppc)
-{
- ppc6_send_cmd(ppc,(REG_STATUS | ACCESS_REG | ACCESS_READ));
-
- return(ppc6_rd_data_byte(ppc) & STATUS_IRQA);
-}
-
-//***************************************************************************
-
-static u8 ppc6_rd_extout(PPC *ppc)
-{
- ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_READ));
-
- return((ppc6_rd_data_byte(ppc) & 0xC0) >> 6);
-}
-
-//***************************************************************************
-
static void ppc6_wr_extout(PPC *ppc, u8 regdata)
{
ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
static int rd_blocksizes[NUM_RAMDISKS]; /* Size of 1024 byte blocks :) */
static int rd_kbsize[NUM_RAMDISKS]; /* Size in blocks of 1024 bytes */
static devfs_handle_t devfs_handle;
-static struct inode *rd_inode[NUM_RAMDISKS]; /* Protected device inodes */
+static struct block_device *rd_bdev[NUM_RAMDISKS];/* Protected device data */
/*
* Parameters for the boot-loading of the RAM disk. These are set by
/* special: we want to release the ramdisk memory,
it's not like with the other blockdevices where
this ioctl only flushes away the buffer cache. */
- if ((atomic_read(&inode->i_bdev->bd_openers) > 2))
+ if ((atomic_read(rd_bdev[minor]->bd_openers) > 2))
return -EBUSY;
destroy_buffers(inode->i_rdev);
rd_blocksizes[minor] = 0;
lock_kernel();
if (!--initrd_users) {
blkdev_put(inode->i_bdev, BDEV_FILE);
- iput(inode);
free_initrd_mem(initrd_start, initrd_end);
initrd_start = 0;
}
static int rd_open(struct inode * inode, struct file * filp)
{
+ int unit = DEVICE_NR(inode->i_rdev);
+
#ifdef CONFIG_BLK_DEV_INITRD
- if (DEVICE_NR(inode->i_rdev) == INITRD_MINOR) {
+ if (unit == INITRD_MINOR) {
if (!initrd_start) return -ENODEV;
initrd_users++;
filp->f_op = &initrd_fops;
}
#endif
- if (DEVICE_NR(inode->i_rdev) >= NUM_RAMDISKS)
+ if (unit >= NUM_RAMDISKS)
return -ENXIO;
/*
* Immunize device against invalidate_buffers() and prune_icache().
*/
- if (rd_inode[DEVICE_NR(inode->i_rdev)] == NULL) {
- if (!inode->i_bdev) return -ENXIO;
- if ((rd_inode[DEVICE_NR(inode->i_rdev)] = igrab(inode)) != NULL)
- atomic_inc(&rd_inode[DEVICE_NR(inode->i_rdev)]->i_bdev->bd_openers);
+ if (rd_bdev[unit] == NULL) {
+ rd_bdev[unit] = bdget(kdev_t_to_nr(inode->i_rdev));
+ atomic_inc(&rd_bdev[unit]->bd_openers);
}
MOD_INC_USE_COUNT;
int i;
for (i = 0 ; i < NUM_RAMDISKS; i++) {
- if (rd_inode[i]) {
- /* withdraw invalidate_buffers() and prune_icache() immunity */
- atomic_dec(&rd_inode[i]->i_bdev->bd_openers);
- /* remove stale pointer to module address space */
- rd_inode[i]->i_bdev->bd_op = NULL;
- iput(rd_inode[i]);
+ struct block_device *bdev = rd_bdev[i];
+ rd_bdev[i] = NULL;
+ if (bdev) {
+ blkdev_put(bdev);
+ bdput(bdev);
}
destroy_buffers(MKDEV(MAJOR_NR, i));
}
dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
-dep_tristate 'HCI EMU (virtual device) driver' CONFIG_BLUEZ_HCIEMU $CONFIG_BLUEZ
+dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
endmenu
obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
-obj-$(CONFIG_BLUEZ_HCIEMU) += hci_emu.o
+obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
include $(TOPDIR)/Rules.make
+++ /dev/null
-/*
- BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
-
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * BlueZ HCI virtual device driver.
- *
- * $Id: hci_emu.c,v 1.1 2001/06/01 08:12:10 davem Exp $
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/fcntl.h>
-#include <linux/init.h>
-#include <linux/random.h>
-
-#include <linux/skbuff.h>
-#include <linux/miscdevice.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/bluez.h>
-#include <net/bluetooth/hci_core.h>
-#include <net/bluetooth/hci_emu.h>
-
-/* HCI device part */
-
-int hci_emu_open(struct hci_dev *hdev)
-{
- hdev->flags |= HCI_RUNNING;
- return 0;
-}
-
-int hci_emu_flush(struct hci_dev *hdev)
-{
- struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) hdev->driver_data;
- bluez_skb_queue_purge(&hci_emu->readq);
- return 0;
-}
-
-int hci_emu_close(struct hci_dev *hdev)
-{
- hdev->flags &= ~HCI_RUNNING;
- hci_emu_flush(hdev);
- return 0;
-}
-
-int hci_emu_send_frame(struct sk_buff *skb)
-{
- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
- struct hci_emu_struct *hci_emu;
-
- if (!hdev) {
- ERR("Frame for uknown device (hdev=NULL)");
- return -ENODEV;
- }
-
- if (!(hdev->flags & HCI_RUNNING))
- return -EBUSY;
-
- hci_emu = (struct hci_emu_struct *) hdev->driver_data;
-
- memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
- skb_queue_tail(&hci_emu->readq, skb);
-
- if (hci_emu->flags & HCI_EMU_FASYNC)
- kill_fasync(&hci_emu->fasync, SIGIO, POLL_IN);
- wake_up_interruptible(&hci_emu->read_wait);
-
- return 0;
-}
-
-/* Character device part */
-
-/* Poll */
-static unsigned int hci_emu_chr_poll(struct file *file, poll_table * wait)
-{
- struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
- poll_wait(file, &hci_emu->read_wait, wait);
-
- if (skb_queue_len(&hci_emu->readq))
- return POLLIN | POLLRDNORM;
-
- return POLLOUT | POLLWRNORM;
-}
-
-/* Get packet from user space buffer(already verified) */
-static __inline__ ssize_t hci_emu_get_user(struct hci_emu_struct *hci_emu, const char *buf, size_t count)
-{
- struct sk_buff *skb;
-
- if (count > HCI_EMU_MAX_FRAME)
- return -EINVAL;
-
- if (!(skb = bluez_skb_alloc(count, GFP_KERNEL)))
- return -ENOMEM;
-
- copy_from_user(skb_put(skb, count), buf, count);
-
- skb->dev = (void *) &hci_emu->hdev;
- skb->pkt_type = *((__u8 *) skb->data);
- skb_pull(skb, 1);
-
- hci_recv_frame(skb);
-
- return count;
-}
-
-/* Write */
-static ssize_t hci_emu_chr_write(struct file * file, const char * buf,
- size_t count, loff_t *pos)
-{
- struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
- if (verify_area(VERIFY_READ, buf, count))
- return -EFAULT;
-
- return hci_emu_get_user(hci_emu, buf, count);
-}
-
-/* Put packet to user space buffer(already verified) */
-static __inline__ ssize_t hci_emu_put_user(struct hci_emu_struct *hci_emu,
- struct sk_buff *skb, char *buf, int count)
-{
- int len = count, total = 0;
- char *ptr = buf;
-
- len = MIN(skb->len, len);
- copy_to_user(ptr, skb->data, len);
- total += len;
-
- hci_emu->hdev.stat.byte_tx += len;
- switch (skb->pkt_type) {
- case HCI_COMMAND_PKT:
- hci_emu->hdev.stat.cmd_tx++;
- break;
-
- case HCI_ACLDATA_PKT:
- hci_emu->hdev.stat.acl_tx++;
- break;
-
- case HCI_SCODATA_PKT:
- hci_emu->hdev.stat.cmd_tx++;
- break;
- };
-
- return total;
-}
-
-/* Read */
-static ssize_t hci_emu_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
-{
- struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
- DECLARE_WAITQUEUE(wait, current);
- struct sk_buff *skb;
- ssize_t ret = 0;
-
- add_wait_queue(&hci_emu->read_wait, &wait);
- while (count) {
- current->state = TASK_INTERRUPTIBLE;
-
- /* Read frames from device queue */
- if (!(skb = skb_dequeue(&hci_emu->readq))) {
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
- break;
- }
- if (signal_pending(current)) {
- ret = -ERESTARTSYS;
- break;
- }
-
- /* Nothing to read, let's sleep */
- schedule();
- continue;
- }
-
- if (!verify_area(VERIFY_WRITE, buf, count))
- ret = hci_emu_put_user(hci_emu, skb, buf, count);
- else
- ret = -EFAULT;
-
- bluez_skb_free(skb);
- break;
- }
-
- current->state = TASK_RUNNING;
- remove_wait_queue(&hci_emu->read_wait, &wait);
-
- return ret;
-}
-
-static int hci_emu_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-{
- return -EINVAL;
-}
-
-static int hci_emu_chr_fasync(int fd, struct file *file, int on)
-{
- struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
- int ret;
-
- if ((ret = fasync_helper(fd, file, on, &hci_emu->fasync)) < 0)
- return ret;
-
- if (on)
- hci_emu->flags |= HCI_EMU_FASYNC;
- else
- hci_emu->flags &= ~HCI_EMU_FASYNC;
-
- return 0;
-}
-
-static int hci_emu_chr_open(struct inode *inode, struct file * file)
-{
- struct hci_emu_struct *hci_emu = NULL;
- struct hci_dev *hdev;
-
- if (!(hci_emu = kmalloc(sizeof(struct hci_emu_struct), GFP_KERNEL)))
- return -ENOMEM;
-
- memset(hci_emu, 0, sizeof(struct hci_emu_struct));
-
- skb_queue_head_init(&hci_emu->readq);
- init_waitqueue_head(&hci_emu->read_wait);
-
- /* Initialize and register HCI device */
- hdev = &hci_emu->hdev;
-
- hdev->type = HCI_EMU;
- hdev->driver_data = hci_emu;
-
- hdev->open = hci_emu_open;
- hdev->close = hci_emu_close;
- hdev->flush = hci_emu_flush;
- hdev->send = hci_emu_send_frame;
-
- if (hci_register_dev(hdev) < 0) {
- kfree(hci_emu);
- return -EBUSY;
- }
-
- file->private_data = hci_emu;
- return 0;
-}
-
-static int hci_emu_chr_close(struct inode *inode, struct file *file)
-{
- struct hci_emu_struct *hci_emu = (struct hci_emu_struct *) file->private_data;
-
- if (hci_unregister_dev(&hci_emu->hdev) < 0) {
- ERR("Can't unregister HCI device %s", hci_emu->hdev.name);
- }
-
- kfree(hci_emu);
- file->private_data = NULL;
-
- return 0;
-}
-
-static struct file_operations hci_emu_fops = {
- owner: THIS_MODULE,
- llseek: no_llseek,
- read: hci_emu_chr_read,
- write: hci_emu_chr_write,
- poll: hci_emu_chr_poll,
- ioctl: hci_emu_chr_ioctl,
- open: hci_emu_chr_open,
- release:hci_emu_chr_close,
- fasync: hci_emu_chr_fasync
-};
-
-static struct miscdevice hci_emu_miscdev=
-{
- HCI_EMU_MINOR,
- "hci_emu",
- &hci_emu_fops
-};
-
-int __init hci_emu_init(void)
-{
- INF("BlueZ HCI EMU driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- BLUEZ_VER);
- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if (misc_register(&hci_emu_miscdev)) {
- ERR("Can't register misc device %d\n", HCI_EMU_MINOR);
- return -EIO;
- }
-
- return 0;
-}
-
-void hci_emu_cleanup(void)
-{
- misc_deregister(&hci_emu_miscdev);
-}
-
-module_init(hci_emu_init);
-module_exit(hci_emu_cleanup);
/*
* BlueZ HCI UART driver.
*
- * $Id: hci_uart.c,v 1.1 2001/06/01 08:12:10 davem Exp $
+ * $Id: hci_uart.c,v 1.5 2001/07/05 18:42:44 maxk Exp $
*/
+#define VERSION "1.0"
#include <linux/config.h>
#include <linux/module.h>
DBG("hdev %p tty %p", hdev, tty);
/* Drop TX queue */
- bluez_skb_queue_purge(&n_hci->txq);
+ skb_queue_purge(&n_hci->txq);
/* Flush any pending characters in the driver and discipline. */
if (tty->ldisc.flush_buffer)
if (len == skb->len) {
/* Full frame was sent */
- bluez_skb_free(skb);
+ kfree_skb(skb);
} else {
/* Subtract sent part and requeue */
skb_pull(skb, len);
hci_recv_frame(n_hci->rx_skb);
} else if (len > room) {
ERR("Data length is to large");
- bluez_skb_free(n_hci->rx_skb);
+ kfree_skb(n_hci->rx_skb);
n_hci->hdev.stat.err_rx++;
} else {
n_hci->rx_state = WAIT_DATA;
hci_sco_hdr *sh;
register int len, type, dlen;
- DBG("count %d state %d rx_count %d", count, n_hci->rx_state, n_hci->rx_count);
+ DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
n_hci->hdev.stat.byte_rx += count;
ptr++; count--;
/* Allocate packet */
- if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_READ, GFP_ATOMIC))) {
+ if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
ERR("Can't allocate mem for new packet");
n_hci->rx_state = WAIT_PACKET_TYPE;
int err;
INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- BLUEZ_VER);
+ VERSION);
INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
/* Register the tty discipline */
module_init(n_hci_init);
module_exit(n_hci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
+MODULE_LICENSE("GPL");
* Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
*
- * $Id: hci_usb.c,v 1.1 2001/06/01 08:12:10 davem Exp $
+ * $Id: hci_usb.c,v 1.5 2001/07/05 18:42:44 maxk Exp $
*/
+#define VERSION "1.0"
#include <linux/config.h>
#include <linux/module.h>
usb_free_urb(husb->write_urb);
if (husb->intr_skb)
- bluez_skb_free(husb->intr_skb);
+ kfree_skb(husb->intr_skb);
}
/* ------- Interface to HCI layer ------ */
DBG("%s", hdev->name);
/* Drop TX queues */
- bluez_skb_queue_purge(&husb->tx_ctrl_q);
- bluez_skb_queue_purge(&husb->tx_write_q);
+ skb_queue_purge(&husb->tx_ctrl_q);
+ skb_queue_purge(&husb->tx_write_q);
return 0;
}
goto done;
if (hci_usb_ctrl_msg(husb, skb)){
- bluez_skb_free(skb);
+ kfree_skb(skb);
goto done;
}
DBG("%s ctrl status: %d", hdev->name, urb->status);
clear_bit(HCI_TX_CTRL, &husb->tx_state);
- bluez_skb_free(skb);
+ kfree_skb(skb);
/* Wake up device */
hci_usb_ctrl_wakeup(husb);
DBG("%s bulk write status: %d", hdev->name, urb->status);
clear_bit(HCI_TX_WRITE, &husb->tx_state);
- bluez_skb_free(skb);
+ kfree_skb(skb);
/* Wake up device */
hci_usb_write_wakeup(husb);
if (count > husb->intr_count) {
ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
- bluez_skb_free(skb);
+ kfree_skb(skb);
husb->intr_skb = NULL;
husb->intr_count = 0;
return;
ep = bulk_in_ep;
pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
- size = HCI_USB_MAX_READ;
+ size = HCI_MAX_FRAME_SIZE;
if (!(buf = kmalloc(size, GFP_KERNEL))) {
ERR("Can't allocate: read buffer");
int err;
INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- BLUEZ_VER);
+ VERSION);
INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
if ((err = usb_register(&hci_usb_driver)) < 0)
module_init(hci_usb_init);
module_exit(hci_usb_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2000-2001 Qualcomm Incorporated
+
+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * BlueZ HCI virtual device driver.
+ *
+ * $Id: hci_vhci.c,v 1.3 2001/08/03 04:19:50 maxk Exp $
+ */
+#define VERSION "1.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/poll.h>
+#include <linux/fcntl.h>
+#include <linux/init.h>
+#include <linux/random.h>
+
+#include <linux/skbuff.h>
+#include <linux/miscdevice.h>
+
+#include <asm/system.h>
+#include <asm/uaccess.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/bluez.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/hci_vhci.h>
+
+/* HCI device part */
+
+int hci_vhci_open(struct hci_dev *hdev)
+{
+ hdev->flags |= HCI_RUNNING;
+ return 0;
+}
+
+int hci_vhci_flush(struct hci_dev *hdev)
+{
+ struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
+ skb_queue_purge(&hci_vhci->readq);
+ return 0;
+}
+
+int hci_vhci_close(struct hci_dev *hdev)
+{
+ hdev->flags &= ~HCI_RUNNING;
+ hci_vhci_flush(hdev);
+ return 0;
+}
+
+int hci_vhci_send_frame(struct sk_buff *skb)
+{
+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
+ struct hci_vhci_struct *hci_vhci;
+
+ if (!hdev) {
+ ERR("Frame for uknown device (hdev=NULL)");
+ return -ENODEV;
+ }
+
+ if (!(hdev->flags & HCI_RUNNING))
+ return -EBUSY;
+
+ hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
+
+ memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
+ skb_queue_tail(&hci_vhci->readq, skb);
+
+ if (hci_vhci->flags & VHCI_FASYNC)
+ kill_fasync(&hci_vhci->fasync, SIGIO, POLL_IN);
+ wake_up_interruptible(&hci_vhci->read_wait);
+
+ return 0;
+}
+
+/* Character device part */
+
+/* Poll */
+static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
+{
+ struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+ poll_wait(file, &hci_vhci->read_wait, wait);
+
+ if (skb_queue_len(&hci_vhci->readq))
+ return POLLIN | POLLRDNORM;
+
+ return POLLOUT | POLLWRNORM;
+}
+
+/* Get packet from user space buffer(already verified) */
+static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char *buf, size_t count)
+{
+ struct sk_buff *skb;
+
+ if (count > HCI_MAX_FRAME_SIZE)
+ return -EINVAL;
+
+ if (!(skb = bluez_skb_alloc(count, GFP_KERNEL)))
+ return -ENOMEM;
+
+ copy_from_user(skb_put(skb, count), buf, count);
+
+ skb->dev = (void *) &hci_vhci->hdev;
+ skb->pkt_type = *((__u8 *) skb->data);
+ skb_pull(skb, 1);
+
+ hci_recv_frame(skb);
+
+ return count;
+}
+
+/* Write */
+static ssize_t hci_vhci_chr_write(struct file * file, const char * buf,
+ size_t count, loff_t *pos)
+{
+ struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+ if (verify_area(VERIFY_READ, buf, count))
+ return -EFAULT;
+
+ return hci_vhci_get_user(hci_vhci, buf, count);
+}
+
+/* Put packet to user space buffer(already verified) */
+static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
+ struct sk_buff *skb, char *buf, int count)
+{
+ int len = count, total = 0;
+ char *ptr = buf;
+
+ len = MIN(skb->len, len);
+ copy_to_user(ptr, skb->data, len);
+ total += len;
+
+ hci_vhci->hdev.stat.byte_tx += len;
+ switch (skb->pkt_type) {
+ case HCI_COMMAND_PKT:
+ hci_vhci->hdev.stat.cmd_tx++;
+ break;
+
+ case HCI_ACLDATA_PKT:
+ hci_vhci->hdev.stat.acl_tx++;
+ break;
+
+ case HCI_SCODATA_PKT:
+ hci_vhci->hdev.stat.cmd_tx++;
+ break;
+ };
+
+ return total;
+}
+
+/* Read */
+static ssize_t hci_vhci_chr_read(struct file * file, char * buf, size_t count, loff_t *pos)
+{
+ struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+ DECLARE_WAITQUEUE(wait, current);
+ struct sk_buff *skb;
+ ssize_t ret = 0;
+
+ add_wait_queue(&hci_vhci->read_wait, &wait);
+ while (count) {
+ current->state = TASK_INTERRUPTIBLE;
+
+ /* Read frames from device queue */
+ if (!(skb = skb_dequeue(&hci_vhci->readq))) {
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EAGAIN;
+ break;
+ }
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+
+ /* Nothing to read, let's sleep */
+ schedule();
+ continue;
+ }
+
+ if (!verify_area(VERIFY_WRITE, buf, count))
+ ret = hci_vhci_put_user(hci_vhci, skb, buf, count);
+ else
+ ret = -EFAULT;
+
+ kfree_skb(skb);
+ break;
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&hci_vhci->read_wait, &wait);
+
+ return ret;
+}
+
+static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+ return -EINVAL;
+}
+
+static int hci_vhci_chr_fasync(int fd, struct file *file, int on)
+{
+ struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+ int ret;
+
+ if ((ret = fasync_helper(fd, file, on, &hci_vhci->fasync)) < 0)
+ return ret;
+
+ if (on)
+ hci_vhci->flags |= VHCI_FASYNC;
+ else
+ hci_vhci->flags &= ~VHCI_FASYNC;
+
+ return 0;
+}
+
+static int hci_vhci_chr_open(struct inode *inode, struct file * file)
+{
+ struct hci_vhci_struct *hci_vhci = NULL;
+ struct hci_dev *hdev;
+
+ if (!(hci_vhci = kmalloc(sizeof(struct hci_vhci_struct), GFP_KERNEL)))
+ return -ENOMEM;
+
+ memset(hci_vhci, 0, sizeof(struct hci_vhci_struct));
+
+ skb_queue_head_init(&hci_vhci->readq);
+ init_waitqueue_head(&hci_vhci->read_wait);
+
+ /* Initialize and register HCI device */
+ hdev = &hci_vhci->hdev;
+
+ hdev->type = HCI_VHCI;
+ hdev->driver_data = hci_vhci;
+
+ hdev->open = hci_vhci_open;
+ hdev->close = hci_vhci_close;
+ hdev->flush = hci_vhci_flush;
+ hdev->send = hci_vhci_send_frame;
+
+ if (hci_register_dev(hdev) < 0) {
+ kfree(hci_vhci);
+ return -EBUSY;
+ }
+
+ file->private_data = hci_vhci;
+ return 0;
+}
+
+static int hci_vhci_chr_close(struct inode *inode, struct file *file)
+{
+ struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
+
+ if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
+ ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
+ }
+
+ kfree(hci_vhci);
+ file->private_data = NULL;
+
+ return 0;
+}
+
+static struct file_operations hci_vhci_fops = {
+ owner: THIS_MODULE,
+ llseek: hci_vhci_chr_lseek,
+ read: hci_vhci_chr_read,
+ write: hci_vhci_chr_write,
+ poll: hci_vhci_chr_poll,
+ ioctl: hci_vhci_chr_ioctl,
+ open: hci_vhci_chr_open,
+ release:hci_vhci_chr_close,
+ fasync: hci_vhci_chr_fasync
+};
+
+static struct miscdevice hci_vhci_miscdev=
+{
+ VHCI_MINOR,
+ "hci_vhci",
+ &hci_vhci_fops
+};
+
+int __init hci_vhci_init(void)
+{
+ INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
+ VERSION);
+ INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+
+ if (misc_register(&hci_vhci_miscdev)) {
+ ERR("Can't register misc device %d\n", VHCI_MINOR);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+void hci_vhci_cleanup(void)
+{
+ misc_deregister(&hci_vhci_miscdev);
+}
+
+module_init(hci_vhci_init);
+module_exit(hci_vhci_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
+MODULE_LICENSE("GPL");
#include <linux/major.h>
#include <linux/devfs_fs_kernel.h>
-#ifndef AZT_KERNEL_PRIOR_2_1
#include <linux/init.h>
-#endif
#include <asm/system.h>
#include <asm/io.h>
-#ifdef AZT_KERNEL_PRIOR_2_1
-#include <asm/segment.h>
-#else
#include <asm/uaccess.h>
static int aztcd_blocksizes[1] = {2048};
-#endif
/*###########################################################################
#define azt_port aztcd /*needed for the modutils*/
-#ifndef AZT_KERNEL_PRIOR_2_1
-#define memcpy_fromfs copy_from_user
-#define memcpy_tofs copy_to_user
-#endif
-
/*##########################################################################
Type Definitions
##########################################################################
static int azt_port = AZT_BASE_ADDR;
-#ifndef AZT_KERNEL_PRIOR_2_1
MODULE_PARM(azt_port, "i");
-#endif
static int azt_port_auto[16] = AZT_BASE_AUTO;
static void azt_invalidate_buffers(void);
int aztcd_open(struct inode *ip, struct file *fp);
-#ifdef AZT_KERNEL_PRIOR_2_1
-static void aztcd_release(struct inode * inode, struct file * file);
-#else
static int aztcd_release(struct inode * inode, struct file * file);
-#endif
int aztcd_init(void);
* Kernel IO-controls
*/
static int aztcd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
-{ int i, st;
+{ int i;
struct azt_Toc qInfo;
struct cdrom_ti ti;
struct cdrom_tochdr tocHdr;
#ifdef AZT_DEBUG
printk("aztcd ioctl MULTISESSION\n");
#endif
- st = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct cdrom_multisession));
- if (st) return st;
- memcpy_fromfs(&ms, (void*) arg, sizeof(struct cdrom_multisession));
+ if(copy_from_user(&ms, (void*) arg, sizeof(struct cdrom_multisession)))
+ return -EFAULT;
if (ms.addr_format == CDROM_MSF)
{ ms.addr.msf.minute = azt_bcd2bin(DiskInfo.lastSession.min);
ms.addr.msf.second = azt_bcd2bin(DiskInfo.lastSession.sec);
else
return -EINVAL;
ms.xa_flag = DiskInfo.xa;
- memcpy_tofs((void*) arg, &ms, sizeof(struct cdrom_multisession));
+ if(copy_to_user((void*) arg, &ms, sizeof(struct cdrom_multisession)))
+ return -EFAULT;
#ifdef AZT_DEBUG
if (ms.addr_format == CDROM_MSF)
printk("aztcd multisession xa:%d, msf:%02x:%02x.%02x [%02x:%02x.%02x])\n",
return 0;
}
case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- st = verify_area(VERIFY_READ, (void *) arg, sizeof ti);
- if (st) return st;
- memcpy_fromfs(&ti, (void *) arg, sizeof ti);
+ if(copy_from_user(&ti, (void *) arg, sizeof ti))
+ return -EFAULT;
if (ti.cdti_trk0 < DiskInfo.first
|| ti.cdti_trk0 > DiskInfo.last
|| ti.cdti_trk1 < ti.cdti_trk0)
aztAudioStatus = CDROM_AUDIO_NO_STATUS;
}
*/
- st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
- if (st) return st;
- memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+ if(copy_from_user(&msf, (void *) arg, sizeof msf))
+ return -EFAULT;
/* convert to bcd */
azt_bin2bcd(&msf.cdmsf_min0);
azt_bin2bcd(&msf.cdmsf_sec0);
break;
case CDROMREADTOCHDR: /* Read the table of contents header */
- st = verify_area(VERIFY_WRITE, (void *) arg, sizeof tocHdr);
- if (st) return st;
tocHdr.cdth_trk0 = DiskInfo.first;
tocHdr.cdth_trk1 = DiskInfo.last;
- memcpy_tofs((void *) arg, &tocHdr, sizeof tocHdr);
+ if(copy_to_user((void *) arg, &tocHdr, sizeof tocHdr))
+ return -EFAULT;
break;
case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
- st = verify_area(VERIFY_WRITE, (void *) arg, sizeof entry);
- if (st) return st;
- memcpy_fromfs(&entry, (void *) arg, sizeof entry);
+ if(copy_from_user(&entry, (void *) arg, sizeof entry))
+ return -EFAULT;
if ((!aztTocUpToDate)||aztDiskChanged) aztUpdateToc();
if (entry.cdte_track == CDROM_LEADOUT)
tocPtr = &Toc[DiskInfo.last + 1];
else
{ return -EINVAL;
}
- memcpy_tofs((void *) arg, &entry, sizeof entry);
+ if(copy_to_user((void *) arg, &entry, sizeof entry))
+ return -EFAULT;
break;
case CDROMSUBCHNL: /* Get subchannel info */
- st = verify_area(VERIFY_WRITE, (void *) arg, sizeof(struct cdrom_subchnl));
- if (st) {
-#ifdef AZT_DEBUG
- printk("aztcd: exiting aztcd_ioctl - Error 1 - Command:%x\n",cmd);
-#endif
- return st;
- }
- memcpy_fromfs(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl));
- if (aztGetQChannelInfo(&qInfo) < 0)
- if (st) {
+ if(copy_from_user(&subchnl, (void *) arg, sizeof (struct cdrom_subchnl)))
+ return -EFAULT;
+ if (aztGetQChannelInfo(&qInfo) < 0) {
#ifdef AZT_DEBUG
printk("aztcd: exiting aztcd_ioctl - Error 3 - Command:%x\n",cmd);
#endif
subchnl.cdsc_reladdr.msf.second = azt_bcd2bin(qInfo.trackTime.sec);
subchnl.cdsc_reladdr.msf.frame = azt_bcd2bin(qInfo.trackTime.frame);
}
- memcpy_tofs((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
+ if(copy_to_user((void *) arg, &subchnl, sizeof (struct cdrom_subchnl)))
+ return -EFAULT;
break;
case CDROMVOLCTRL: /* Volume control
* With my Aztech CD268-01A volume control does not work, I can only
turn the channels on (any value !=0) or off (value==0). Maybe it
works better with your drive */
- st=verify_area(VERIFY_READ,(void *) arg, sizeof(volctrl));
- if (st) return (st);
- memcpy_fromfs(&volctrl,(char *) arg,sizeof(volctrl));
+ if(copy_from_user(&volctrl,(char *) arg,sizeof(volctrl)))
+ return -EFAULT;
azt_Play.start.min = 0x21;
azt_Play.start.sec = 0x84;
azt_Play.start.frame = volctrl.channel0;
#if AZT_PRIVATE_IOCTLS
case CDROMREADCOOKED: /*read data in mode 1 (2048 Bytes)*/
case CDROMREADRAW: /*read data in mode 2 (2336 Bytes)*/
- { st = verify_area(VERIFY_WRITE, (void *) arg, sizeof buf);
- if (st) return st;
- memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+ {
+ if(copy_from_user(&msf, (void *) arg, sizeof msf))
+ return -EFAULT;
/* convert to bcd */
azt_bin2bcd(&msf.cdmsf_min0);
azt_bin2bcd(&msf.cdmsf_sec0);
{ if (sendAztCmd(ACMD_PLAY_READ_RAW, &azt_Play)) return -1;
DTEN_LOW;
insb(DATA_PORT,buf,CD_FRAMESIZE_RAW);
- memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE_RAW);
+ if(copy_to_user((void *) arg, &buf, CD_FRAMESIZE_RAW))
+ return -EFAULT;
}
}
else /*CDROMREADCOOKED*/
{ if (sendAztCmd(ACMD_PLAY_READ, &azt_Play)) return -1;
DTEN_LOW;
insb(DATA_PORT,buf,CD_FRAMESIZE);
- memcpy_tofs((void *) arg, &buf, CD_FRAMESIZE);
+ if(copy_to_user((void *) arg, &buf, CD_FRAMESIZE))
+ return -EFAULT;
}
}
break;
case CDROMSEEK: /*seek msf address*/
- st = verify_area(VERIFY_READ, (void *) arg, sizeof msf);
- if (st) return st;
- memcpy_fromfs(&msf, (void *) arg, sizeof msf);
+ if(copy_from_user(&msf, (void *) arg, sizeof msf))
+ return -EFAULT;
/* convert to bcd */
azt_bin2bcd(&msf.cdmsf_min0);
azt_bin2bcd(&msf.cdmsf_sec0);
/*
* On close, we flush all azt blocks from the buffer cache.
*/
-#ifdef AZT_KERNEL_PRIOR_2_1
-static void aztcd_release(struct inode * inode, struct file * file)
-#else
static int aztcd_release(struct inode * inode, struct file * file)
-#endif
{
#ifdef AZT_DEBUG
printk("aztcd: executing aztcd_release\n");
aztSendCmd(ACMD_EJECT);
CLEAR_TIMER;
}
-#ifdef AZT_KERNEL_PRIOR_2_1
- return;
-#else
return 0;
-#endif
}
return -EIO;
}
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
-#ifndef AZT_KERNEL_PRIOR_2_1
blksize_size[MAJOR_NR] = aztcd_blocksizes;
-#endif
read_ahead[MAJOR_NR] = 4;
register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &azt_fops, 0);
static int azt_bcd2bin(unsigned char bcd)
{ return (bcd >> 4) * 10 + (bcd & 0xF);
}
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
#define MAJOR_NR CDU31A_CDROM_MAJOR
#include <linux/blk.h>
-#define CDU31A_READAHEAD 4 /* 128 sector, 64kB, 32 reads read-ahead */
+#define CDU31A_READAHEAD 4 /* 128 sector, 64kB, 32 reads read-ahead */
#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10
#define DEBUG 0
** Default is polled and no DMA. DMA is not recommended for double-speed
** drives.
*/
-static struct
-{
- unsigned short base; /* I/O Base Address */
- short int_num; /* Interrupt Number (-1 means scan for it,
- 0 means don't use) */
-} cdu31a_addresses[] __initdata =
-{
-#if 0 /* No autoconfig any more. See Note at beginning
- of this file. */
- { 0x340, 0 }, /* Standard configuration Sony Interface */
- { 0x1f88, 0 }, /* Fusion CD-16 */
- { 0x230, 0 }, /* SoundBlaster 16 card */
- { 0x360, 0 }, /* Secondary standard Sony Interface */
- { 0x320, 0 }, /* Secondary standard Sony Interface */
- { 0x330, 0 }, /* Secondary standard Sony Interface */
- { 0x634, 0 }, /* Sound FX SC400 */
- { 0x654, 0 }, /* Sound FX SC400 */
-#endif
- { 0 }
+static struct {
+ unsigned short base; /* I/O Base Address */
+ short int_num; /* Interrupt Number (-1 means scan for it,
+ 0 means don't use) */
+} cdu31a_addresses[] __initdata = {
+ {0}
};
static int handle_sony_cd_attention(void);
/*static int scd_open(struct inode *inode, struct file *filp);*/
static int scd_open(struct cdrom_device_info *, int);
static void do_sony_cd_cmd(unsigned char cmd,
- unsigned char *params,
- unsigned int num_params,
- unsigned char *result_buffer,
- unsigned int *result_size);
-static void size_to_buf(unsigned int size,
- unsigned char *buf);
+ unsigned char *params,
+ unsigned int num_params,
+ unsigned char *result_buffer,
+ unsigned int *result_size);
+static void size_to_buf(unsigned int size, unsigned char *buf);
/* Parameters for the read-ahead. */
-static unsigned int sony_next_block; /* Next 512 byte block offset */
-static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
- in the current read command. */
+static unsigned int sony_next_block; /* Next 512 byte block offset */
+static unsigned int sony_blocks_left = 0; /* Number of 512 byte blocks left
+ in the current read command. */
/* The base I/O address of the Sony Interface. This is a variable (not a
static volatile unsigned short sony_cd_fifost_reg;
-static int sony_spun_up = 0; /* Has the drive been spun up? */
+static int sony_spun_up = 0; /* Has the drive been spun up? */
-static int sony_speed = 0; /* Last wanted speed */
+static int sony_speed = 0; /* Last wanted speed */
-static int sony_xa_mode = 0; /* Is an XA disk in the drive
- and the drive a CDU31A? */
+static int sony_xa_mode = 0; /* Is an XA disk in the drive
+ and the drive a CDU31A? */
-static int sony_raw_data_mode = 1; /* 1 if data tracks, 0 if audio.
- For raw data reads. */
+static int sony_raw_data_mode = 1; /* 1 if data tracks, 0 if audio.
+ For raw data reads. */
-static unsigned int sony_usage = 0; /* How many processes have the
- drive open. */
+static unsigned int sony_usage = 0; /* How many processes have the
+ drive open. */
-static int sony_pas_init = 0; /* Initialize the Pro-Audio
- Spectrum card? */
+static int sony_pas_init = 0; /* Initialize the Pro-Audio
+ Spectrum card? */
-static struct s_sony_session_toc single_toc; /* Holds the
- table of
- contents. */
+static struct s_sony_session_toc single_toc; /* Holds the
+ table of
+ contents. */
-static struct s_all_sessions_toc sony_toc; /* entries gathered from all
- sessions */
+static struct s_all_sessions_toc sony_toc; /* entries gathered from all
+ sessions */
-static int sony_toc_read = 0; /* Has the TOC been read for
- the drive? */
+static int sony_toc_read = 0; /* Has the TOC been read for
+ the drive? */
-static struct s_sony_subcode last_sony_subcode; /* Points to the last
- subcode address read */
+static struct s_sony_subcode last_sony_subcode; /* Points to the last
+ subcode address read */
-static volatile int sony_inuse = 0; /* Is the drive in use? Only one operation
- at a time allowed */
+static volatile int sony_inuse = 0; /* Is the drive in use? Only one operation
+ at a time allowed */
static DECLARE_WAIT_QUEUE_HEAD(sony_wait); /* Things waiting for the drive */
-static struct task_struct *has_cd_task = NULL; /* The task that is currently
+static struct task_struct *has_cd_task = NULL; /* The task that is currently
using the CDROM drive, or
NULL if none. */
-static int is_double_speed = 0; /* does the drive support double speed ? */
-static int is_a_cdu31a = 1; /* Is the drive a CDU31A? */
+static int is_double_speed = 0; /* does the drive support double speed ? */
+static int is_a_cdu31a = 1; /* Is the drive a CDU31A? */
-static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */
+static int is_auto_eject = 1; /* Door has been locked? 1=No/0=Yes */
/*
* The audio status uses the values from read subchannel data as specified
interrupts. */
DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait);
-static int curr_control_reg = 0; /* Current value of the control register */
+static int curr_control_reg = 0; /* Current value of the control register */
/* A disk changed variable. When a disk change is detected, it will
all be set to TRUE. As the upper layers ask for disk_changed status
* This routine returns 1 if the disk has been changed since the last
* check or 0 if it hasn't.
*/
-static int
-scd_disk_change(kdev_t full_dev)
+static int scd_disk_change(kdev_t full_dev)
{
- int retval;
+ int retval;
- retval = disk_changed;
- disk_changed = 0;
+ retval = disk_changed;
+ disk_changed = 0;
- return retval;
+ return retval;
}
/*
* Uniform cdrom interface function
* report back, if disc has changed from time of last request.
*/
-static int
-scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
+static int scd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
- return scd_disk_change(cdi->dev);
+ return scd_disk_change(cdi->dev);
}
/*
*/
static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
{
- if (CDSL_CURRENT != slot_nr) {
- /* we have no changer support */
- return -EINVAL;
- }
- if (scd_spinup() == 0) {
- sony_spun_up = 1;
- }
- return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
+ if (CDSL_CURRENT != slot_nr) {
+ /* we have no changer support */
+ return -EINVAL;
+ }
+ if (scd_spinup() == 0) {
+ sony_spun_up = 1;
+ }
+ return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
}
-static inline void
-enable_interrupts(void)
+static inline void enable_interrupts(void)
{
- curr_control_reg |= ( SONY_ATTN_INT_EN_BIT
- | SONY_RES_RDY_INT_EN_BIT
- | SONY_DATA_RDY_INT_EN_BIT);
- outb(curr_control_reg, sony_cd_control_reg);
+ curr_control_reg |= (SONY_ATTN_INT_EN_BIT
+ | SONY_RES_RDY_INT_EN_BIT
+ | SONY_DATA_RDY_INT_EN_BIT);
+ outb(curr_control_reg, sony_cd_control_reg);
}
-static inline void
-disable_interrupts(void)
+static inline void disable_interrupts(void)
{
- curr_control_reg &= ~( SONY_ATTN_INT_EN_BIT
- | SONY_RES_RDY_INT_EN_BIT
- | SONY_DATA_RDY_INT_EN_BIT);
- outb(curr_control_reg, sony_cd_control_reg);
+ curr_control_reg &= ~(SONY_ATTN_INT_EN_BIT
+ | SONY_RES_RDY_INT_EN_BIT
+ | SONY_DATA_RDY_INT_EN_BIT);
+ outb(curr_control_reg, sony_cd_control_reg);
}
/*
* Wait a little while (used for polling the drive). If in initialization,
* setting a timeout doesn't work, so just loop for a while.
*/
-static inline void
-sony_sleep(void)
+static inline void sony_sleep(void)
{
- unsigned long flags;
+ unsigned long flags;
+
+ if (cdu31a_irq <= 0) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(0);
+ } else { /* Interrupt driven */
- if (cdu31a_irq <= 0)
- {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(0);
- }
- else /* Interrupt driven */
- {
- save_flags(flags);
- cli();
- enable_interrupts();
- interruptible_sleep_on(&cdu31a_irq_wait);
- restore_flags(flags);
- }
+ save_flags(flags);
+ cli();
+ enable_interrupts();
+ interruptible_sleep_on(&cdu31a_irq_wait);
+ restore_flags(flags);
+ }
}
* The following are convenience routine to read various status and set
* various conditions in the drive.
*/
-static inline int
-is_attention(void)
+static inline int is_attention(void)
{
- return((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
+ return ((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
}
-static inline int
-is_busy(void)
+static inline int is_busy(void)
{
- return((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
+ return ((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
}
-static inline int
-is_data_ready(void)
+static inline int is_data_ready(void)
{
- return((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
+ return ((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
}
-static inline int
-is_data_requested(void)
+static inline int is_data_requested(void)
{
- return((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
+ return ((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
}
-static inline int
-is_result_ready(void)
+static inline int is_result_ready(void)
{
- return((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
+ return ((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
}
-static inline int
-is_param_write_rdy(void)
+static inline int is_param_write_rdy(void)
{
- return((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
+ return ((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
}
-static inline int
-is_result_reg_not_empty(void)
+static inline int is_result_reg_not_empty(void)
{
- return((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
+ return ((inb(sony_cd_fifost_reg) & SONY_RES_REG_NOT_EMP_BIT) != 0);
}
-static inline void
-reset_drive(void)
+static inline void reset_drive(void)
{
- curr_control_reg = 0;
- readahead_dataleft = 0;
- sony_toc_read = 0;
- outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
+ curr_control_reg = 0;
+ readahead_dataleft = 0;
+ sony_toc_read = 0;
+ outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
}
/*
* Uniform cdrom interface function
* reset drive and return when it is ready
*/
-static int scd_reset(struct cdrom_device_info * cdi)
+static int scd_reset(struct cdrom_device_info *cdi)
{
- int retry_count;
+ int retry_count;
- reset_drive();
+ reset_drive();
- retry_count = jiffies + SONY_RESET_TIMEOUT;
- while (time_before(jiffies, retry_count) && (!is_attention()))
- {
- sony_sleep();
- }
+ retry_count = jiffies + SONY_RESET_TIMEOUT;
+ while (time_before(jiffies, retry_count) && (!is_attention())) {
+ sony_sleep();
+ }
- return 0;
+ return 0;
}
-static inline void
-clear_attention(void)
+static inline void clear_attention(void)
{
- outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
+ outb(curr_control_reg | SONY_ATTN_CLR_BIT, sony_cd_control_reg);
}
-static inline void
-clear_result_ready(void)
+static inline void clear_result_ready(void)
{
- outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
+ outb(curr_control_reg | SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
}
-static inline void
-clear_data_ready(void)
+static inline void clear_data_ready(void)
{
- outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT, sony_cd_control_reg);
+ outb(curr_control_reg | SONY_DATA_RDY_CLR_BIT,
+ sony_cd_control_reg);
}
-static inline void
-clear_param_reg(void)
+static inline void clear_param_reg(void)
{
- outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
+ outb(curr_control_reg | SONY_PARAM_CLR_BIT, sony_cd_control_reg);
}
-static inline unsigned char
-read_status_register(void)
+static inline unsigned char read_status_register(void)
{
- return(inb(sony_cd_status_reg));
+ return (inb(sony_cd_status_reg));
}
-static inline unsigned char
-read_result_register(void)
+static inline unsigned char read_result_register(void)
{
- return(inb(sony_cd_result_reg));
+ return (inb(sony_cd_result_reg));
}
-static inline unsigned char
-read_data_register(void)
+static inline unsigned char read_data_register(void)
{
- return(inb(sony_cd_read_reg));
+ return (inb(sony_cd_read_reg));
}
-static inline void
-write_param(unsigned char param)
+static inline void write_param(unsigned char param)
{
- outb(param, sony_cd_param_reg);
+ outb(param, sony_cd_param_reg);
}
-static inline void
-write_cmd(unsigned char cmd)
+static inline void write_cmd(unsigned char cmd)
{
- outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT, sony_cd_control_reg);
- outb(cmd, sony_cd_cmd_reg);
+ outb(curr_control_reg | SONY_RES_RDY_INT_EN_BIT,
+ sony_cd_control_reg);
+ outb(cmd, sony_cd_cmd_reg);
}
-static void
-cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
- unsigned char val;
-
- if (abort_read_started)
- {
- /* We might be waiting for an abort to finish. Don't
- disable interrupts yet, though, because we handle
- this one here. */
- /* Clear out the result registers. */
- while (is_result_reg_not_empty())
- {
- val = read_result_register();
- }
- clear_data_ready();
- clear_result_ready();
-
- /* Clear out the data */
- while (is_data_requested())
- {
- val = read_data_register();
- }
- abort_read_started = 0;
-
- /* If something was waiting, wake it up now. */
- if (waitqueue_active(&cdu31a_irq_wait))
- {
- disable_interrupts();
- wake_up(&cdu31a_irq_wait);
- }
- }
- else if (waitqueue_active(&cdu31a_irq_wait))
- {
- disable_interrupts();
- wake_up(&cdu31a_irq_wait);
- }
- else
- {
- disable_interrupts();
- printk("CDU31A: Got an interrupt but nothing was waiting\n");
- }
+static void cdu31a_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned char val;
+
+ if (abort_read_started) {
+ /* We might be waiting for an abort to finish. Don't
+ disable interrupts yet, though, because we handle
+ this one here. */
+ /* Clear out the result registers. */
+ while (is_result_reg_not_empty()) {
+ val = read_result_register();
+ }
+ clear_data_ready();
+ clear_result_ready();
+
+ /* Clear out the data */
+ while (is_data_requested()) {
+ val = read_data_register();
+ }
+ abort_read_started = 0;
+
+ /* If something was waiting, wake it up now. */
+ if (waitqueue_active(&cdu31a_irq_wait)) {
+ disable_interrupts();
+ wake_up(&cdu31a_irq_wait);
+ }
+ } else if (waitqueue_active(&cdu31a_irq_wait)) {
+ disable_interrupts();
+ wake_up(&cdu31a_irq_wait);
+ } else {
+ disable_interrupts();
+ printk
+ ("CDU31A: Got an interrupt but nothing was waiting\n");
+ }
}
/*
* give more verbose error messages
*/
-static unsigned char *translate_error( unsigned char err_code )
-{
- static unsigned char errbuf[80];
-
- switch (err_code) {
- case 0x10: return "illegal command ";
- case 0x11: return "illegal parameter ";
-
- case 0x20: return "not loaded ";
- case 0x21: return "no disc ";
- case 0x22: return "not spinning ";
- case 0x23: return "spinning ";
- case 0x25: return "spindle servo ";
- case 0x26: return "focus servo ";
- case 0x29: return "eject mechanism ";
- case 0x2a: return "audio playing ";
- case 0x2c: return "emergency eject ";
-
- case 0x30: return "focus ";
- case 0x31: return "frame sync ";
- case 0x32: return "subcode address ";
- case 0x33: return "block sync ";
- case 0x34: return "header address ";
-
- case 0x40: return "illegal track read ";
- case 0x41: return "mode 0 read ";
- case 0x42: return "illegal mode read ";
- case 0x43: return "illegal block size read ";
- case 0x44: return "mode read ";
- case 0x45: return "form read ";
- case 0x46: return "leadout read ";
- case 0x47: return "buffer overrun ";
-
- case 0x53: return "unrecoverable CIRC ";
- case 0x57: return "unrecoverable LECC ";
-
- case 0x60: return "no TOC ";
- case 0x61: return "invalid subcode data ";
- case 0x63: return "focus on TOC read ";
- case 0x64: return "frame sync on TOC read ";
- case 0x65: return "TOC data ";
-
- case 0x70: return "hardware failure ";
- case 0x91: return "leadin ";
- case 0x92: return "leadout ";
- case 0x93: return "data track ";
- }
- sprintf(errbuf, "unknown 0x%02x ", err_code);
- return errbuf;
+static unsigned char *translate_error(unsigned char err_code)
+{
+ static unsigned char errbuf[80];
+
+ switch (err_code) {
+ case 0x10:
+ return "illegal command ";
+ case 0x11:
+ return "illegal parameter ";
+
+ case 0x20:
+ return "not loaded ";
+ case 0x21:
+ return "no disc ";
+ case 0x22:
+ return "not spinning ";
+ case 0x23:
+ return "spinning ";
+ case 0x25:
+ return "spindle servo ";
+ case 0x26:
+ return "focus servo ";
+ case 0x29:
+ return "eject mechanism ";
+ case 0x2a:
+ return "audio playing ";
+ case 0x2c:
+ return "emergency eject ";
+
+ case 0x30:
+ return "focus ";
+ case 0x31:
+ return "frame sync ";
+ case 0x32:
+ return "subcode address ";
+ case 0x33:
+ return "block sync ";
+ case 0x34:
+ return "header address ";
+
+ case 0x40:
+ return "illegal track read ";
+ case 0x41:
+ return "mode 0 read ";
+ case 0x42:
+ return "illegal mode read ";
+ case 0x43:
+ return "illegal block size read ";
+ case 0x44:
+ return "mode read ";
+ case 0x45:
+ return "form read ";
+ case 0x46:
+ return "leadout read ";
+ case 0x47:
+ return "buffer overrun ";
+
+ case 0x53:
+ return "unrecoverable CIRC ";
+ case 0x57:
+ return "unrecoverable LECC ";
+
+ case 0x60:
+ return "no TOC ";
+ case 0x61:
+ return "invalid subcode data ";
+ case 0x63:
+ return "focus on TOC read ";
+ case 0x64:
+ return "frame sync on TOC read ";
+ case 0x65:
+ return "TOC data ";
+
+ case 0x70:
+ return "hardware failure ";
+ case 0x91:
+ return "leadin ";
+ case 0x92:
+ return "leadout ";
+ case 0x93:
+ return "data track ";
+ }
+ sprintf(errbuf, "unknown 0x%02x ", err_code);
+ return errbuf;
}
/*
* Set the drive parameters so the drive will auto-spin-up when a
* disk is inserted.
*/
-static void
-set_drive_params(int want_doublespeed)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned char params[3];
-
-
- params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
- params[1] = 0x00; /* Never spin down the drive. */
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk(" Unable to set spin-down time: 0x%2.2x\n", res_reg[1]);
- }
-
- params[0] = SONY_SD_MECH_CONTROL;
- params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
-
- if (is_auto_eject) params[1] |= SONY_AUTO_EJECT_BIT;
-
- if (is_double_speed && want_doublespeed)
- {
- params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if
- possible */
- }
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk(" Unable to set mechanical parameters: 0x%2.2x\n", res_reg[1]);
- }
+static void set_drive_params(int want_doublespeed)
+{
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ unsigned char params[3];
+
+
+ params[0] = SONY_SD_AUTO_SPIN_DOWN_TIME;
+ params[1] = 0x00; /* Never spin down the drive. */
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params, 2, res_reg, &res_size);
+ if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk(" Unable to set spin-down time: 0x%2.2x\n",
+ res_reg[1]);
+ }
+
+ params[0] = SONY_SD_MECH_CONTROL;
+ params[1] = SONY_AUTO_SPIN_UP_BIT; /* Set auto spin up */
+
+ if (is_auto_eject)
+ params[1] |= SONY_AUTO_EJECT_BIT;
+
+ if (is_double_speed && want_doublespeed) {
+ params[1] |= SONY_DOUBLE_SPEED_BIT; /* Set the drive to double speed if
+ possible */
+ }
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params, 2, res_reg, &res_size);
+ if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk(" Unable to set mechanical parameters: 0x%2.2x\n",
+ res_reg[1]);
+ }
}
/*
*/
static int scd_select_speed(struct cdrom_device_info *cdi, int speed)
{
- if (speed == 0)
- sony_speed = 1;
- else
- sony_speed = speed - 1;
+ if (speed == 0)
+ sony_speed = 1;
+ else
+ sony_speed = speed - 1;
- set_drive_params(sony_speed);
- return 0;
+ set_drive_params(sony_speed);
+ return 0;
}
/*
*/
static int scd_lock_door(struct cdrom_device_info *cdi, int lock)
{
- if (lock == 0 && sony_usage == 1)
- {
- /* Unlock the door, only if nobody is using the drive */
- is_auto_eject = 1;
- } else {
- is_auto_eject = 0;
- }
- set_drive_params(sony_speed);
- return 0;
+ if (lock == 0 && sony_usage == 1) {
+ /* Unlock the door, only if nobody is using the drive */
+ is_auto_eject = 1;
+ } else {
+ is_auto_eject = 0;
+ }
+ set_drive_params(sony_speed);
+ return 0;
}
/*
* This code will reset the drive and attempt to restore sane parameters.
*/
-static void
-restart_on_error(void)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned int retry_count;
-
-
- printk("cdu31a: Resetting drive on error\n");
- reset_drive();
- retry_count = jiffies + SONY_RESET_TIMEOUT;
- while (time_before(jiffies, retry_count) && (!is_attention()))
- {
- sony_sleep();
- }
- set_drive_params(sony_speed);
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("cdu31a: Unable to spin up drive: 0x%2.2x\n", res_reg[1]);
- }
-
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(2*HZ);
-
- sony_get_toc();
+static void restart_on_error(void)
+{
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ unsigned int retry_count;
+
+
+ printk("cdu31a: Resetting drive on error\n");
+ reset_drive();
+ retry_count = jiffies + SONY_RESET_TIMEOUT;
+ while (time_before(jiffies, retry_count) && (!is_attention())) {
+ sony_sleep();
+ }
+ set_drive_params(sony_speed);
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
+ if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk("cdu31a: Unable to spin up drive: 0x%2.2x\n",
+ res_reg[1]);
+ }
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(2 * HZ);
+
+ sony_get_toc();
}
/*
* This routine writes data to the parameter register. Since this should
* happen fairly fast, it is polled with no OS waits between.
*/
-static int
-write_params(unsigned char *params,
- int num_params)
+static int write_params(unsigned char *params, int num_params)
{
- unsigned int retry_count;
+ unsigned int retry_count;
- retry_count = SONY_READY_RETRIES;
- while ((retry_count > 0) && (!is_param_write_rdy()))
- {
- retry_count--;
- }
- if (!is_param_write_rdy())
- {
- return -EIO;
- }
+ retry_count = SONY_READY_RETRIES;
+ while ((retry_count > 0) && (!is_param_write_rdy())) {
+ retry_count--;
+ }
+ if (!is_param_write_rdy()) {
+ return -EIO;
+ }
- while (num_params > 0)
- {
- write_param(*params);
- params++;
- num_params--;
- }
+ while (num_params > 0) {
+ write_param(*params);
+ params++;
+ num_params--;
+ }
- return 0;
+ return 0;
}
* the drive manual.
*/
static void
-get_result(unsigned char *result_buffer,
- unsigned int *result_size)
-{
- unsigned char a, b;
- int i;
- unsigned int retry_count;
-
-
- while (handle_sony_cd_attention())
- ;
- /* Wait for the result data to be ready */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && (is_busy() || (!(is_result_ready()))))
- {
- sony_sleep();
-
- while (handle_sony_cd_attention())
- ;
- }
- if (is_busy() || (!(is_result_ready())))
- {
+get_result(unsigned char *result_buffer, unsigned int *result_size)
+{
+ unsigned char a, b;
+ int i;
+ unsigned int retry_count;
+
+
+ while (handle_sony_cd_attention());
+ /* Wait for the result data to be ready */
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ while (time_before(jiffies, retry_count)
+ && (is_busy() || (!(is_result_ready())))) {
+ sony_sleep();
+
+ while (handle_sony_cd_attention());
+ }
+ if (is_busy() || (!(is_result_ready()))) {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n", __LINE__);
#endif
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- return;
- }
-
- /*
- * Get the first two bytes. This determines what else needs
- * to be done.
- */
- clear_result_ready();
- a = read_result_register();
- *result_buffer = a;
- result_buffer++;
-
- /* Check for block error status result. */
- if ((a & 0xf0) == 0x50)
- {
- *result_size = 1;
- return;
- }
-
- b = read_result_register();
- *result_buffer = b;
- result_buffer++;
- *result_size = 2;
-
- /*
- * 0x20 means an error occurred. Byte 2 will have the error code.
- * Otherwise, the command succeeded, byte 2 will have the count of
- * how many more status bytes are coming.
- *
- * The result register can be read 10 bytes at a time, a wait for
- * result ready to be asserted must be done between every 10 bytes.
- */
- if ((a & 0xf0) != 0x20)
- {
- if (b > 8)
- {
- for (i=0; i<8; i++)
- {
- *result_buffer = read_result_register();
- result_buffer++;
- (*result_size)++;
- }
- b = b - 8;
-
- while (b > 10)
- {
- retry_count = SONY_READY_RETRIES;
- while ((retry_count > 0) && (!is_result_ready()))
- {
- retry_count--;
- }
- if (!is_result_ready())
- {
+ result_buffer[0] = 0x20;
+ result_buffer[1] = SONY_TIMEOUT_OP_ERR;
+ *result_size = 2;
+ return;
+ }
+
+ /*
+ * Get the first two bytes. This determines what else needs
+ * to be done.
+ */
+ clear_result_ready();
+ a = read_result_register();
+ *result_buffer = a;
+ result_buffer++;
+
+ /* Check for block error status result. */
+ if ((a & 0xf0) == 0x50) {
+ *result_size = 1;
+ return;
+ }
+
+ b = read_result_register();
+ *result_buffer = b;
+ result_buffer++;
+ *result_size = 2;
+
+ /*
+ * 0x20 means an error occurred. Byte 2 will have the error code.
+ * Otherwise, the command succeeded, byte 2 will have the count of
+ * how many more status bytes are coming.
+ *
+ * The result register can be read 10 bytes at a time, a wait for
+ * result ready to be asserted must be done between every 10 bytes.
+ */
+ if ((a & 0xf0) != 0x20) {
+ if (b > 8) {
+ for (i = 0; i < 8; i++) {
+ *result_buffer = read_result_register();
+ result_buffer++;
+ (*result_size)++;
+ }
+ b = b - 8;
+
+ while (b > 10) {
+ retry_count = SONY_READY_RETRIES;
+ while ((retry_count > 0)
+ && (!is_result_ready())) {
+ retry_count--;
+ }
+ if (!is_result_ready()) {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n",
+ __LINE__);
#endif
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- return;
- }
-
- clear_result_ready();
-
- for (i=0; i<10; i++)
- {
- *result_buffer = read_result_register();
- result_buffer++;
- (*result_size)++;
- }
- b = b - 10;
- }
-
- if (b > 0)
- {
- retry_count = SONY_READY_RETRIES;
- while ((retry_count > 0) && (!is_result_ready()))
- {
- retry_count--;
- }
- if (!is_result_ready())
- {
+ result_buffer[0] = 0x20;
+ result_buffer[1] =
+ SONY_TIMEOUT_OP_ERR;
+ *result_size = 2;
+ return;
+ }
+
+ clear_result_ready();
+
+ for (i = 0; i < 10; i++) {
+ *result_buffer =
+ read_result_register();
+ result_buffer++;
+ (*result_size)++;
+ }
+ b = b - 10;
+ }
+
+ if (b > 0) {
+ retry_count = SONY_READY_RETRIES;
+ while ((retry_count > 0)
+ && (!is_result_ready())) {
+ retry_count--;
+ }
+ if (!is_result_ready()) {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n",
+ __LINE__);
#endif
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- return;
- }
- }
- }
-
- while (b > 0)
- {
- *result_buffer = read_result_register();
- result_buffer++;
- (*result_size)++;
- b--;
- }
- }
+ result_buffer[0] = 0x20;
+ result_buffer[1] =
+ SONY_TIMEOUT_OP_ERR;
+ *result_size = 2;
+ return;
+ }
+ }
+ }
+
+ while (b > 0) {
+ *result_buffer = read_result_register();
+ result_buffer++;
+ (*result_size)++;
+ b--;
+ }
+ }
}
/*
*/
static void
do_sony_cd_cmd(unsigned char cmd,
- unsigned char *params,
- unsigned int num_params,
- unsigned char *result_buffer,
- unsigned int *result_size)
-{
- unsigned int retry_count;
- int num_retries;
- int recursive_call;
- unsigned long flags;
-
-
- save_flags(flags);
- cli();
- if (current != has_cd_task) /* Allow recursive calls to this routine */
- {
- while (sony_inuse)
- {
- interruptible_sleep_on(&sony_wait);
- if (signal_pending(current))
- {
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_SIGNAL_OP_ERR;
- *result_size = 2;
- restore_flags(flags);
- return;
- }
- }
- sony_inuse = 1;
- has_cd_task = current;
- recursive_call = 0;
- }
- else
- {
- recursive_call = 1;
- }
-
- num_retries = 0;
+ unsigned char *params,
+ unsigned int num_params,
+ unsigned char *result_buffer, unsigned int *result_size)
+{
+ unsigned int retry_count;
+ int num_retries;
+ int recursive_call;
+ unsigned long flags;
+
+
+ save_flags(flags);
+ cli();
+ if (current != has_cd_task) { /* Allow recursive calls to this routine */
+ while (sony_inuse) {
+ interruptible_sleep_on(&sony_wait);
+ if (signal_pending(current)) {
+ result_buffer[0] = 0x20;
+ result_buffer[1] = SONY_SIGNAL_OP_ERR;
+ *result_size = 2;
+ restore_flags(flags);
+ return;
+ }
+ }
+ sony_inuse = 1;
+ has_cd_task = current;
+ recursive_call = 0;
+ } else {
+ recursive_call = 1;
+ }
+
+ num_retries = 0;
retry_cd_operation:
- while (handle_sony_cd_attention())
- ;
-
- sti();
-
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && (is_busy()))
- {
- sony_sleep();
-
- while (handle_sony_cd_attention())
- ;
- }
- if (is_busy())
- {
-#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
-#endif
- result_buffer[0] = 0x20;
- result_buffer[1] = SONY_TIMEOUT_OP_ERR;
- *result_size = 2;
- }
- else
- {
- clear_result_ready();
- clear_param_reg();
-
- write_params(params, num_params);
- write_cmd(cmd);
+ while (handle_sony_cd_attention());
- get_result(result_buffer, result_size);
- }
+ sti();
- if ( ((result_buffer[0] & 0xf0) == 0x20)
- && (num_retries < MAX_CDU31A_RETRIES))
- {
- num_retries++;
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/10); /* Wait .1 seconds on retries */
- goto retry_cd_operation;
- }
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ while (time_before(jiffies, retry_count) && (is_busy())) {
+ sony_sleep();
- if (!recursive_call)
- {
- has_cd_task = NULL;
- sony_inuse = 0;
- wake_up_interruptible(&sony_wait);
- }
-
- restore_flags(flags);
+ while (handle_sony_cd_attention());
+ }
+ if (is_busy()) {
+#if DEBUG
+ printk("CDU31A timeout out %d\n", __LINE__);
+#endif
+ result_buffer[0] = 0x20;
+ result_buffer[1] = SONY_TIMEOUT_OP_ERR;
+ *result_size = 2;
+ } else {
+ clear_result_ready();
+ clear_param_reg();
+
+ write_params(params, num_params);
+ write_cmd(cmd);
+
+ get_result(result_buffer, result_size);
+ }
+
+ if (((result_buffer[0] & 0xf0) == 0x20)
+ && (num_retries < MAX_CDU31A_RETRIES)) {
+ num_retries++;
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ / 10); /* Wait .1 seconds on retries */
+ goto retry_cd_operation;
+ }
+
+ if (!recursive_call) {
+ has_cd_task = NULL;
+ sony_inuse = 0;
+ wake_up_interruptible(&sony_wait);
+ }
+
+ restore_flags(flags);
}
* a 0), and returns a 0 if it happens too many times. This will help
* prevent a lockup.
*/
-static int
-handle_sony_cd_attention(void)
+static int handle_sony_cd_attention(void)
{
- unsigned char atten_code;
- static int num_consecutive_attentions = 0;
- volatile int val;
+ unsigned char atten_code;
+ static int num_consecutive_attentions = 0;
+ volatile int val;
#if 0*DEBUG
- printk("Entering handle_sony_cd_attention\n");
+ printk("Entering handle_sony_cd_attention\n");
#endif
- if (is_attention())
- {
- if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
- {
- printk("cdu31a: Too many consecutive attentions: %d\n",
- num_consecutive_attentions);
- num_consecutive_attentions = 0;
+ if (is_attention()) {
+ if (num_consecutive_attentions >
+ CDU31A_MAX_CONSECUTIVE_ATTENTIONS) {
+ printk
+ ("cdu31a: Too many consecutive attentions: %d\n",
+ num_consecutive_attentions);
+ num_consecutive_attentions = 0;
#if DEBUG
- printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+ printk("Leaving handle_sony_cd_attention at %d\n",
+ __LINE__);
#endif
- return(0);
- }
-
- clear_attention();
- atten_code = read_result_register();
-
- switch (atten_code)
- {
- /* Someone changed the CD. Mark it as changed */
- case SONY_MECH_LOADED_ATTN:
- disk_changed = 1;
- sony_toc_read = 0;
- sony_audio_status = CDROM_AUDIO_NO_STATUS;
- sony_blocks_left = 0;
- break;
-
- case SONY_SPIN_DOWN_COMPLETE_ATTN:
- /* Mark the disk as spun down. */
- sony_spun_up = 0;
- break;
-
- case SONY_AUDIO_PLAY_DONE_ATTN:
- sony_audio_status = CDROM_AUDIO_COMPLETED;
- read_subcode();
- break;
-
- case SONY_EJECT_PUSHED_ATTN:
- if (is_auto_eject)
- {
- sony_audio_status = CDROM_AUDIO_INVALID;
- }
- break;
-
- case SONY_LEAD_IN_ERR_ATTN:
- case SONY_LEAD_OUT_ERR_ATTN:
- case SONY_DATA_TRACK_ERR_ATTN:
- case SONY_AUDIO_PLAYBACK_ERR_ATTN:
- sony_audio_status = CDROM_AUDIO_ERROR;
- break;
- }
-
- num_consecutive_attentions++;
+ return (0);
+ }
+
+ clear_attention();
+ atten_code = read_result_register();
+
+ switch (atten_code) {
+ /* Someone changed the CD. Mark it as changed */
+ case SONY_MECH_LOADED_ATTN:
+ disk_changed = 1;
+ sony_toc_read = 0;
+ sony_audio_status = CDROM_AUDIO_NO_STATUS;
+ sony_blocks_left = 0;
+ break;
+
+ case SONY_SPIN_DOWN_COMPLETE_ATTN:
+ /* Mark the disk as spun down. */
+ sony_spun_up = 0;
+ break;
+
+ case SONY_AUDIO_PLAY_DONE_ATTN:
+ sony_audio_status = CDROM_AUDIO_COMPLETED;
+ read_subcode();
+ break;
+
+ case SONY_EJECT_PUSHED_ATTN:
+ if (is_auto_eject) {
+ sony_audio_status = CDROM_AUDIO_INVALID;
+ }
+ break;
+
+ case SONY_LEAD_IN_ERR_ATTN:
+ case SONY_LEAD_OUT_ERR_ATTN:
+ case SONY_DATA_TRACK_ERR_ATTN:
+ case SONY_AUDIO_PLAYBACK_ERR_ATTN:
+ sony_audio_status = CDROM_AUDIO_ERROR;
+ break;
+ }
+
+ num_consecutive_attentions++;
#if DEBUG
- printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+ printk("Leaving handle_sony_cd_attention at %d\n",
+ __LINE__);
#endif
- return(1);
- }
- else if (abort_read_started)
- {
- while (is_result_reg_not_empty())
- {
- val = read_result_register();
- }
- clear_data_ready();
- clear_result_ready();
- /* Clear out the data */
- while (is_data_requested())
- {
- val = read_data_register();
- }
- abort_read_started = 0;
+ return (1);
+ } else if (abort_read_started) {
+ while (is_result_reg_not_empty()) {
+ val = read_result_register();
+ }
+ clear_data_ready();
+ clear_result_ready();
+ /* Clear out the data */
+ while (is_data_requested()) {
+ val = read_data_register();
+ }
+ abort_read_started = 0;
#if DEBUG
- printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+ printk("Leaving handle_sony_cd_attention at %d\n",
+ __LINE__);
#endif
- return(1);
- }
+ return (1);
+ }
- num_consecutive_attentions = 0;
+ num_consecutive_attentions = 0;
#if 0*DEBUG
- printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
+ printk("Leaving handle_sony_cd_attention at %d\n", __LINE__);
#endif
- return(0);
+ return (0);
}
/* Convert from an integer 0-99 to BCD */
-static inline unsigned int
-int_to_bcd(unsigned int val)
+static inline unsigned int int_to_bcd(unsigned int val)
{
- int retval;
+ int retval;
- retval = (val / 10) << 4;
- retval = retval | val % 10;
- return(retval);
+ retval = (val / 10) << 4;
+ retval = retval | val % 10;
+ return (retval);
}
/* Convert from BCD to an integer from 0-99 */
-static unsigned int
-bcd_to_int(unsigned int bcd)
+static unsigned int bcd_to_int(unsigned int bcd)
{
- return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
+ return ((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
}
* Convert a logical sector value (like the OS would want to use for
* a block device) to an MSF format.
*/
-static void
-log_to_msf(unsigned int log, unsigned char *msf)
+static void log_to_msf(unsigned int log, unsigned char *msf)
{
- log = log + LOG_START_OFFSET;
- msf[0] = int_to_bcd(log / 4500);
- log = log % 4500;
- msf[1] = int_to_bcd(log / 75);
- msf[2] = int_to_bcd(log % 75);
+ log = log + LOG_START_OFFSET;
+ msf[0] = int_to_bcd(log / 4500);
+ log = log % 4500;
+ msf[1] = int_to_bcd(log / 75);
+ msf[2] = int_to_bcd(log % 75);
}
/*
* Convert an MSF format to a logical sector.
*/
-static unsigned int
-msf_to_log(unsigned char *msf)
+static unsigned int msf_to_log(unsigned char *msf)
{
- unsigned int log;
+ unsigned int log;
- log = msf[2];
- log += msf[1] * 75;
- log += msf[0] * 4500;
- log = log - LOG_START_OFFSET;
+ log = msf[2];
+ log += msf[1] * 75;
+ log += msf[0] * 4500;
+ log = log - LOG_START_OFFSET;
- return log;
+ return log;
}
* Take in integer size value and put it into a buffer like
* the drive would want to see a number-of-sector value.
*/
-static void
-size_to_buf(unsigned int size,
- unsigned char *buf)
+static void size_to_buf(unsigned int size, unsigned char *buf)
{
- buf[0] = size / 65536;
- size = size % 65536;
- buf[1] = size / 256;
- buf[2] = size % 256;
+ buf[0] = size / 65536;
+ size = size % 65536;
+ buf[1] = size / 256;
+ buf[2] = size % 256;
}
/* Starts a read operation. Returns 0 on success and 1 on failure.
operation if the requested sector is not the next one from the
drive. */
static int
-start_request(unsigned int sector,
- unsigned int nsect,
- int read_nsect_only)
+start_request(unsigned int sector, unsigned int nsect, int read_nsect_only)
{
- unsigned char params[6];
- unsigned int read_size;
- unsigned int retry_count;
+ unsigned char params[6];
+ unsigned int read_size;
+ unsigned int retry_count;
#if DEBUG
- printk("Entering start_request\n");
+ printk("Entering start_request\n");
#endif
- log_to_msf(sector, params);
- /* If requested, read exactly what was asked. */
- if (read_nsect_only)
- {
- read_size = nsect;
- }
- /*
- * If the full read-ahead would go beyond the end of the media, trim
- * it back to read just till the end of the media.
- */
- else if ((sector + nsect) >= sony_toc.lead_out_start_lba)
- {
- read_size = sony_toc.lead_out_start_lba - sector;
- }
- /* Read the full readahead amount. */
- else
- {
- read_size = CDU31A_READAHEAD / 4;
- }
- size_to_buf(read_size, ¶ms[3]);
-
- /*
- * Clear any outstanding attentions and wait for the drive to
- * complete any pending operations.
- */
- while (handle_sony_cd_attention())
- ;
-
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && (is_busy()))
- {
- sony_sleep();
-
- while (handle_sony_cd_attention())
- ;
- }
-
- if (is_busy())
- {
- printk("CDU31A: Timeout while waiting to issue command\n");
+ log_to_msf(sector, params);
+ /* If requested, read exactly what was asked. */
+ if (read_nsect_only) {
+ read_size = nsect;
+ }
+ /*
+ * If the full read-ahead would go beyond the end of the media, trim
+ * it back to read just till the end of the media.
+ */
+ else if ((sector + nsect) >= sony_toc.lead_out_start_lba) {
+ read_size = sony_toc.lead_out_start_lba - sector;
+ }
+ /* Read the full readahead amount. */
+ else {
+ read_size = CDU31A_READAHEAD / 4;
+ }
+ size_to_buf(read_size, ¶ms[3]);
+
+ /*
+ * Clear any outstanding attentions and wait for the drive to
+ * complete any pending operations.
+ */
+ while (handle_sony_cd_attention());
+
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ while (time_before(jiffies, retry_count) && (is_busy())) {
+ sony_sleep();
+
+ while (handle_sony_cd_attention());
+ }
+
+ if (is_busy()) {
+ printk("CDU31A: Timeout while waiting to issue command\n");
#if DEBUG
- printk("Leaving start_request at %d\n", __LINE__);
+ printk("Leaving start_request at %d\n", __LINE__);
#endif
- return(1);
- }
- else
- {
- /* Issue the command */
- clear_result_ready();
- clear_param_reg();
-
- write_params(params, 6);
- write_cmd(SONY_READ_BLKERR_STAT_CMD);
-
- sony_blocks_left = read_size * 4;
- sony_next_block = sector * 4;
- readahead_dataleft = 0;
- readahead_bad = 0;
+ return (1);
+ } else {
+ /* Issue the command */
+ clear_result_ready();
+ clear_param_reg();
+
+ write_params(params, 6);
+ write_cmd(SONY_READ_BLKERR_STAT_CMD);
+
+ sony_blocks_left = read_size * 4;
+ sony_next_block = sector * 4;
+ readahead_dataleft = 0;
+ readahead_bad = 0;
#if DEBUG
- printk("Leaving start_request at %d\n", __LINE__);
+ printk("Leaving start_request at %d\n", __LINE__);
#endif
- return(0);
- }
+ return (0);
+ }
#if DEBUG
- printk("Leaving start_request at %d\n", __LINE__);
+ printk("Leaving start_request at %d\n", __LINE__);
#endif
}
/* Abort a pending read operation. Clear all the drive status and
readahead variables. */
-static void
-abort_read(void)
-{
- unsigned char result_reg[2];
- int result_size;
- volatile int val;
-
-
- do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
- if ((result_reg[0] & 0xf0) == 0x20)
- {
- printk("CDU31A: Error aborting read, %s error\n",
- translate_error(
- result_reg[1]));
- }
-
- while (is_result_reg_not_empty())
- {
- val = read_result_register();
- }
- clear_data_ready();
- clear_result_ready();
- /* Clear out the data */
- while (is_data_requested())
- {
- val = read_data_register();
- }
-
- sony_blocks_left = 0;
- readahead_dataleft = 0;
- readahead_bad = 0;
+static void abort_read(void)
+{
+ unsigned char result_reg[2];
+ int result_size;
+ volatile int val;
+
+
+ do_sony_cd_cmd(SONY_ABORT_CMD, NULL, 0, result_reg, &result_size);
+ if ((result_reg[0] & 0xf0) == 0x20) {
+ printk("CDU31A: Error aborting read, %s error\n",
+ translate_error(result_reg[1]));
+ }
+
+ while (is_result_reg_not_empty()) {
+ val = read_result_register();
+ }
+ clear_data_ready();
+ clear_result_ready();
+ /* Clear out the data */
+ while (is_data_requested()) {
+ val = read_data_register();
+ }
+
+ sony_blocks_left = 0;
+ readahead_dataleft = 0;
+ readahead_bad = 0;
}
/* Called when the timer times out. This will abort the
pending read operation. */
-static void
-handle_abort_timeout(unsigned long data)
+static void handle_abort_timeout(unsigned long data)
{
- unsigned long flags;
+ unsigned long flags;
#if DEBUG
- printk("Entering handle_abort_timeout\n");
+ printk("Entering handle_abort_timeout\n");
#endif
- save_flags(flags);
- cli();
- /* If it is in use, ignore it. */
- if (!sony_inuse)
- {
- /* We can't use abort_read(), because it will sleep
- or schedule in the timer interrupt. Just start
- the operation, finish it on the next access to
- the drive. */
- clear_result_ready();
- clear_param_reg();
- write_cmd(SONY_ABORT_CMD);
-
- sony_blocks_left = 0;
- readahead_dataleft = 0;
- readahead_bad = 0;
- abort_read_started = 1;
- }
- restore_flags(flags);
+ save_flags(flags);
+ cli();
+ /* If it is in use, ignore it. */
+ if (!sony_inuse) {
+ /* We can't use abort_read(), because it will sleep
+ or schedule in the timer interrupt. Just start
+ the operation, finish it on the next access to
+ the drive. */
+ clear_result_ready();
+ clear_param_reg();
+ write_cmd(SONY_ABORT_CMD);
+
+ sony_blocks_left = 0;
+ readahead_dataleft = 0;
+ readahead_bad = 0;
+ abort_read_started = 1;
+ }
+ restore_flags(flags);
#if DEBUG
- printk("Leaving handle_abort_timeout\n");
+ printk("Leaving handle_abort_timeout\n");
#endif
}
/* Actually get data and status from the drive. */
static void
-input_data(char *buffer,
- unsigned int bytesleft,
- unsigned int nblocks,
- unsigned int offset,
- unsigned int skip)
+input_data(char *buffer,
+ unsigned int bytesleft,
+ unsigned int nblocks, unsigned int offset, unsigned int skip)
{
- int i;
- volatile unsigned char val;
+ int i;
+ volatile unsigned char val;
#if DEBUG
- printk("Entering input_data\n");
+ printk("Entering input_data\n");
#endif
- /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
- the disk. The real data is after that. */
- if (sony_xa_mode)
- {
- for(i=0; i<CD_XA_HEAD; i++)
- {
- val = read_data_register();
- }
- }
-
- clear_data_ready();
-
- if (bytesleft == 2048) /* 2048 byte direct buffer transfer */
- {
- insb(sony_cd_read_reg, buffer, 2048);
- readahead_dataleft = 0;
- }
- else
- {
- /* If the input read did not align with the beginning of the block,
- skip the necessary bytes. */
- if (skip != 0)
- {
- insb(sony_cd_read_reg, readahead_buffer, skip);
- }
-
- /* Get the data into the buffer. */
- insb(sony_cd_read_reg, &buffer[offset], bytesleft);
-
- /* Get the rest of the data into the readahead buffer at the
- proper location. */
- readahead_dataleft = (2048 - skip) - bytesleft;
- insb(sony_cd_read_reg,
- readahead_buffer + bytesleft,
- readahead_dataleft);
- }
- sony_blocks_left -= nblocks;
- sony_next_block += nblocks;
-
- /* If an XA disk, we have to clear out the rest of the unused
- error correction data. */
- if (sony_xa_mode)
- {
- for(i=0; i<CD_XA_TAIL; i++)
- {
- val = read_data_register();
- }
- }
+ /* If an XA disk on a CDU31A, skip the first 12 bytes of data from
+ the disk. The real data is after that. */
+ if (sony_xa_mode) {
+ for (i = 0; i < CD_XA_HEAD; i++) {
+ val = read_data_register();
+ }
+ }
+
+ clear_data_ready();
+
+ if (bytesleft == 2048) { /* 2048 byte direct buffer transfer */
+ insb(sony_cd_read_reg, buffer, 2048);
+ readahead_dataleft = 0;
+ } else {
+ /* If the input read did not align with the beginning of the block,
+ skip the necessary bytes. */
+ if (skip != 0) {
+ insb(sony_cd_read_reg, readahead_buffer, skip);
+ }
+
+ /* Get the data into the buffer. */
+ insb(sony_cd_read_reg, &buffer[offset], bytesleft);
+
+ /* Get the rest of the data into the readahead buffer at the
+ proper location. */
+ readahead_dataleft = (2048 - skip) - bytesleft;
+ insb(sony_cd_read_reg,
+ readahead_buffer + bytesleft, readahead_dataleft);
+ }
+ sony_blocks_left -= nblocks;
+ sony_next_block += nblocks;
+
+ /* If an XA disk, we have to clear out the rest of the unused
+ error correction data. */
+ if (sony_xa_mode) {
+ for (i = 0; i < CD_XA_TAIL; i++) {
+ val = read_data_register();
+ }
+ }
#if DEBUG
- printk("Leaving input_data at %d\n", __LINE__);
+ printk("Leaving input_data at %d\n", __LINE__);
#endif
}
/* read data from the drive. Note the nsect must be <= 4. */
static void
-read_data_block(char *buffer,
- unsigned int block,
- unsigned int nblocks,
- unsigned char res_reg[],
- int *res_size)
+read_data_block(char *buffer,
+ unsigned int block,
+ unsigned int nblocks,
+ unsigned char res_reg[], int *res_size)
{
- unsigned int retry_count;
- unsigned int bytesleft;
- unsigned int offset;
- unsigned int skip;
+ unsigned int retry_count;
+ unsigned int bytesleft;
+ unsigned int offset;
+ unsigned int skip;
#if DEBUG
- printk("Entering read_data_block\n");
+ printk("Entering read_data_block\n");
#endif
- res_reg[0] = 0;
- res_reg[1] = 0;
- *res_size = 0;
- bytesleft = nblocks * 512;
- offset = 0;
-
- /* If the data in the read-ahead does not match the block offset,
- then fix things up. */
- if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048))
- {
- sony_next_block += block % 4;
- sony_blocks_left -= block % 4;
- skip = (block % 4) * 512;
- }
- else
- {
- skip = 0;
- }
-
- /* We have readahead data in the buffer, get that first before we
- decide if a read is necessary. */
- if (readahead_dataleft != 0)
- {
- if (bytesleft > readahead_dataleft)
- {
- /* The readahead will not fill the requested buffer, but
- get the data out of the readahead into the buffer. */
- memcpy(buffer,
- readahead_buffer + (2048 - readahead_dataleft),
- readahead_dataleft);
- readahead_dataleft = 0;
- bytesleft -= readahead_dataleft;
- offset += readahead_dataleft;
- }
- else
- {
- /* The readahead will fill the whole buffer, get the data
- and return. */
- memcpy(buffer,
- readahead_buffer + (2048 - readahead_dataleft),
- bytesleft);
- readahead_dataleft -= bytesleft;
- bytesleft = 0;
- sony_blocks_left -= nblocks;
- sony_next_block += nblocks;
-
- /* If the data in the readahead is bad, return an error so the
- driver will abort the buffer. */
- if (readahead_bad)
- {
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
-
- if (readahead_dataleft == 0)
- {
- readahead_bad = 0;
- }
-
- /* Final transfer is done for read command, get final result. */
- if (sony_blocks_left == 0)
- {
- get_result(res_reg, res_size);
- }
+ res_reg[0] = 0;
+ res_reg[1] = 0;
+ *res_size = 0;
+ bytesleft = nblocks * 512;
+ offset = 0;
+
+ /* If the data in the read-ahead does not match the block offset,
+ then fix things up. */
+ if (((block % 4) * 512) != ((2048 - readahead_dataleft) % 2048)) {
+ sony_next_block += block % 4;
+ sony_blocks_left -= block % 4;
+ skip = (block % 4) * 512;
+ } else {
+ skip = 0;
+ }
+
+ /* We have readahead data in the buffer, get that first before we
+ decide if a read is necessary. */
+ if (readahead_dataleft != 0) {
+ if (bytesleft > readahead_dataleft) {
+ /* The readahead will not fill the requested buffer, but
+ get the data out of the readahead into the buffer. */
+ memcpy(buffer,
+ readahead_buffer + (2048 -
+ readahead_dataleft),
+ readahead_dataleft);
+ readahead_dataleft = 0;
+ bytesleft -= readahead_dataleft;
+ offset += readahead_dataleft;
+ } else {
+ /* The readahead will fill the whole buffer, get the data
+ and return. */
+ memcpy(buffer,
+ readahead_buffer + (2048 -
+ readahead_dataleft),
+ bytesleft);
+ readahead_dataleft -= bytesleft;
+ bytesleft = 0;
+ sony_blocks_left -= nblocks;
+ sony_next_block += nblocks;
+
+ /* If the data in the readahead is bad, return an error so the
+ driver will abort the buffer. */
+ if (readahead_bad) {
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+
+ if (readahead_dataleft == 0) {
+ readahead_bad = 0;
+ }
+
+ /* Final transfer is done for read command, get final result. */
+ if (sony_blocks_left == 0) {
+ get_result(res_reg, res_size);
+ }
#if DEBUG
- printk("Leaving read_data_block at %d\n", __LINE__);
+ printk("Leaving read_data_block at %d\n",
+ __LINE__);
#endif
- return;
- }
- }
-
- /* Wait for the drive to tell us we have something */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && !(is_data_ready()))
- {
- while (handle_sony_cd_attention())
- ;
-
- sony_sleep();
- }
- if (!(is_data_ready()))
- {
- if (is_result_ready())
- {
- get_result(res_reg, res_size);
- if ((res_reg[0] & 0xf0) != 0x20)
- {
- printk("CDU31A: Got result that should have been error: %d\n",
- res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- abort_read();
- }
- else
- {
+ return;
+ }
+ }
+
+ /* Wait for the drive to tell us we have something */
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ while (time_before(jiffies, retry_count) && !(is_data_ready())) {
+ while (handle_sony_cd_attention());
+
+ sony_sleep();
+ }
+ if (!(is_data_ready())) {
+ if (is_result_ready()) {
+ get_result(res_reg, res_size);
+ if ((res_reg[0] & 0xf0) != 0x20) {
+ printk
+ ("CDU31A: Got result that should have been error: %d\n",
+ res_reg[0]);
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+ abort_read();
+ } else {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n", __LINE__);
#endif
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- }
- }
- else
- {
- input_data(buffer, bytesleft, nblocks, offset, skip);
-
- /* Wait for the status from the drive. */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && !(is_result_ready()))
- {
- while (handle_sony_cd_attention())
- ;
-
- sony_sleep();
- }
-
- if (!is_result_ready())
- {
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_TIMEOUT_OP_ERR;
+ *res_size = 2;
+ abort_read();
+ }
+ } else {
+ input_data(buffer, bytesleft, nblocks, offset, skip);
+
+ /* Wait for the status from the drive. */
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ while (time_before(jiffies, retry_count)
+ && !(is_result_ready())) {
+ while (handle_sony_cd_attention());
+
+ sony_sleep();
+ }
+
+ if (!is_result_ready()) {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n", __LINE__);
#endif
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- }
- else
- {
- get_result(res_reg, res_size);
-
- /* If we got a buffer status, handle that. */
- if ((res_reg[0] & 0xf0) == 0x50)
- {
-
- if ( (res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT))
- {
- /* The data was successful, but if data was read from
- the readahead and it was bad, set the whole
- buffer as bad. */
- if (readahead_bad)
- {
- readahead_bad = 0;
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- }
- else
- {
- printk("CDU31A: Data block error: 0x%x\n", res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
-
- /* Data is in the readahead buffer but an error was returned.
- Make sure future requests don't use the data. */
- if (bytesleft != 2048)
- {
- readahead_bad = 1;
- }
- }
-
- /* Final transfer is done for read command, get final result. */
- if (sony_blocks_left == 0)
- {
- get_result(res_reg, res_size);
- }
- }
- else if ((res_reg[0] & 0xf0) != 0x20)
- {
- /* The drive gave me bad status, I don't know what to do.
- Reset the driver and return an error. */
- printk("CDU31A: Invalid block status: 0x%x\n", res_reg[0]);
- restart_on_error();
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- }
- }
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_TIMEOUT_OP_ERR;
+ *res_size = 2;
+ abort_read();
+ } else {
+ get_result(res_reg, res_size);
+
+ /* If we got a buffer status, handle that. */
+ if ((res_reg[0] & 0xf0) == 0x50) {
+
+ if ((res_reg[0] ==
+ SONY_NO_CIRC_ERR_BLK_STAT)
+ || (res_reg[0] ==
+ SONY_NO_LECC_ERR_BLK_STAT)
+ || (res_reg[0] ==
+ SONY_RECOV_LECC_ERR_BLK_STAT)) {
+ /* The data was successful, but if data was read from
+ the readahead and it was bad, set the whole
+ buffer as bad. */
+ if (readahead_bad) {
+ readahead_bad = 0;
+ res_reg[0] = 0x20;
+ res_reg[1] =
+ SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+ } else {
+ printk
+ ("CDU31A: Data block error: 0x%x\n",
+ res_reg[0]);
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+
+ /* Data is in the readahead buffer but an error was returned.
+ Make sure future requests don't use the data. */
+ if (bytesleft != 2048) {
+ readahead_bad = 1;
+ }
+ }
+
+ /* Final transfer is done for read command, get final result. */
+ if (sony_blocks_left == 0) {
+ get_result(res_reg, res_size);
+ }
+ } else if ((res_reg[0] & 0xf0) != 0x20) {
+ /* The drive gave me bad status, I don't know what to do.
+ Reset the driver and return an error. */
+ printk
+ ("CDU31A: Invalid block status: 0x%x\n",
+ res_reg[0]);
+ restart_on_error();
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+ }
+ }
#if DEBUG
- printk("Leaving read_data_block at %d\n", __LINE__);
+ printk("Leaving read_data_block at %d\n", __LINE__);
#endif
}
* uses 1024 byte blocks and the drive uses 2048 byte blocks. Since most
* data access on a CD is done sequentially, this saves a lot of operations.
*/
-static void
-do_cdu31a_request(request_queue_t * q)
+static void do_cdu31a_request(request_queue_t * q)
{
- int block;
- int nblock;
- unsigned char res_reg[12];
- unsigned int res_size;
- int num_retries;
- unsigned long flags;
+ int block;
+ int nblock;
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ int num_retries;
+ unsigned long flags;
#if DEBUG
- printk("Entering do_cdu31a_request\n");
+ printk("Entering do_cdu31a_request\n");
#endif
- /*
- * Make sure no one else is using the driver; wait for them
- * to finish if it is so.
- */
- save_flags(flags);
- cli();
- while (sony_inuse)
- {
- interruptible_sleep_on(&sony_wait);
- if (signal_pending(current))
- {
- restore_flags(flags);
- if (!QUEUE_EMPTY && CURRENT->rq_status != RQ_INACTIVE)
- {
- end_request(0);
- }
- restore_flags(flags);
+ /*
+ * Make sure no one else is using the driver; wait for them
+ * to finish if it is so.
+ */
+ save_flags(flags);
+ cli();
+ while (sony_inuse) {
+ interruptible_sleep_on(&sony_wait);
+ if (signal_pending(current)) {
+ restore_flags(flags);
+ if (!QUEUE_EMPTY
+ && CURRENT->rq_status != RQ_INACTIVE) {
+ end_request(0);
+ }
+ restore_flags(flags);
#if DEBUG
- printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+ printk("Leaving do_cdu31a_request at %d\n",
+ __LINE__);
#endif
- return;
- }
- }
- sony_inuse = 1;
- has_cd_task = current;
-
- /* Get drive status before doing anything. */
- while (handle_sony_cd_attention())
- ;
-
- /* Make sure we have a valid TOC. */
- sony_get_toc();
-
- spin_unlock_irq(&io_request_lock);
-
- /* Make sure the timer is cancelled. */
- del_timer(&cdu31a_abort_timer);
-
- while (1)
- {
-cdu31a_request_startover:
- /*
- * The beginning here is stolen from the hard disk driver. I hope
- * it's right.
- */
- if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
- {
- goto end_do_cdu31a_request;
- }
-
- if (!sony_spun_up)
- {
- scd_spinup();
- }
-
- /* I don't use INIT_REQUEST because it calls return, which would
- return without unlocking the device. It shouldn't matter,
- but just to be safe... */
- if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
- {
- panic(DEVICE_NAME ": request list destroyed");
- }
- if (CURRENT->bh)
- {
- if (!buffer_locked(CURRENT->bh))
- {
- panic(DEVICE_NAME ": block not locked");
- }
- }
-
- block = CURRENT->sector;
- nblock = CURRENT->nr_sectors;
-
- if (!sony_toc_read)
- {
- printk("CDU31A: TOC not read\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
-
- switch(CURRENT->cmd)
- {
- case READ:
- /*
- * If the block address is invalid or the request goes beyond the end of
- * the media, return an error.
- */
+ return;
+ }
+ }
+ sony_inuse = 1;
+ has_cd_task = current;
+
+ /* Get drive status before doing anything. */
+ while (handle_sony_cd_attention());
+
+ /* Make sure we have a valid TOC. */
+ sony_get_toc();
+
+ spin_unlock_irq(&io_request_lock);
+
+ /* Make sure the timer is cancelled. */
+ del_timer(&cdu31a_abort_timer);
+
+ while (1) {
+ cdu31a_request_startover:
+ /*
+ * The beginning here is stolen from the hard disk driver. I hope
+ * it's right.
+ */
+ if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE) {
+ goto end_do_cdu31a_request;
+ }
+
+ if (!sony_spun_up) {
+ scd_spinup();
+ }
+
+ /* I don't use INIT_REQUEST because it calls return, which would
+ return without unlocking the device. It shouldn't matter,
+ but just to be safe... */
+ if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) {
+ panic(DEVICE_NAME ": request list destroyed");
+ }
+ if (CURRENT->bh) {
+ if (!buffer_locked(CURRENT->bh)) {
+ panic(DEVICE_NAME ": block not locked");
+ }
+ }
+
+ block = CURRENT->sector;
+ nblock = CURRENT->nr_sectors;
+
+ if (!sony_toc_read) {
+ printk("CDU31A: TOC not read\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+
+ switch (CURRENT->cmd) {
+ case READ:
+ /*
+ * If the block address is invalid or the request goes beyond the end of
+ * the media, return an error.
+ */
#if 0
- if ((block / 4) < sony_toc.start_track_lba)
- {
- printk("CDU31A: Request before beginning of media\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
+ if ((block / 4) < sony_toc.start_track_lba) {
+ printk
+ ("CDU31A: Request before beginning of media\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
#endif
- if ((block / 4) >= sony_toc.lead_out_start_lba)
- {
- printk("CDU31A: Request past end of media\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
- if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba)
- {
- printk("CDU31A: Request past end of media\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
-
- num_retries = 0;
-
-try_read_again:
- while (handle_sony_cd_attention())
- ;
-
- if (!sony_toc_read)
- {
- printk("CDU31A: TOC not read\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
-
- /* If no data is left to be read from the drive, start the
- next request. */
- if (sony_blocks_left == 0)
- {
- if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
- {
- end_request(0);
- goto cdu31a_request_startover;
- }
- }
- /* If the requested block is not the next one waiting in
- the driver, abort the current operation and start a
- new one. */
- else if (block != sony_next_block)
- {
+ if ((block / 4) >= sony_toc.lead_out_start_lba) {
+ printk
+ ("CDU31A: Request past end of media\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+ if (((block + nblock) / 4) >=
+ sony_toc.lead_out_start_lba) {
+ printk
+ ("CDU31A: Request past end of media\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+
+ num_retries = 0;
+
+ try_read_again:
+ while (handle_sony_cd_attention());
+
+ if (!sony_toc_read) {
+ printk("CDU31A: TOC not read\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+
+ /* If no data is left to be read from the drive, start the
+ next request. */
+ if (sony_blocks_left == 0) {
+ if (start_request
+ (block / 4, CDU31A_READAHEAD / 4, 0)) {
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+ }
+ /* If the requested block is not the next one waiting in
+ the driver, abort the current operation and start a
+ new one. */
+ else if (block != sony_next_block) {
#if DEBUG
- printk("CDU31A Warning: Read for block %d, expected %d\n",
- block,
- sony_next_block);
+ printk
+ ("CDU31A Warning: Read for block %d, expected %d\n",
+ block, sony_next_block);
#endif
- abort_read();
- if (!sony_toc_read)
- {
- printk("CDU31A: TOC not read\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
- if (start_request(block / 4, CDU31A_READAHEAD / 4, 0))
- {
- printk("CDU31a: start request failed\n");
- end_request(0);
- goto cdu31a_request_startover;
- }
- }
-
- read_data_block(CURRENT->buffer, block, nblock, res_reg, &res_size);
- if (res_reg[0] == 0x20)
- {
- if (num_retries > MAX_CDU31A_RETRIES)
- {
- end_request(0);
- goto cdu31a_request_startover;
- }
-
- num_retries++;
- if (res_reg[1] == SONY_NOT_SPIN_ERR)
- {
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
- }
- else
- {
- printk("CDU31A: %s error for block %d, nblock %d\n", translate_error(res_reg[1]), block, nblock);
- }
- goto try_read_again;
- }
- else
- {
- end_request(1);
- }
- break;
-
- case WRITE:
- end_request(0);
- break;
-
- default:
- panic("CDU31A: Unknown cmd");
- }
- }
-
-end_do_cdu31a_request:
- spin_lock_irq(&io_request_lock);
+ abort_read();
+ if (!sony_toc_read) {
+ printk("CDU31A: TOC not read\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+ if (start_request
+ (block / 4, CDU31A_READAHEAD / 4, 0)) {
+ printk
+ ("CDU31a: start request failed\n");
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+ }
+
+ read_data_block(CURRENT->buffer, block, nblock,
+ res_reg, &res_size);
+ if (res_reg[0] == 0x20) {
+ if (num_retries > MAX_CDU31A_RETRIES) {
+ end_request(0);
+ goto cdu31a_request_startover;
+ }
+
+ num_retries++;
+ if (res_reg[1] == SONY_NOT_SPIN_ERR) {
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD,
+ NULL, 0, res_reg,
+ &res_size);
+ } else {
+ printk
+ ("CDU31A: %s error for block %d, nblock %d\n",
+ translate_error(res_reg[1]),
+ block, nblock);
+ }
+ goto try_read_again;
+ } else {
+ end_request(1);
+ }
+ break;
+
+ case WRITE:
+ end_request(0);
+ break;
+
+ default:
+ panic("CDU31A: Unknown cmd");
+ }
+ }
+
+ end_do_cdu31a_request:
+ spin_lock_irq(&io_request_lock);
#if 0
- /* After finished, cancel any pending operations. */
- abort_read();
+ /* After finished, cancel any pending operations. */
+ abort_read();
#else
- /* Start a timer to time out after a while to disable
- the read. */
- cdu31a_abort_timer.expires = jiffies + 2*HZ; /* Wait 2 seconds */
- add_timer(&cdu31a_abort_timer);
+ /* Start a timer to time out after a while to disable
+ the read. */
+ cdu31a_abort_timer.expires = jiffies + 2 * HZ; /* Wait 2 seconds */
+ add_timer(&cdu31a_abort_timer);
#endif
- has_cd_task = NULL;
- sony_inuse = 0;
- wake_up_interruptible(&sony_wait);
- restore_flags(flags);
+ has_cd_task = NULL;
+ sony_inuse = 0;
+ wake_up_interruptible(&sony_wait);
+ restore_flags(flags);
#if DEBUG
- printk("Leaving do_cdu31a_request at %d\n", __LINE__);
+ printk("Leaving do_cdu31a_request at %d\n", __LINE__);
#endif
}
* Read the table of contents from the drive and set up TOC if
* successful.
*/
-static void
-sony_get_toc(void)
+static void sony_get_toc(void)
{
- unsigned char res_reg[2];
- unsigned int res_size;
- unsigned char parms[1];
- int session;
- int num_spin_ups;
- int totaltracks = 0;
- int mint = 99;
- int maxt = 0;
+ unsigned char res_reg[2];
+ unsigned int res_size;
+ unsigned char parms[1];
+ int session;
+ int num_spin_ups;
+ int totaltracks = 0;
+ int mint = 99;
+ int maxt = 0;
#if DEBUG
- printk("Entering sony_get_toc\n");
+ printk("Entering sony_get_toc\n");
#endif
- num_spin_ups = 0;
- if (!sony_toc_read)
- {
-respinup_on_gettoc:
- /* Ignore the result, since it might error if spinning already. */
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
- do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
- /* The drive sometimes returns error 0. I don't know why, but ignore
- it. It seems to mean the drive has already done the operation. */
- if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
- {
- /* If the drive is already playing, it's ok. */
- if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
- {
- goto gettoc_drive_spinning;
- }
-
- /* If the drive says it is not spun up (even though we just did it!)
- then retry the operation at least a few times. */
- if ( (res_reg[1] == SONY_NOT_SPIN_ERR)
- && (num_spin_ups < MAX_CDU31A_RETRIES))
- {
- num_spin_ups++;
- goto respinup_on_gettoc;
- }
-
- printk("cdu31a: Error reading TOC: %x %s\n",
- res_reg[0], translate_error(res_reg[1]));
- return;
- }
-
-gettoc_drive_spinning:
-
- /* The idea here is we keep asking for sessions until the command
- fails. Then we know what the last valid session on the disk is.
- No need to check session 0, since session 0 is the same as session
- 1; the command returns different information if you give it 0.
- */
+ num_spin_ups = 0;
+ if (!sony_toc_read) {
+ respinup_on_gettoc:
+ /* Ignore the result, since it might error if spinning already. */
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ /* The drive sometimes returns error 0. I don't know why, but ignore
+ it. It seems to mean the drive has already done the operation. */
+ if ((res_size < 2)
+ || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+ /* If the drive is already playing, it's ok. */
+ if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
+ || (res_reg[1] == 0)) {
+ goto gettoc_drive_spinning;
+ }
+
+ /* If the drive says it is not spun up (even though we just did it!)
+ then retry the operation at least a few times. */
+ if ((res_reg[1] == SONY_NOT_SPIN_ERR)
+ && (num_spin_ups < MAX_CDU31A_RETRIES)) {
+ num_spin_ups++;
+ goto respinup_on_gettoc;
+ }
+
+ printk("cdu31a: Error reading TOC: %x %s\n",
+ res_reg[0], translate_error(res_reg[1]));
+ return;
+ }
+
+ gettoc_drive_spinning:
+
+ /* The idea here is we keep asking for sessions until the command
+ fails. Then we know what the last valid session on the disk is.
+ No need to check session 0, since session 0 is the same as session
+ 1; the command returns different information if you give it 0.
+ */
#if DEBUG
- memset(&sony_toc, 0x0e, sizeof(sony_toc));
- memset(&single_toc, 0x0f, sizeof(single_toc));
+ memset(&sony_toc, 0x0e, sizeof(sony_toc));
+ memset(&single_toc, 0x0f, sizeof(single_toc));
#endif
- session = 1;
- while (1)
- {
+ session = 1;
+ while (1) {
/* This seems to slow things down enough to make it work. This
* appears to be a problem in do_sony_cd_cmd. This printk seems
* to address the symptoms... -Erik */
#if 1
- printk("cdu31a: Trying session %d\n", session);
+ printk("cdu31a: Trying session %d\n", session);
#endif
- parms[0] = session;
- do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
- parms,
- 1,
- res_reg,
- &res_size);
+ parms[0] = session;
+ do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
+ parms, 1, res_reg, &res_size);
#if DEBUG
- printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
+ printk("%2.2x %2.2x\n", res_reg[0], res_reg[1]);
#endif
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- /* An error reading the TOC, this must be past the last session. */
- if (session == 1)
- printk("Yikes! Couldn't read any sessions!");
- break;
- }
+ if ((res_size < 2)
+ || ((res_reg[0] & 0xf0) == 0x20)) {
+ /* An error reading the TOC, this must be past the last session. */
+ if (session == 1)
+ printk
+ ("Yikes! Couldn't read any sessions!");
+ break;
+ }
#if DEBUG
- printk("Reading session %d\n", session);
+ printk("Reading session %d\n", session);
#endif
- parms[0] = session;
- do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
- parms,
- 1,
- (unsigned char *) &single_toc,
- &res_size);
- if ((res_size < 2) || ((single_toc.exec_status[0] & 0xf0) == 0x20))
- {
- printk("cdu31a: Error reading session %d: %x %s\n",
- session,
- single_toc.exec_status[0],
- translate_error(single_toc.exec_status[1]));
- /* An error reading the TOC. Return without sony_toc_read
- set. */
- return;
- }
+ parms[0] = session;
+ do_sony_cd_cmd(SONY_REQ_TOC_DATA_SPEC_CMD,
+ parms,
+ 1,
+ (unsigned char *) &single_toc,
+ &res_size);
+ if ((res_size < 2)
+ || ((single_toc.exec_status[0] & 0xf0) ==
+ 0x20)) {
+ printk
+ ("cdu31a: Error reading session %d: %x %s\n",
+ session, single_toc.exec_status[0],
+ translate_error(single_toc.
+ exec_status[1]));
+ /* An error reading the TOC. Return without sony_toc_read
+ set. */
+ return;
+ }
#if DEBUG
- printk("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
- single_toc.address0, single_toc.control0, single_toc.point0,
- bcd_to_int(single_toc.first_track_num), single_toc.disk_type, single_toc.dummy0);
- printk("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
- single_toc.address1, single_toc.control1, single_toc.point1,
- bcd_to_int(single_toc.last_track_num), single_toc.dummy1, single_toc.dummy2);
- printk("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
- single_toc.address2, single_toc.control2, single_toc.point2,
- bcd_to_int(single_toc.lead_out_start_msf[0]),
- bcd_to_int(single_toc.lead_out_start_msf[1]),
- bcd_to_int(single_toc.lead_out_start_msf[2]));
- if (res_size > 18 && single_toc.pointb0 > 0xaf)
- printk("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
- "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
- single_toc.addressb0, single_toc.controlb0, single_toc.pointb0,
- bcd_to_int(single_toc.next_poss_prog_area_msf[0]),
- bcd_to_int(single_toc.next_poss_prog_area_msf[1]),
- bcd_to_int(single_toc.next_poss_prog_area_msf[2]),
- single_toc.num_mode_5_pointers,
- bcd_to_int(single_toc.max_start_outer_leadout_msf[0]),
- bcd_to_int(single_toc.max_start_outer_leadout_msf[1]),
- bcd_to_int(single_toc.max_start_outer_leadout_msf[2]));
- if (res_size > 27 && single_toc.pointb1 > 0xaf)
- printk("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
- single_toc.addressb1, single_toc.controlb1, single_toc.pointb1,
- single_toc.dummyb0_1[0],
- single_toc.dummyb0_1[1],
- single_toc.dummyb0_1[2],
- single_toc.dummyb0_1[3],
- single_toc.num_skip_interval_pointers,
- single_toc.num_skip_track_assignments,
- single_toc.dummyb0_2);
- if (res_size > 36 && single_toc.pointb2 > 0xaf)
- printk("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressb2, single_toc.controlb2, single_toc.pointb2,
- single_toc.tracksb2[0],
- single_toc.tracksb2[1],
- single_toc.tracksb2[2],
- single_toc.tracksb2[3],
- single_toc.tracksb2[4],
- single_toc.tracksb2[5],
- single_toc.tracksb2[6]);
- if (res_size > 45 && single_toc.pointb3 > 0xaf)
- printk("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressb3, single_toc.controlb3, single_toc.pointb3,
- single_toc.tracksb3[0],
- single_toc.tracksb3[1],
- single_toc.tracksb3[2],
- single_toc.tracksb3[3],
- single_toc.tracksb3[4],
- single_toc.tracksb3[5],
- single_toc.tracksb3[6]);
- if (res_size > 54 && single_toc.pointb4 > 0xaf)
- printk("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressb4, single_toc.controlb4, single_toc.pointb4,
- single_toc.tracksb4[0],
- single_toc.tracksb4[1],
- single_toc.tracksb4[2],
- single_toc.tracksb4[3],
- single_toc.tracksb4[4],
- single_toc.tracksb4[5],
- single_toc.tracksb4[6]);
- if (res_size > 63 && single_toc.pointc0 > 0xaf)
- printk("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
- single_toc.addressc0, single_toc.controlc0, single_toc.pointc0,
- single_toc.dummyc0[0],
- single_toc.dummyc0[1],
- single_toc.dummyc0[2],
- single_toc.dummyc0[3],
- single_toc.dummyc0[4],
- single_toc.dummyc0[5],
- single_toc.dummyc0[6]);
+ printk
+ ("add0 %01x, con0 %01x, poi0 %02x, 1st trk %d, dsktyp %x, dum0 %x\n",
+ single_toc.address0, single_toc.control0,
+ single_toc.point0,
+ bcd_to_int(single_toc.first_track_num),
+ single_toc.disk_type, single_toc.dummy0);
+ printk
+ ("add1 %01x, con1 %01x, poi1 %02x, lst trk %d, dummy1 %x, dum2 %x\n",
+ single_toc.address1, single_toc.control1,
+ single_toc.point1,
+ bcd_to_int(single_toc.last_track_num),
+ single_toc.dummy1, single_toc.dummy2);
+ printk
+ ("add2 %01x, con2 %01x, poi2 %02x leadout start min %d, sec %d, frame %d\n",
+ single_toc.address2, single_toc.control2,
+ single_toc.point2,
+ bcd_to_int(single_toc.lead_out_start_msf[0]),
+ bcd_to_int(single_toc.lead_out_start_msf[1]),
+ bcd_to_int(single_toc.lead_out_start_msf[2]));
+ if (res_size > 18 && single_toc.pointb0 > 0xaf)
+ printk
+ ("addb0 %01x, conb0 %01x, poib0 %02x, nextsession min %d, sec %d, frame %d\n"
+ "#mode5_ptrs %02d, max_start_outer_leadout_msf min %d, sec %d, frame %d\n",
+ single_toc.addressb0,
+ single_toc.controlb0,
+ single_toc.pointb0,
+ bcd_to_int(single_toc.
+ next_poss_prog_area_msf
+ [0]),
+ bcd_to_int(single_toc.
+ next_poss_prog_area_msf
+ [1]),
+ bcd_to_int(single_toc.
+ next_poss_prog_area_msf
+ [2]),
+ single_toc.num_mode_5_pointers,
+ bcd_to_int(single_toc.
+ max_start_outer_leadout_msf
+ [0]),
+ bcd_to_int(single_toc.
+ max_start_outer_leadout_msf
+ [1]),
+ bcd_to_int(single_toc.
+ max_start_outer_leadout_msf
+ [2]));
+ if (res_size > 27 && single_toc.pointb1 > 0xaf)
+ printk
+ ("addb1 %01x, conb1 %01x, poib1 %02x, %x %x %x %x #skipint_ptrs %d, #skiptrkassign %d %x\n",
+ single_toc.addressb1,
+ single_toc.controlb1,
+ single_toc.pointb1,
+ single_toc.dummyb0_1[0],
+ single_toc.dummyb0_1[1],
+ single_toc.dummyb0_1[2],
+ single_toc.dummyb0_1[3],
+ single_toc.num_skip_interval_pointers,
+ single_toc.num_skip_track_assignments,
+ single_toc.dummyb0_2);
+ if (res_size > 36 && single_toc.pointb2 > 0xaf)
+ printk
+ ("addb2 %01x, conb2 %01x, poib2 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+ single_toc.addressb2,
+ single_toc.controlb2,
+ single_toc.pointb2,
+ single_toc.tracksb2[0],
+ single_toc.tracksb2[1],
+ single_toc.tracksb2[2],
+ single_toc.tracksb2[3],
+ single_toc.tracksb2[4],
+ single_toc.tracksb2[5],
+ single_toc.tracksb2[6]);
+ if (res_size > 45 && single_toc.pointb3 > 0xaf)
+ printk
+ ("addb3 %01x, conb3 %01x, poib3 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+ single_toc.addressb3,
+ single_toc.controlb3,
+ single_toc.pointb3,
+ single_toc.tracksb3[0],
+ single_toc.tracksb3[1],
+ single_toc.tracksb3[2],
+ single_toc.tracksb3[3],
+ single_toc.tracksb3[4],
+ single_toc.tracksb3[5],
+ single_toc.tracksb3[6]);
+ if (res_size > 54 && single_toc.pointb4 > 0xaf)
+ printk
+ ("addb4 %01x, conb4 %01x, poib4 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+ single_toc.addressb4,
+ single_toc.controlb4,
+ single_toc.pointb4,
+ single_toc.tracksb4[0],
+ single_toc.tracksb4[1],
+ single_toc.tracksb4[2],
+ single_toc.tracksb4[3],
+ single_toc.tracksb4[4],
+ single_toc.tracksb4[5],
+ single_toc.tracksb4[6]);
+ if (res_size > 63 && single_toc.pointc0 > 0xaf)
+ printk
+ ("addc0 %01x, conc0 %01x, poic0 %02x, %02x %02x %02x %02x %02x %02x %02x\n",
+ single_toc.addressc0,
+ single_toc.controlc0,
+ single_toc.pointc0,
+ single_toc.dummyc0[0],
+ single_toc.dummyc0[1],
+ single_toc.dummyc0[2],
+ single_toc.dummyc0[3],
+ single_toc.dummyc0[4],
+ single_toc.dummyc0[5],
+ single_toc.dummyc0[6]);
#endif
#undef DEBUG
#define DEBUG 0
- sony_toc.lead_out_start_msf[0] = bcd_to_int(single_toc.lead_out_start_msf[0]);
- sony_toc.lead_out_start_msf[1] = bcd_to_int(single_toc.lead_out_start_msf[1]);
- sony_toc.lead_out_start_msf[2] = bcd_to_int(single_toc.lead_out_start_msf[2]);
- sony_toc.lead_out_start_lba = single_toc.lead_out_start_lba =
- msf_to_log(sony_toc.lead_out_start_msf);
-
- /* For points that do not exist, move the data over them
- to the right location. */
- if (single_toc.pointb0 != 0xb0)
- {
- memmove(((char *) &single_toc) + 27,
- ((char *) &single_toc) + 18,
- res_size - 18);
- res_size += 9;
- }
- else if (res_size > 18) {
- sony_toc.lead_out_start_msf[0] = bcd_to_int(single_toc.max_start_outer_leadout_msf[0]);
- sony_toc.lead_out_start_msf[1] = bcd_to_int(single_toc.max_start_outer_leadout_msf[1]);
- sony_toc.lead_out_start_msf[2] = bcd_to_int(single_toc.max_start_outer_leadout_msf[2]);
- sony_toc.lead_out_start_lba = msf_to_log(sony_toc.lead_out_start_msf);
- }
- if (single_toc.pointb1 != 0xb1)
- {
- memmove(((char *) &single_toc) + 36,
- ((char *) &single_toc) + 27,
- res_size - 27);
- res_size += 9;
- }
- if (single_toc.pointb2 != 0xb2)
- {
- memmove(((char *) &single_toc) + 45,
- ((char *) &single_toc) + 36,
- res_size - 36);
- res_size += 9;
- }
- if (single_toc.pointb3 != 0xb3)
- {
- memmove(((char *) &single_toc) + 54,
- ((char *) &single_toc) + 45,
- res_size - 45);
- res_size += 9;
- }
- if (single_toc.pointb4 != 0xb4)
- {
- memmove(((char *) &single_toc) + 63,
- ((char *) &single_toc) + 54,
- res_size - 54);
- res_size += 9;
- }
- if (single_toc.pointc0 != 0xc0)
- {
- memmove(((char *) &single_toc) + 72,
- ((char *) &single_toc) + 63,
- res_size - 63);
- res_size += 9;
- }
-
+ sony_toc.lead_out_start_msf[0] =
+ bcd_to_int(single_toc.lead_out_start_msf[0]);
+ sony_toc.lead_out_start_msf[1] =
+ bcd_to_int(single_toc.lead_out_start_msf[1]);
+ sony_toc.lead_out_start_msf[2] =
+ bcd_to_int(single_toc.lead_out_start_msf[2]);
+ sony_toc.lead_out_start_lba =
+ single_toc.lead_out_start_lba =
+ msf_to_log(sony_toc.lead_out_start_msf);
+
+ /* For points that do not exist, move the data over them
+ to the right location. */
+ if (single_toc.pointb0 != 0xb0) {
+ memmove(((char *) &single_toc) + 27,
+ ((char *) &single_toc) + 18,
+ res_size - 18);
+ res_size += 9;
+ } else if (res_size > 18) {
+ sony_toc.lead_out_start_msf[0] =
+ bcd_to_int(single_toc.
+ max_start_outer_leadout_msf
+ [0]);
+ sony_toc.lead_out_start_msf[1] =
+ bcd_to_int(single_toc.
+ max_start_outer_leadout_msf
+ [1]);
+ sony_toc.lead_out_start_msf[2] =
+ bcd_to_int(single_toc.
+ max_start_outer_leadout_msf
+ [2]);
+ sony_toc.lead_out_start_lba =
+ msf_to_log(sony_toc.
+ lead_out_start_msf);
+ }
+ if (single_toc.pointb1 != 0xb1) {
+ memmove(((char *) &single_toc) + 36,
+ ((char *) &single_toc) + 27,
+ res_size - 27);
+ res_size += 9;
+ }
+ if (single_toc.pointb2 != 0xb2) {
+ memmove(((char *) &single_toc) + 45,
+ ((char *) &single_toc) + 36,
+ res_size - 36);
+ res_size += 9;
+ }
+ if (single_toc.pointb3 != 0xb3) {
+ memmove(((char *) &single_toc) + 54,
+ ((char *) &single_toc) + 45,
+ res_size - 45);
+ res_size += 9;
+ }
+ if (single_toc.pointb4 != 0xb4) {
+ memmove(((char *) &single_toc) + 63,
+ ((char *) &single_toc) + 54,
+ res_size - 54);
+ res_size += 9;
+ }
+ if (single_toc.pointc0 != 0xc0) {
+ memmove(((char *) &single_toc) + 72,
+ ((char *) &single_toc) + 63,
+ res_size - 63);
+ res_size += 9;
+ }
#if DEBUG
- printk("start track lba %u, leadout start lba %u\n",
- single_toc.start_track_lba, single_toc.lead_out_start_lba);
- { int i;
- for (i = 0; i < 1 + bcd_to_int(single_toc.last_track_num)
- - bcd_to_int(single_toc.first_track_num); i++) {
- printk("trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n",
- i, single_toc.tracks[i].address, single_toc.tracks[i].control,
- bcd_to_int(single_toc.tracks[i].track),
- bcd_to_int(single_toc.tracks[i].track_start_msf[0]),
- bcd_to_int(single_toc.tracks[i].track_start_msf[1]),
- bcd_to_int(single_toc.tracks[i].track_start_msf[2]));
- if (mint > bcd_to_int(single_toc.tracks[i].track))
- mint = bcd_to_int(single_toc.tracks[i].track);
- if (maxt < bcd_to_int(single_toc.tracks[i].track))
- maxt = bcd_to_int(single_toc.tracks[i].track);
- }
- printk("min track number %d, max track number %d\n", mint, maxt);
- }
+ printk
+ ("start track lba %u, leadout start lba %u\n",
+ single_toc.start_track_lba,
+ single_toc.lead_out_start_lba);
+ {
+ int i;
+ for (i = 0;
+ i <
+ 1 +
+ bcd_to_int(single_toc.last_track_num)
+ -
+ bcd_to_int(single_toc.
+ first_track_num); i++) {
+ printk
+ ("trk %02d: add 0x%01x, con 0x%01x, track %02d, start min %02d, sec %02d, frame %02d\n",
+ i,
+ single_toc.tracks[i].address,
+ single_toc.tracks[i].control,
+ bcd_to_int(single_toc.
+ tracks[i].track),
+ bcd_to_int(single_toc.
+ tracks[i].
+ track_start_msf
+ [0]),
+ bcd_to_int(single_toc.
+ tracks[i].
+ track_start_msf
+ [1]),
+ bcd_to_int(single_toc.
+ tracks[i].
+ track_start_msf
+ [2]));
+ if (mint >
+ bcd_to_int(single_toc.
+ tracks[i].track))
+ mint =
+ bcd_to_int(single_toc.
+ tracks[i].
+ track);
+ if (maxt <
+ bcd_to_int(single_toc.
+ tracks[i].track))
+ maxt =
+ bcd_to_int(single_toc.
+ tracks[i].
+ track);
+ }
+ printk
+ ("min track number %d, max track number %d\n",
+ mint, maxt);
+ }
#endif
- /* prepare a special table of contents for a CD-I disc. They don't have one. */
- if (single_toc.disk_type == 0x10 &&
- single_toc.first_track_num == 2 &&
- single_toc.last_track_num == 2 /* CD-I */)
- {
- sony_toc.tracks[totaltracks].address = 1;
- sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
- sony_toc.tracks[totaltracks].track = 1;
- sony_toc.tracks[totaltracks].track_start_msf[0] = 0;
- sony_toc.tracks[totaltracks].track_start_msf[1] = 2;
- sony_toc.tracks[totaltracks].track_start_msf[2] = 0;
- mint = maxt = 1;
- totaltracks++;
- } else
- /* gather track entries from this session */
- { int i;
- for (i = 0; i < 1 + bcd_to_int(single_toc.last_track_num)
- - bcd_to_int(single_toc.first_track_num); i++, totaltracks++) {
- sony_toc.tracks[totaltracks].address = single_toc.tracks[i].address;
- sony_toc.tracks[totaltracks].control = single_toc.tracks[i].control;
- sony_toc.tracks[totaltracks].track = bcd_to_int(single_toc.tracks[i].track);
- sony_toc.tracks[totaltracks].track_start_msf[0] =
- bcd_to_int(single_toc.tracks[i].track_start_msf[0]);
- sony_toc.tracks[totaltracks].track_start_msf[1] =
- bcd_to_int(single_toc.tracks[i].track_start_msf[1]);
- sony_toc.tracks[totaltracks].track_start_msf[2] =
- bcd_to_int(single_toc.tracks[i].track_start_msf[2]);
- if (i == 0)
- single_toc.start_track_lba = msf_to_log(sony_toc.tracks[totaltracks].track_start_msf);
- if (mint > sony_toc.tracks[totaltracks].track)
- mint = sony_toc.tracks[totaltracks].track;
- if (maxt < sony_toc.tracks[totaltracks].track)
- maxt = sony_toc.tracks[totaltracks].track;
- }
- }
- sony_toc.first_track_num = mint;
- sony_toc.last_track_num = maxt;
- /* Disk type of last session wins. For example:
- CD-Extra has disk type 0 for the first session, so
- a dumb HiFi CD player thinks it is a plain audio CD.
- We are interested in the disk type of the last session,
- which is 0x20 (XA) for CD-Extra, so we can access the
- data track ... */
- sony_toc.disk_type = single_toc.disk_type;
- sony_toc.sessions = session;
-
- /* don't believe everything :-) */
- if (session == 1)
- single_toc.start_track_lba = 0;
- sony_toc.start_track_lba = single_toc.start_track_lba;
-
- if (session > 1 && single_toc.pointb0 == 0xb0 &&
- sony_toc.lead_out_start_lba == single_toc.lead_out_start_lba)
- {
- break;
- }
-
- /* Let's not get carried away... */
- if (session > 40)
- {
- printk("cdu31a: too many sessions: %d\n", session);
- break;
- }
- session++;
- }
- sony_toc.track_entries = totaltracks;
- /* add one entry for the LAST track with track number CDROM_LEADOUT */
- sony_toc.tracks[totaltracks].address = single_toc.address2;
- sony_toc.tracks[totaltracks].control = single_toc.control2;
- sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
- sony_toc.tracks[totaltracks].track_start_msf[0] =
- sony_toc.lead_out_start_msf[0];
- sony_toc.tracks[totaltracks].track_start_msf[1] =
- sony_toc.lead_out_start_msf[1];
- sony_toc.tracks[totaltracks].track_start_msf[2] =
- sony_toc.lead_out_start_msf[2];
-
- sony_toc_read = 1;
+ /* prepare a special table of contents for a CD-I disc. They don't have one. */
+ if (single_toc.disk_type == 0x10 &&
+ single_toc.first_track_num == 2 &&
+ single_toc.last_track_num == 2 /* CD-I */ ) {
+ sony_toc.tracks[totaltracks].address = 1;
+ sony_toc.tracks[totaltracks].control = 4; /* force data tracks */
+ sony_toc.tracks[totaltracks].track = 1;
+ sony_toc.tracks[totaltracks].
+ track_start_msf[0] = 0;
+ sony_toc.tracks[totaltracks].
+ track_start_msf[1] = 2;
+ sony_toc.tracks[totaltracks].
+ track_start_msf[2] = 0;
+ mint = maxt = 1;
+ totaltracks++;
+ } else
+ /* gather track entries from this session */
+ {
+ int i;
+ for (i = 0;
+ i <
+ 1 +
+ bcd_to_int(single_toc.last_track_num)
+ -
+ bcd_to_int(single_toc.
+ first_track_num);
+ i++, totaltracks++) {
+ sony_toc.tracks[totaltracks].
+ address =
+ single_toc.tracks[i].address;
+ sony_toc.tracks[totaltracks].
+ control =
+ single_toc.tracks[i].control;
+ sony_toc.tracks[totaltracks].
+ track =
+ bcd_to_int(single_toc.
+ tracks[i].track);
+ sony_toc.tracks[totaltracks].
+ track_start_msf[0] =
+ bcd_to_int(single_toc.
+ tracks[i].
+ track_start_msf[0]);
+ sony_toc.tracks[totaltracks].
+ track_start_msf[1] =
+ bcd_to_int(single_toc.
+ tracks[i].
+ track_start_msf[1]);
+ sony_toc.tracks[totaltracks].
+ track_start_msf[2] =
+ bcd_to_int(single_toc.
+ tracks[i].
+ track_start_msf[2]);
+ if (i == 0)
+ single_toc.
+ start_track_lba =
+ msf_to_log(sony_toc.
+ tracks
+ [totaltracks].
+ track_start_msf);
+ if (mint >
+ sony_toc.tracks[totaltracks].
+ track)
+ mint =
+ sony_toc.
+ tracks[totaltracks].
+ track;
+ if (maxt <
+ sony_toc.tracks[totaltracks].
+ track)
+ maxt =
+ sony_toc.
+ tracks[totaltracks].
+ track;
+ }
+ }
+ sony_toc.first_track_num = mint;
+ sony_toc.last_track_num = maxt;
+ /* Disk type of last session wins. For example:
+ CD-Extra has disk type 0 for the first session, so
+ a dumb HiFi CD player thinks it is a plain audio CD.
+ We are interested in the disk type of the last session,
+ which is 0x20 (XA) for CD-Extra, so we can access the
+ data track ... */
+ sony_toc.disk_type = single_toc.disk_type;
+ sony_toc.sessions = session;
+
+ /* don't believe everything :-) */
+ if (session == 1)
+ single_toc.start_track_lba = 0;
+ sony_toc.start_track_lba =
+ single_toc.start_track_lba;
+
+ if (session > 1 && single_toc.pointb0 == 0xb0 &&
+ sony_toc.lead_out_start_lba ==
+ single_toc.lead_out_start_lba) {
+ break;
+ }
+
+ /* Let's not get carried away... */
+ if (session > 40) {
+ printk("cdu31a: too many sessions: %d\n",
+ session);
+ break;
+ }
+ session++;
+ }
+ sony_toc.track_entries = totaltracks;
+ /* add one entry for the LAST track with track number CDROM_LEADOUT */
+ sony_toc.tracks[totaltracks].address = single_toc.address2;
+ sony_toc.tracks[totaltracks].control = single_toc.control2;
+ sony_toc.tracks[totaltracks].track = CDROM_LEADOUT;
+ sony_toc.tracks[totaltracks].track_start_msf[0] =
+ sony_toc.lead_out_start_msf[0];
+ sony_toc.tracks[totaltracks].track_start_msf[1] =
+ sony_toc.lead_out_start_msf[1];
+ sony_toc.tracks[totaltracks].track_start_msf[2] =
+ sony_toc.lead_out_start_msf[2];
+
+ sony_toc_read = 1;
#undef DEBUG
#if DEBUG
- printk("Disk session %d, start track: %d, stop track: %d\n",
- session,
- single_toc.start_track_lba,
- single_toc.lead_out_start_lba);
+ printk
+ ("Disk session %d, start track: %d, stop track: %d\n",
+ session, single_toc.start_track_lba,
+ single_toc.lead_out_start_lba);
#endif
- }
+ }
#if DEBUG
- printk("Leaving sony_get_toc\n");
+ printk("Leaving sony_get_toc\n");
#endif
}
* Uniform cdrom interface function
* return multisession offset and sector information
*/
-static int scd_get_last_session(struct cdrom_device_info *cdi,
- struct cdrom_multisession *ms_info)
+static int scd_get_last_session(struct cdrom_device_info *cdi,
+ struct cdrom_multisession *ms_info)
{
- if (ms_info == NULL)
- return 1;
+ if (ms_info == NULL)
+ return 1;
- if (!sony_toc_read)
- sony_get_toc();
+ if (!sony_toc_read)
+ sony_get_toc();
- ms_info->addr_format = CDROM_LBA;
- ms_info->addr.lba = sony_toc.start_track_lba;
- ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
- sony_toc.disk_type == 0x10 /* CDI */;
+ ms_info->addr_format = CDROM_LBA;
+ ms_info->addr.lba = sony_toc.start_track_lba;
+ ms_info->xa_flag = sony_toc.disk_type == SONY_XA_DISK_TYPE ||
+ sony_toc.disk_type == 0x10 /* CDI */ ;
- return 0;
+ return 0;
}
/*
* Search for a specific track in the table of contents.
*/
-static int
-find_track(int track)
+static int find_track(int track)
{
- int i;
+ int i;
- for (i = 0; i <= sony_toc.track_entries; i++)
- {
- if (sony_toc.tracks[i].track == track)
- {
- return i;
- }
- }
+ for (i = 0; i <= sony_toc.track_entries; i++) {
+ if (sony_toc.tracks[i].track == track) {
+ return i;
+ }
+ }
- return -1;
+ return -1;
}
/*
* Read the subcode and put it in last_sony_subcode for future use.
*/
-static int
-read_subcode(void)
-{
- unsigned int res_size;
-
-
- do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
- NULL,
- 0,
- (unsigned char *) &last_sony_subcode,
- &res_size);
- if ((res_size < 2) || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error %s (read_subcode)\n",
- translate_error(last_sony_subcode.exec_status[1]));
- return -EIO;
- }
-
- last_sony_subcode.track_num = bcd_to_int(last_sony_subcode.track_num);
- last_sony_subcode.index_num = bcd_to_int(last_sony_subcode.index_num);
- last_sony_subcode.abs_msf[0] = bcd_to_int(last_sony_subcode.abs_msf[0]);
- last_sony_subcode.abs_msf[1] = bcd_to_int(last_sony_subcode.abs_msf[1]);
- last_sony_subcode.abs_msf[2] = bcd_to_int(last_sony_subcode.abs_msf[2]);
-
- last_sony_subcode.rel_msf[0] = bcd_to_int(last_sony_subcode.rel_msf[0]);
- last_sony_subcode.rel_msf[1] = bcd_to_int(last_sony_subcode.rel_msf[1]);
- last_sony_subcode.rel_msf[2] = bcd_to_int(last_sony_subcode.rel_msf[2]);
- return 0;
+static int read_subcode(void)
+{
+ unsigned int res_size;
+
+
+ do_sony_cd_cmd(SONY_REQ_SUBCODE_ADDRESS_CMD,
+ NULL,
+ 0, (unsigned char *) &last_sony_subcode, &res_size);
+ if ((res_size < 2)
+ || ((last_sony_subcode.exec_status[0] & 0xf0) == 0x20)) {
+ printk("Sony CDROM error %s (read_subcode)\n",
+ translate_error(last_sony_subcode.exec_status[1]));
+ return -EIO;
+ }
+
+ last_sony_subcode.track_num =
+ bcd_to_int(last_sony_subcode.track_num);
+ last_sony_subcode.index_num =
+ bcd_to_int(last_sony_subcode.index_num);
+ last_sony_subcode.abs_msf[0] =
+ bcd_to_int(last_sony_subcode.abs_msf[0]);
+ last_sony_subcode.abs_msf[1] =
+ bcd_to_int(last_sony_subcode.abs_msf[1]);
+ last_sony_subcode.abs_msf[2] =
+ bcd_to_int(last_sony_subcode.abs_msf[2]);
+
+ last_sony_subcode.rel_msf[0] =
+ bcd_to_int(last_sony_subcode.rel_msf[0]);
+ last_sony_subcode.rel_msf[1] =
+ bcd_to_int(last_sony_subcode.rel_msf[1]);
+ last_sony_subcode.rel_msf[2] =
+ bcd_to_int(last_sony_subcode.rel_msf[2]);
+ return 0;
}
/*
static int
scd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
{
- unsigned char resbuffer[2 + 14];
- unsigned char *mcnp = mcn->medium_catalog_number;
- unsigned char *resp = resbuffer + 3;
- unsigned int res_size;
-
- memset(mcn->medium_catalog_number, 0, 14);
- do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
- NULL,
- 0,
- resbuffer,
- &res_size);
- if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20))
- ;
- else {
- /* packed bcd to single ASCII digits */
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- *mcnp++ = (*resp++ & 0x0f) + '0';
- *mcnp++ = (*resp >> 4) + '0';
- }
- *mcnp = '\0';
- return 0;
+ unsigned char resbuffer[2 + 14];
+ unsigned char *mcnp = mcn->medium_catalog_number;
+ unsigned char *resp = resbuffer + 3;
+ unsigned int res_size;
+
+ memset(mcn->medium_catalog_number, 0, 14);
+ do_sony_cd_cmd(SONY_REQ_UPC_EAN_CMD,
+ NULL, 0, resbuffer, &res_size);
+ if ((res_size < 2) || ((resbuffer[0] & 0xf0) == 0x20));
+ else {
+ /* packed bcd to single ASCII digits */
+ *mcnp++ = (*resp >> 4) + '0';
+ *mcnp++ = (*resp++ & 0x0f) + '0';
+ *mcnp++ = (*resp >> 4) + '0';
+ *mcnp++ = (*resp++ & 0x0f) + '0';
+ *mcnp++ = (*resp >> 4) + '0';
+ *mcnp++ = (*resp++ & 0x0f) + '0';
+ *mcnp++ = (*resp >> 4) + '0';
+ *mcnp++ = (*resp++ & 0x0f) + '0';
+ *mcnp++ = (*resp >> 4) + '0';
+ *mcnp++ = (*resp++ & 0x0f) + '0';
+ *mcnp++ = (*resp >> 4) + '0';
+ *mcnp++ = (*resp++ & 0x0f) + '0';
+ *mcnp++ = (*resp >> 4) + '0';
+ }
+ *mcnp = '\0';
+ return 0;
}
* already been stored, just use that. The ioctl call wants things in decimal
* (not BCD), so all the conversions are done.
*/
-static int
-sony_get_subchnl_info(struct cdrom_subchnl *schi)
-{
- /* Get attention stuff */
- while (handle_sony_cd_attention())
- ;
-
- sony_get_toc();
- if (!sony_toc_read)
- {
- return -EIO;
- }
-
- switch (sony_audio_status)
- {
- case CDROM_AUDIO_NO_STATUS:
- case CDROM_AUDIO_PLAY:
- if (read_subcode() < 0)
- {
- return -EIO;
- }
- break;
-
- case CDROM_AUDIO_PAUSED:
- case CDROM_AUDIO_COMPLETED:
- break;
+static int sony_get_subchnl_info(struct cdrom_subchnl *schi)
+{
+ /* Get attention stuff */
+ while (handle_sony_cd_attention());
+
+ sony_get_toc();
+ if (!sony_toc_read) {
+ return -EIO;
+ }
+
+ switch (sony_audio_status) {
+ case CDROM_AUDIO_NO_STATUS:
+ case CDROM_AUDIO_PLAY:
+ if (read_subcode() < 0) {
+ return -EIO;
+ }
+ break;
+
+ case CDROM_AUDIO_PAUSED:
+ case CDROM_AUDIO_COMPLETED:
+ break;
#if 0
- case CDROM_AUDIO_NO_STATUS:
- schi->cdsc_audiostatus = sony_audio_status;
- return 0;
- break;
+ case CDROM_AUDIO_NO_STATUS:
+ schi->cdsc_audiostatus = sony_audio_status;
+ return 0;
+ break;
#endif
- case CDROM_AUDIO_INVALID:
- case CDROM_AUDIO_ERROR:
- default:
- return -EIO;
- }
-
- schi->cdsc_audiostatus = sony_audio_status;
- schi->cdsc_adr = last_sony_subcode.address;
- schi->cdsc_ctrl = last_sony_subcode.control;
- schi->cdsc_trk = last_sony_subcode.track_num;
- schi->cdsc_ind = last_sony_subcode.index_num;
- if (schi->cdsc_format == CDROM_MSF)
- {
- schi->cdsc_absaddr.msf.minute = last_sony_subcode.abs_msf[0];
- schi->cdsc_absaddr.msf.second = last_sony_subcode.abs_msf[1];
- schi->cdsc_absaddr.msf.frame = last_sony_subcode.abs_msf[2];
-
- schi->cdsc_reladdr.msf.minute = last_sony_subcode.rel_msf[0];
- schi->cdsc_reladdr.msf.second = last_sony_subcode.rel_msf[1];
- schi->cdsc_reladdr.msf.frame = last_sony_subcode.rel_msf[2];
- }
- else if (schi->cdsc_format == CDROM_LBA)
- {
- schi->cdsc_absaddr.lba = msf_to_log(last_sony_subcode.abs_msf);
- schi->cdsc_reladdr.lba = msf_to_log(last_sony_subcode.rel_msf);
- }
-
- return 0;
+ case CDROM_AUDIO_INVALID:
+ case CDROM_AUDIO_ERROR:
+ default:
+ return -EIO;
+ }
+
+ schi->cdsc_audiostatus = sony_audio_status;
+ schi->cdsc_adr = last_sony_subcode.address;
+ schi->cdsc_ctrl = last_sony_subcode.control;
+ schi->cdsc_trk = last_sony_subcode.track_num;
+ schi->cdsc_ind = last_sony_subcode.index_num;
+ if (schi->cdsc_format == CDROM_MSF) {
+ schi->cdsc_absaddr.msf.minute =
+ last_sony_subcode.abs_msf[0];
+ schi->cdsc_absaddr.msf.second =
+ last_sony_subcode.abs_msf[1];
+ schi->cdsc_absaddr.msf.frame =
+ last_sony_subcode.abs_msf[2];
+
+ schi->cdsc_reladdr.msf.minute =
+ last_sony_subcode.rel_msf[0];
+ schi->cdsc_reladdr.msf.second =
+ last_sony_subcode.rel_msf[1];
+ schi->cdsc_reladdr.msf.frame =
+ last_sony_subcode.rel_msf[2];
+ } else if (schi->cdsc_format == CDROM_LBA) {
+ schi->cdsc_absaddr.lba =
+ msf_to_log(last_sony_subcode.abs_msf);
+ schi->cdsc_reladdr.lba =
+ msf_to_log(last_sony_subcode.rel_msf);
+ }
+
+ return 0;
}
/* Get audio data from the drive. This is fairly complex because I
then I just look for data. I need to get the status immediately so
the switch from audio to data tracks will happen quickly. */
static void
-read_audio_data(char *buffer,
- unsigned char res_reg[],
- int *res_size)
-{
- unsigned int retry_count;
- int result_read;
-
-
- res_reg[0] = 0;
- res_reg[1] = 0;
- *res_size = 0;
- result_read = 0;
-
- /* Wait for the drive to tell us we have something */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
-continue_read_audio_wait:
- while (time_before(jiffies, retry_count) && !(is_data_ready())
- && !(is_result_ready() || result_read))
- {
- while (handle_sony_cd_attention())
- ;
-
- sony_sleep();
- }
- if (!(is_data_ready()))
- {
- if (is_result_ready() && !result_read)
- {
- get_result(res_reg, res_size);
-
- /* Read block status and continue waiting for data. */
- if ((res_reg[0] & 0xf0) == 0x50)
- {
- result_read = 1;
- goto continue_read_audio_wait;
- }
- /* Invalid data from the drive. Shut down the operation. */
- else if ((res_reg[0] & 0xf0) != 0x20)
- {
- printk("CDU31A: Got result that should have been error: %d\n",
- res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- abort_read();
- }
- else
- {
+read_audio_data(char *buffer, unsigned char res_reg[], int *res_size)
+{
+ unsigned int retry_count;
+ int result_read;
+
+
+ res_reg[0] = 0;
+ res_reg[1] = 0;
+ *res_size = 0;
+ result_read = 0;
+
+ /* Wait for the drive to tell us we have something */
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ continue_read_audio_wait:
+ while (time_before(jiffies, retry_count) && !(is_data_ready())
+ && !(is_result_ready() || result_read)) {
+ while (handle_sony_cd_attention());
+
+ sony_sleep();
+ }
+ if (!(is_data_ready())) {
+ if (is_result_ready() && !result_read) {
+ get_result(res_reg, res_size);
+
+ /* Read block status and continue waiting for data. */
+ if ((res_reg[0] & 0xf0) == 0x50) {
+ result_read = 1;
+ goto continue_read_audio_wait;
+ }
+ /* Invalid data from the drive. Shut down the operation. */
+ else if ((res_reg[0] & 0xf0) != 0x20) {
+ printk
+ ("CDU31A: Got result that should have been error: %d\n",
+ res_reg[0]);
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+ abort_read();
+ } else {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n", __LINE__);
#endif
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- }
- }
- else
- {
- clear_data_ready();
-
- /* If data block, then get 2340 bytes offset by 12. */
- if (sony_raw_data_mode)
- {
- insb(sony_cd_read_reg, buffer + CD_XA_HEAD, CD_FRAMESIZE_RAW1);
- }
- else
- {
- /* Audio gets the whole 2352 bytes. */
- insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
- }
-
- /* If I haven't already gotten the result, get it now. */
- if (!result_read)
- {
- /* Wait for the drive to tell us we have something */
- retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
- while (time_before(jiffies, retry_count) && !(is_result_ready()))
- {
- while (handle_sony_cd_attention())
- ;
-
- sony_sleep();
- }
-
- if (!is_result_ready())
- {
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_TIMEOUT_OP_ERR;
+ *res_size = 2;
+ abort_read();
+ }
+ } else {
+ clear_data_ready();
+
+ /* If data block, then get 2340 bytes offset by 12. */
+ if (sony_raw_data_mode) {
+ insb(sony_cd_read_reg, buffer + CD_XA_HEAD,
+ CD_FRAMESIZE_RAW1);
+ } else {
+ /* Audio gets the whole 2352 bytes. */
+ insb(sony_cd_read_reg, buffer, CD_FRAMESIZE_RAW);
+ }
+
+ /* If I haven't already gotten the result, get it now. */
+ if (!result_read) {
+ /* Wait for the drive to tell us we have something */
+ retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
+ while (time_before(jiffies, retry_count)
+ && !(is_result_ready())) {
+ while (handle_sony_cd_attention());
+
+ sony_sleep();
+ }
+
+ if (!is_result_ready()) {
#if DEBUG
- printk("CDU31A timeout out %d\n", __LINE__);
+ printk("CDU31A timeout out %d\n",
+ __LINE__);
#endif
- res_reg[0] = 0x20;
- res_reg[1] = SONY_TIMEOUT_OP_ERR;
- *res_size = 2;
- abort_read();
- return;
- }
- else
- {
- get_result(res_reg, res_size);
- }
- }
-
- if ((res_reg[0] & 0xf0) == 0x50)
- {
- if ( (res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
- || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT))
- {
- /* Ok, nothing to do. */
- }
- else
- {
- printk("CDU31A: Data block error: 0x%x\n", res_reg[0]);
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- }
- else if ((res_reg[0] & 0xf0) != 0x20)
- {
- /* The drive gave me bad status, I don't know what to do.
- Reset the driver and return an error. */
- printk("CDU31A: Invalid block status: 0x%x\n", res_reg[0]);
- restart_on_error();
- res_reg[0] = 0x20;
- res_reg[1] = SONY_BAD_DATA_ERR;
- *res_size = 2;
- }
- }
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_TIMEOUT_OP_ERR;
+ *res_size = 2;
+ abort_read();
+ return;
+ } else {
+ get_result(res_reg, res_size);
+ }
+ }
+
+ if ((res_reg[0] & 0xf0) == 0x50) {
+ if ((res_reg[0] == SONY_NO_CIRC_ERR_BLK_STAT)
+ || (res_reg[0] == SONY_NO_LECC_ERR_BLK_STAT)
+ || (res_reg[0] == SONY_RECOV_LECC_ERR_BLK_STAT)
+ || (res_reg[0] == SONY_NO_ERR_DETECTION_STAT)) {
+ /* Ok, nothing to do. */
+ } else {
+ printk("CDU31A: Data block error: 0x%x\n",
+ res_reg[0]);
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+ } else if ((res_reg[0] & 0xf0) != 0x20) {
+ /* The drive gave me bad status, I don't know what to do.
+ Reset the driver and return an error. */
+ printk("CDU31A: Invalid block status: 0x%x\n",
+ res_reg[0]);
+ restart_on_error();
+ res_reg[0] = 0x20;
+ res_reg[1] = SONY_BAD_DATA_ERR;
+ *res_size = 2;
+ }
+ }
}
/* Perform a raw data read. This will automatically detect the
track type and read the proper data (audio or data). */
-static int
-read_audio(struct cdrom_read_audio *ra)
-{
- int retval;
- unsigned char params[2];
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned int cframe;
- unsigned long flags;
-
- /*
- * Make sure no one else is using the driver; wait for them
- * to finish if it is so.
- */
- save_flags(flags);
- cli();
- while (sony_inuse)
- {
- interruptible_sleep_on(&sony_wait);
- if (signal_pending(current))
- {
- restore_flags(flags);
- return -EAGAIN;
- }
- }
- sony_inuse = 1;
- has_cd_task = current;
- restore_flags(flags);
-
- if (!sony_spun_up)
- {
- scd_spinup();
- }
-
- /* Set the drive to do raw operations. */
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x06 | sony_raw_data_mode;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("CDU31A: Unable to set decode params: 0x%2.2x\n", res_reg[1]);
- return -EIO;
- }
-
- /* From here down, we have to goto exit_read_audio instead of returning
- because the drive parameters have to be set back to data before
- return. */
-
- retval = 0;
- /* start_request clears out any readahead data, so it should be safe. */
- if (start_request(ra->addr.lba, ra->nframes, 1))
- {
- retval = -EIO;
- goto exit_read_audio;
- }
-
- /* For every requested frame. */
- cframe = 0;
- while (cframe < ra->nframes)
- {
- read_audio_data(readahead_buffer, res_reg, &res_size);
- if ((res_reg[0] & 0xf0) == 0x20)
- {
- if (res_reg[1] == SONY_BAD_DATA_ERR)
- {
- printk("CDU31A: Data error on audio sector %d\n",
- ra->addr.lba + cframe);
- }
- else if (res_reg[1] == SONY_ILL_TRACK_R_ERR)
- {
- /* Illegal track type, change track types and start over. */
- sony_raw_data_mode = (sony_raw_data_mode) ? 0 : 1;
-
- /* Set the drive mode. */
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x06 | sony_raw_data_mode;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("CDU31A: Unable to set decode params: 0x%2.2x\n", res_reg[1]);
- retval = -EIO;
- goto exit_read_audio;
- }
-
- /* Restart the request on the current frame. */
- if (start_request(ra->addr.lba + cframe, ra->nframes - cframe, 1))
- {
- retval = -EIO;
- goto exit_read_audio;
- }
-
- /* Don't go back to the top because don't want to get into
- and infinite loop. A lot of code gets duplicated, but
- that's no big deal, I don't guess. */
- read_audio_data(readahead_buffer, res_reg, &res_size);
- if ((res_reg[0] & 0xf0) == 0x20)
- {
- if (res_reg[1] == SONY_BAD_DATA_ERR)
- {
- printk("CDU31A: Data error on audio sector %d\n",
- ra->addr.lba + cframe);
- }
- else
- {
- printk("CDU31A: Error reading audio data on sector %d: %s\n",
- ra->addr.lba + cframe,
- translate_error(res_reg[1]));
- retval = -EIO;
- goto exit_read_audio;
- }
- }
- else
- {
- copy_to_user((char *) (ra->buf + (CD_FRAMESIZE_RAW * cframe)),
- (char *) readahead_buffer,
- CD_FRAMESIZE_RAW);
- }
- }
- else
- {
- printk("CDU31A: Error reading audio data on sector %d: %s\n",
- ra->addr.lba + cframe,
- translate_error(res_reg[1]));
- retval = -EIO;
- goto exit_read_audio;
- }
- }
- else
- {
- copy_to_user((char *) (ra->buf + (CD_FRAMESIZE_RAW * cframe)),
- (char *) readahead_buffer,
- CD_FRAMESIZE_RAW);
- }
-
- cframe++;
- }
-
- get_result(res_reg, &res_size);
- if ((res_reg[0] & 0xf0) == 0x20)
- {
- printk("CDU31A: Error return from audio read: %s\n",
- translate_error(res_reg[1]));
- retval = -EIO;
- goto exit_read_audio;
- }
-
-exit_read_audio:
-
- /* Set the drive mode back to the proper one for the disk. */
- params[0] = SONY_SD_DECODE_PARAM;
- if (!sony_xa_mode)
- {
- params[1] = 0x0f;
- }
- else
- {
- params[1] = 0x07;
- }
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("CDU31A: Unable to reset decode params: 0x%2.2x\n", res_reg[1]);
- return -EIO;
- }
-
- has_cd_task = NULL;
- sony_inuse = 0;
- wake_up_interruptible(&sony_wait);
-
- return(retval);
+static int read_audio(struct cdrom_read_audio *ra)
+{
+ int retval;
+ unsigned char params[2];
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ unsigned int cframe;
+ unsigned long flags;
+
+ /*
+ * Make sure no one else is using the driver; wait for them
+ * to finish if it is so.
+ */
+ save_flags(flags);
+ cli();
+ while (sony_inuse) {
+ interruptible_sleep_on(&sony_wait);
+ if (signal_pending(current)) {
+ restore_flags(flags);
+ return -EAGAIN;
+ }
+ }
+ sony_inuse = 1;
+ has_cd_task = current;
+ restore_flags(flags);
+
+ if (!sony_spun_up) {
+ scd_spinup();
+ }
+
+ /* Set the drive to do raw operations. */
+ params[0] = SONY_SD_DECODE_PARAM;
+ params[1] = 0x06 | sony_raw_data_mode;
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params, 2, res_reg, &res_size);
+ if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk("CDU31A: Unable to set decode params: 0x%2.2x\n",
+ res_reg[1]);
+ return -EIO;
+ }
+
+ /* From here down, we have to goto exit_read_audio instead of returning
+ because the drive parameters have to be set back to data before
+ return. */
+
+ retval = 0;
+ /* start_request clears out any readahead data, so it should be safe. */
+ if (start_request(ra->addr.lba, ra->nframes, 1)) {
+ retval = -EIO;
+ goto exit_read_audio;
+ }
+
+ /* For every requested frame. */
+ cframe = 0;
+ while (cframe < ra->nframes) {
+ read_audio_data(readahead_buffer, res_reg, &res_size);
+ if ((res_reg[0] & 0xf0) == 0x20) {
+ if (res_reg[1] == SONY_BAD_DATA_ERR) {
+ printk
+ ("CDU31A: Data error on audio sector %d\n",
+ ra->addr.lba + cframe);
+ } else if (res_reg[1] == SONY_ILL_TRACK_R_ERR) {
+ /* Illegal track type, change track types and start over. */
+ sony_raw_data_mode =
+ (sony_raw_data_mode) ? 0 : 1;
+
+ /* Set the drive mode. */
+ params[0] = SONY_SD_DECODE_PARAM;
+ params[1] = 0x06 | sony_raw_data_mode;
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params,
+ 2, res_reg, &res_size);
+ if ((res_size < 2)
+ || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk
+ ("CDU31A: Unable to set decode params: 0x%2.2x\n",
+ res_reg[1]);
+ retval = -EIO;
+ goto exit_read_audio;
+ }
+
+ /* Restart the request on the current frame. */
+ if (start_request
+ (ra->addr.lba + cframe,
+ ra->nframes - cframe, 1)) {
+ retval = -EIO;
+ goto exit_read_audio;
+ }
+
+ /* Don't go back to the top because don't want to get into
+ and infinite loop. A lot of code gets duplicated, but
+ that's no big deal, I don't guess. */
+ read_audio_data(readahead_buffer, res_reg,
+ &res_size);
+ if ((res_reg[0] & 0xf0) == 0x20) {
+ if (res_reg[1] ==
+ SONY_BAD_DATA_ERR) {
+ printk
+ ("CDU31A: Data error on audio sector %d\n",
+ ra->addr.lba +
+ cframe);
+ } else {
+ printk
+ ("CDU31A: Error reading audio data on sector %d: %s\n",
+ ra->addr.lba + cframe,
+ translate_error
+ (res_reg[1]));
+ retval = -EIO;
+ goto exit_read_audio;
+ }
+ } else {
+ copy_to_user((char *) (ra->buf +
+ (CD_FRAMESIZE_RAW
+ * cframe)),
+ (char *)
+ readahead_buffer,
+ CD_FRAMESIZE_RAW);
+ }
+ } else {
+ printk
+ ("CDU31A: Error reading audio data on sector %d: %s\n",
+ ra->addr.lba + cframe,
+ translate_error(res_reg[1]));
+ retval = -EIO;
+ goto exit_read_audio;
+ }
+ } else {
+ copy_to_user((char *) (ra->buf +
+ (CD_FRAMESIZE_RAW *
+ cframe)),
+ (char *) readahead_buffer,
+ CD_FRAMESIZE_RAW);
+ }
+
+ cframe++;
+ }
+
+ get_result(res_reg, &res_size);
+ if ((res_reg[0] & 0xf0) == 0x20) {
+ printk("CDU31A: Error return from audio read: %s\n",
+ translate_error(res_reg[1]));
+ retval = -EIO;
+ goto exit_read_audio;
+ }
+
+ exit_read_audio:
+
+ /* Set the drive mode back to the proper one for the disk. */
+ params[0] = SONY_SD_DECODE_PARAM;
+ if (!sony_xa_mode) {
+ params[1] = 0x0f;
+ } else {
+ params[1] = 0x07;
+ }
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params, 2, res_reg, &res_size);
+ if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk("CDU31A: Unable to reset decode params: 0x%2.2x\n",
+ res_reg[1]);
+ return -EIO;
+ }
+
+ has_cd_task = NULL;
+ sony_inuse = 0;
+ wake_up_interruptible(&sony_wait);
+
+ return (retval);
}
static int
do_sony_cd_cmd_chk(const char *name,
- unsigned char cmd,
- unsigned char *params,
- unsigned int num_params,
- unsigned char *result_buffer,
- unsigned int *result_size)
-{
- do_sony_cd_cmd(cmd, params, num_params, result_buffer, result_size);
- if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20))
- {
- printk("Sony CDROM error %s (CDROM%s)\n", translate_error(result_buffer[1]), name);
- return -EIO;
- }
- return 0;
+ unsigned char cmd,
+ unsigned char *params,
+ unsigned int num_params,
+ unsigned char *result_buffer, unsigned int *result_size)
+{
+ do_sony_cd_cmd(cmd, params, num_params, result_buffer,
+ result_size);
+ if ((*result_size < 2) || ((result_buffer[0] & 0xf0) == 0x20)) {
+ printk("Sony CDROM error %s (CDROM%s)\n",
+ translate_error(result_buffer[1]), name);
+ return -EIO;
+ }
+ return 0;
}
-
+
/*
* Uniform cdrom interface function
* open the tray
*/
static int scd_tray_move(struct cdrom_device_info *cdi, int position)
{
- if (position == 1 /* open tray */)
- {
- unsigned char res_reg[12];
- unsigned int res_size;
-
- do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
- sony_audio_status = CDROM_AUDIO_INVALID;
- return do_sony_cd_cmd_chk("EJECT",SONY_EJECT_CMD, NULL, 0, res_reg, &res_size);
- } else {
- if (0 == scd_spinup())
- sony_spun_up = 1;
- return 0;
- }
+ if (position == 1 /* open tray */ ) {
+ unsigned char res_reg[12];
+ unsigned int res_size;
+
+ do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+ &res_size);
+ do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ sony_audio_status = CDROM_AUDIO_INVALID;
+ return do_sony_cd_cmd_chk("EJECT", SONY_EJECT_CMD, NULL, 0,
+ res_reg, &res_size);
+ } else {
+ if (0 == scd_spinup())
+ sony_spun_up = 1;
+ return 0;
+ }
}
/*
* The big ugly ioctl handler.
*/
static int scd_audio_ioctl(struct cdrom_device_info *cdi,
- unsigned int cmd,
- void * arg)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned char params[7];
- int i;
-
-
- switch (cmd)
- {
- case CDROMSTART: /* Spin up the drive */
- return do_sony_cd_cmd_chk("START",SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
- break;
-
- case CDROMSTOP: /* Spin down the drive */
- do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size);
-
- /*
- * Spin the drive down, ignoring the error if the disk was
- * already not spinning.
- */
- sony_audio_status = CDROM_AUDIO_NO_STATUS;
- return do_sony_cd_cmd_chk("STOP",SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
-
- case CDROMPAUSE: /* Pause the drive */
- if(do_sony_cd_cmd_chk("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg, &res_size))
- return -EIO;
- /* Get the current position and save it for resuming */
- if (read_subcode() < 0)
- {
- return -EIO;
- }
- cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
- cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
- cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
- sony_audio_status = CDROM_AUDIO_PAUSED;
- return 0;
- break;
-
- case CDROMRESUME: /* Start the drive after being paused */
- if (sony_audio_status != CDROM_AUDIO_PAUSED)
- {
- return -EINVAL;
- }
-
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
- /* Start the drive at the saved position. */
- params[1] = int_to_bcd(cur_pos_msf[0]);
- params[2] = int_to_bcd(cur_pos_msf[1]);
- params[3] = int_to_bcd(cur_pos_msf[2]);
- params[4] = int_to_bcd(final_pos_msf[0]);
- params[5] = int_to_bcd(final_pos_msf[1]);
- params[6] = int_to_bcd(final_pos_msf[2]);
- params[0] = 0x03;
- if(do_sony_cd_cmd_chk("RESUME",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
- return -EIO;
- sony_audio_status = CDROM_AUDIO_PLAY;
- return 0;
-
- case CDROMPLAYMSF: /* Play starting at the given MSF address. */
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
- /* The parameters are given in int, must be converted */
- for (i=1; i<7; i++)
- {
- params[i] = int_to_bcd(((unsigned char *)arg)[i-1]);
- }
- params[0] = 0x03;
- if(do_sony_cd_cmd_chk("PLAYMSF",SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size)<0)
- return -EIO;
-
- /* Save the final position for pauses and resumes */
- final_pos_msf[0] = bcd_to_int(params[4]);
- final_pos_msf[1] = bcd_to_int(params[5]);
- final_pos_msf[2] = bcd_to_int(params[6]);
- sony_audio_status = CDROM_AUDIO_PLAY;
- return 0;
-
- case CDROMREADTOCHDR: /* Read the table of contents header */
- {
- struct cdrom_tochdr *hdr;
-
- sony_get_toc();
- if (!sony_toc_read)
- {
- return -EIO;
- }
-
- hdr = (struct cdrom_tochdr *) arg;
- hdr->cdth_trk0 = sony_toc.first_track_num;
- hdr->cdth_trk1 = sony_toc.last_track_num;
- }
- return 0;
-
- case CDROMREADTOCENTRY: /* Read a given table of contents entry */
- {
- struct cdrom_tocentry *entry;
- int track_idx;
- unsigned char *msf_val = NULL;
-
- sony_get_toc();
- if (!sony_toc_read)
- {
- return -EIO;
- }
-
- entry = (struct cdrom_tocentry *) arg;
-
- track_idx = find_track(entry->cdte_track);
- if (track_idx < 0)
- {
- return -EINVAL;
- }
-
- entry->cdte_adr = sony_toc.tracks[track_idx].address;
- entry->cdte_ctrl = sony_toc.tracks[track_idx].control;
- msf_val = sony_toc.tracks[track_idx].track_start_msf;
-
- /* Logical buffer address or MSF format requested? */
- if (entry->cdte_format == CDROM_LBA)
- {
- entry->cdte_addr.lba = msf_to_log(msf_val);
- }
- else if (entry->cdte_format == CDROM_MSF)
- {
- entry->cdte_addr.msf.minute = *msf_val;
- entry->cdte_addr.msf.second = *(msf_val+1);
- entry->cdte_addr.msf.frame = *(msf_val+2);
- }
- }
- return 0;
- break;
-
- case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- {
- struct cdrom_ti *ti = (struct cdrom_ti *) arg;
- int track_idx;
-
- sony_get_toc();
- if (!sony_toc_read)
- {
- return -EIO;
- }
-
- if ( (ti->cdti_trk0 < sony_toc.first_track_num)
- || (ti->cdti_trk0 > sony_toc.last_track_num)
- || (ti->cdti_trk1 < ti->cdti_trk0))
- {
- return -EINVAL;
- }
-
- track_idx = find_track(ti->cdti_trk0);
- if (track_idx < 0)
- {
- return -EINVAL;
- }
- params[1] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[0]);
- params[2] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[1]);
- params[3] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[2]);
-
- /*
- * If we want to stop after the last track, use the lead-out
- * MSF to do that.
- */
- if (ti->cdti_trk1 >= sony_toc.last_track_num)
- {
- track_idx = find_track(CDROM_LEADOUT);
- }
- else
- {
- track_idx = find_track(ti->cdti_trk1+1);
- }
- if (track_idx < 0)
- {
- return -EINVAL;
- }
- params[4] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[0]);
- params[5] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[1]);
- params[6] = int_to_bcd(sony_toc.tracks[track_idx].track_start_msf[2]);
- params[0] = 0x03;
-
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
- do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg, &res_size);
-
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("Params: %x %x %x %x %x %x %x\n", params[0], params[1],
- params[2], params[3], params[4], params[5], params[6]);
- printk("Sony CDROM error %s (CDROMPLAYTRKIND)\n", translate_error(res_reg[1]));
- return -EIO;
- }
-
- /* Save the final position for pauses and resumes */
- final_pos_msf[0] = bcd_to_int(params[4]);
- final_pos_msf[1] = bcd_to_int(params[5]);
- final_pos_msf[2] = bcd_to_int(params[6]);
- sony_audio_status = CDROM_AUDIO_PLAY;
- return 0;
- }
-
- case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
- {
- struct cdrom_volctrl *volctrl = (struct cdrom_volctrl *) arg;
-
- params[0] = SONY_SD_AUDIO_VOLUME;
- params[1] = volctrl->channel0;
- params[2] = volctrl->channel1;
- return do_sony_cd_cmd_chk("VOLCTRL",SONY_SET_DRIVE_PARAM_CMD, params, 3, res_reg, &res_size);
- }
- case CDROMSUBCHNL: /* Get subchannel info */
- return sony_get_subchnl_info((struct cdrom_subchnl *)arg);
-
- default:
- return -EINVAL;
- }
+ unsigned int cmd, void *arg)
+{
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ unsigned char params[7];
+ int i;
+
+
+ switch (cmd) {
+ case CDROMSTART: /* Spin up the drive */
+ return do_sony_cd_cmd_chk("START", SONY_SPIN_UP_CMD, NULL,
+ 0, res_reg, &res_size);
+ break;
+
+ case CDROMSTOP: /* Spin down the drive */
+ do_sony_cd_cmd(SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ /*
+ * Spin the drive down, ignoring the error if the disk was
+ * already not spinning.
+ */
+ sony_audio_status = CDROM_AUDIO_NO_STATUS;
+ return do_sony_cd_cmd_chk("STOP", SONY_SPIN_DOWN_CMD, NULL,
+ 0, res_reg, &res_size);
+
+ case CDROMPAUSE: /* Pause the drive */
+ if (do_sony_cd_cmd_chk
+ ("PAUSE", SONY_AUDIO_STOP_CMD, NULL, 0, res_reg,
+ &res_size))
+ return -EIO;
+ /* Get the current position and save it for resuming */
+ if (read_subcode() < 0) {
+ return -EIO;
+ }
+ cur_pos_msf[0] = last_sony_subcode.abs_msf[0];
+ cur_pos_msf[1] = last_sony_subcode.abs_msf[1];
+ cur_pos_msf[2] = last_sony_subcode.abs_msf[2];
+ sony_audio_status = CDROM_AUDIO_PAUSED;
+ return 0;
+ break;
+
+ case CDROMRESUME: /* Start the drive after being paused */
+ if (sony_audio_status != CDROM_AUDIO_PAUSED) {
+ return -EINVAL;
+ }
+
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ /* Start the drive at the saved position. */
+ params[1] = int_to_bcd(cur_pos_msf[0]);
+ params[2] = int_to_bcd(cur_pos_msf[1]);
+ params[3] = int_to_bcd(cur_pos_msf[2]);
+ params[4] = int_to_bcd(final_pos_msf[0]);
+ params[5] = int_to_bcd(final_pos_msf[1]);
+ params[6] = int_to_bcd(final_pos_msf[2]);
+ params[0] = 0x03;
+ if (do_sony_cd_cmd_chk
+ ("RESUME", SONY_AUDIO_PLAYBACK_CMD, params, 7, res_reg,
+ &res_size) < 0)
+ return -EIO;
+ sony_audio_status = CDROM_AUDIO_PLAY;
+ return 0;
+
+ case CDROMPLAYMSF: /* Play starting at the given MSF address. */
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ /* The parameters are given in int, must be converted */
+ for (i = 1; i < 7; i++) {
+ params[i] =
+ int_to_bcd(((unsigned char *) arg)[i - 1]);
+ }
+ params[0] = 0x03;
+ if (do_sony_cd_cmd_chk
+ ("PLAYMSF", SONY_AUDIO_PLAYBACK_CMD, params, 7,
+ res_reg, &res_size) < 0)
+ return -EIO;
+
+ /* Save the final position for pauses and resumes */
+ final_pos_msf[0] = bcd_to_int(params[4]);
+ final_pos_msf[1] = bcd_to_int(params[5]);
+ final_pos_msf[2] = bcd_to_int(params[6]);
+ sony_audio_status = CDROM_AUDIO_PLAY;
+ return 0;
+
+ case CDROMREADTOCHDR: /* Read the table of contents header */
+ {
+ struct cdrom_tochdr *hdr;
+
+ sony_get_toc();
+ if (!sony_toc_read) {
+ return -EIO;
+ }
+
+ hdr = (struct cdrom_tochdr *) arg;
+ hdr->cdth_trk0 = sony_toc.first_track_num;
+ hdr->cdth_trk1 = sony_toc.last_track_num;
+ }
+ return 0;
+
+ case CDROMREADTOCENTRY: /* Read a given table of contents entry */
+ {
+ struct cdrom_tocentry *entry;
+ int track_idx;
+ unsigned char *msf_val = NULL;
+
+ sony_get_toc();
+ if (!sony_toc_read) {
+ return -EIO;
+ }
+
+ entry = (struct cdrom_tocentry *) arg;
+
+ track_idx = find_track(entry->cdte_track);
+ if (track_idx < 0) {
+ return -EINVAL;
+ }
+
+ entry->cdte_adr =
+ sony_toc.tracks[track_idx].address;
+ entry->cdte_ctrl =
+ sony_toc.tracks[track_idx].control;
+ msf_val =
+ sony_toc.tracks[track_idx].track_start_msf;
+
+ /* Logical buffer address or MSF format requested? */
+ if (entry->cdte_format == CDROM_LBA) {
+ entry->cdte_addr.lba = msf_to_log(msf_val);
+ } else if (entry->cdte_format == CDROM_MSF) {
+ entry->cdte_addr.msf.minute = *msf_val;
+ entry->cdte_addr.msf.second =
+ *(msf_val + 1);
+ entry->cdte_addr.msf.frame =
+ *(msf_val + 2);
+ }
+ }
+ return 0;
+ break;
+
+ case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
+ {
+ struct cdrom_ti *ti = (struct cdrom_ti *) arg;
+ int track_idx;
+
+ sony_get_toc();
+ if (!sony_toc_read) {
+ return -EIO;
+ }
+
+ if ((ti->cdti_trk0 < sony_toc.first_track_num)
+ || (ti->cdti_trk0 > sony_toc.last_track_num)
+ || (ti->cdti_trk1 < ti->cdti_trk0)) {
+ return -EINVAL;
+ }
+
+ track_idx = find_track(ti->cdti_trk0);
+ if (track_idx < 0) {
+ return -EINVAL;
+ }
+ params[1] =
+ int_to_bcd(sony_toc.tracks[track_idx].
+ track_start_msf[0]);
+ params[2] =
+ int_to_bcd(sony_toc.tracks[track_idx].
+ track_start_msf[1]);
+ params[3] =
+ int_to_bcd(sony_toc.tracks[track_idx].
+ track_start_msf[2]);
+
+ /*
+ * If we want to stop after the last track, use the lead-out
+ * MSF to do that.
+ */
+ if (ti->cdti_trk1 >= sony_toc.last_track_num) {
+ track_idx = find_track(CDROM_LEADOUT);
+ } else {
+ track_idx = find_track(ti->cdti_trk1 + 1);
+ }
+ if (track_idx < 0) {
+ return -EINVAL;
+ }
+ params[4] =
+ int_to_bcd(sony_toc.tracks[track_idx].
+ track_start_msf[0]);
+ params[5] =
+ int_to_bcd(sony_toc.tracks[track_idx].
+ track_start_msf[1]);
+ params[6] =
+ int_to_bcd(sony_toc.tracks[track_idx].
+ track_start_msf[2]);
+ params[0] = 0x03;
+
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
+ &res_size);
+
+ do_sony_cd_cmd(SONY_AUDIO_PLAYBACK_CMD, params, 7,
+ res_reg, &res_size);
+
+ if ((res_size < 2)
+ || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk("Params: %x %x %x %x %x %x %x\n",
+ params[0], params[1], params[2],
+ params[3], params[4], params[5],
+ params[6]);
+ printk
+ ("Sony CDROM error %s (CDROMPLAYTRKIND)\n",
+ translate_error(res_reg[1]));
+ return -EIO;
+ }
+
+ /* Save the final position for pauses and resumes */
+ final_pos_msf[0] = bcd_to_int(params[4]);
+ final_pos_msf[1] = bcd_to_int(params[5]);
+ final_pos_msf[2] = bcd_to_int(params[6]);
+ sony_audio_status = CDROM_AUDIO_PLAY;
+ return 0;
+ }
+
+ case CDROMVOLCTRL: /* Volume control. What volume does this change, anyway? */
+ {
+ struct cdrom_volctrl *volctrl =
+ (struct cdrom_volctrl *) arg;
+
+ params[0] = SONY_SD_AUDIO_VOLUME;
+ params[1] = volctrl->channel0;
+ params[2] = volctrl->channel1;
+ return do_sony_cd_cmd_chk("VOLCTRL",
+ SONY_SET_DRIVE_PARAM_CMD,
+ params, 3, res_reg,
+ &res_size);
+ }
+ case CDROMSUBCHNL: /* Get subchannel info */
+ return sony_get_subchnl_info((struct cdrom_subchnl *) arg);
+
+ default:
+ return -EINVAL;
+ }
}
static int scd_dev_ioctl(struct cdrom_device_info *cdi,
- unsigned int cmd,
- unsigned long arg)
-{
- int i;
-
- switch (cmd)
- {
- case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte
- raw data tracks. */
- {
- struct cdrom_read_audio ra;
-
-
- sony_get_toc();
- if (!sony_toc_read)
- {
- return -EIO;
- }
-
- if(copy_from_user(&ra, (char *) arg, sizeof(ra)))
- return -EFAULT;
-
- if (ra.nframes == 0)
- {
- return 0;
- }
-
- i=verify_area(VERIFY_WRITE, ra.buf, CD_FRAMESIZE_RAW * ra.nframes);
- if(i<0)
- return i;
-
- if (ra.addr_format == CDROM_LBA)
- {
- if ( (ra.addr.lba >= sony_toc.lead_out_start_lba)
- || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
- {
- return -EINVAL;
- }
- }
- else if (ra.addr_format == CDROM_MSF)
- {
- if ( (ra.addr.msf.minute >= 75)
- || (ra.addr.msf.second >= 60)
- || (ra.addr.msf.frame >= 75))
- {
- return -EINVAL;
- }
-
- ra.addr.lba = ( (ra.addr.msf.minute * 4500)
- + (ra.addr.msf.second * 75)
- + ra.addr.msf.frame);
- if ( (ra.addr.lba >= sony_toc.lead_out_start_lba)
- || (ra.addr.lba + ra.nframes >= sony_toc.lead_out_start_lba))
- {
- return -EINVAL;
- }
-
- /* I know, this can go negative on an unsigned. However,
- the first thing done to the data is to add this value,
- so this should compensate and allow direct msf access. */
- ra.addr.lba -= LOG_START_OFFSET;
- }
- else
- {
- return -EINVAL;
- }
-
- return(read_audio(&ra));
- }
- return 0;
- break;
-
- default:
- return -EINVAL;
- }
+ unsigned int cmd, unsigned long arg)
+{
+ int i;
+
+ switch (cmd) {
+ case CDROMREADAUDIO: /* Read 2352 byte audio tracks and 2340 byte
+ raw data tracks. */
+ {
+ struct cdrom_read_audio ra;
+
+
+ sony_get_toc();
+ if (!sony_toc_read) {
+ return -EIO;
+ }
+
+ if (copy_from_user(&ra, (char *) arg, sizeof(ra)))
+ return -EFAULT;
+
+ if (ra.nframes == 0) {
+ return 0;
+ }
+
+ i = verify_area(VERIFY_WRITE, ra.buf,
+ CD_FRAMESIZE_RAW * ra.nframes);
+ if (i < 0)
+ return i;
+
+ if (ra.addr_format == CDROM_LBA) {
+ if ((ra.addr.lba >=
+ sony_toc.lead_out_start_lba)
+ || (ra.addr.lba + ra.nframes >=
+ sony_toc.lead_out_start_lba)) {
+ return -EINVAL;
+ }
+ } else if (ra.addr_format == CDROM_MSF) {
+ if ((ra.addr.msf.minute >= 75)
+ || (ra.addr.msf.second >= 60)
+ || (ra.addr.msf.frame >= 75)) {
+ return -EINVAL;
+ }
+
+ ra.addr.lba = ((ra.addr.msf.minute * 4500)
+ + (ra.addr.msf.second * 75)
+ + ra.addr.msf.frame);
+ if ((ra.addr.lba >=
+ sony_toc.lead_out_start_lba)
+ || (ra.addr.lba + ra.nframes >=
+ sony_toc.lead_out_start_lba)) {
+ return -EINVAL;
+ }
+
+ /* I know, this can go negative on an unsigned. However,
+ the first thing done to the data is to add this value,
+ so this should compensate and allow direct msf access. */
+ ra.addr.lba -= LOG_START_OFFSET;
+ } else {
+ return -EINVAL;
+ }
+
+ return (read_audio(&ra));
+ }
+ return 0;
+ break;
+
+ default:
+ return -EINVAL;
+ }
}
static int scd_spinup(void)
{
- unsigned char res_reg[12];
- unsigned int res_size;
- int num_spin_ups;
-
- num_spin_ups = 0;
-
-respinup_on_open:
- do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
-
- /* The drive sometimes returns error 0. I don't know why, but ignore
- it. It seems to mean the drive has already done the operation. */
- if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
- {
- printk("Sony CDROM %s error (scd_open, spin up)\n", translate_error(res_reg[1]));
- return 1;
- }
-
- do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
-
- /* The drive sometimes returns error 0. I don't know why, but ignore
- it. It seems to mean the drive has already done the operation. */
- if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0)))
- {
- /* If the drive is already playing, it's ok. */
- if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR) || (res_reg[1] == 0))
- {
- return 0;
- }
-
- /* If the drive says it is not spun up (even though we just did it!)
- then retry the operation at least a few times. */
- if ( (res_reg[1] == SONY_NOT_SPIN_ERR)
- && (num_spin_ups < MAX_CDU31A_RETRIES))
- {
- num_spin_ups++;
- goto respinup_on_open;
- }
-
- printk("Sony CDROM error %s (scd_open, read toc)\n", translate_error(res_reg[1]));
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
- return 1;
- }
- return 0;
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ int num_spin_ups;
+
+ num_spin_ups = 0;
+
+ respinup_on_open:
+ do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
+
+ /* The drive sometimes returns error 0. I don't know why, but ignore
+ it. It seems to mean the drive has already done the operation. */
+ if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+ printk("Sony CDROM %s error (scd_open, spin up)\n",
+ translate_error(res_reg[1]));
+ return 1;
+ }
+
+ do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
+
+ /* The drive sometimes returns error 0. I don't know why, but ignore
+ it. It seems to mean the drive has already done the operation. */
+ if ((res_size < 2) || ((res_reg[0] != 0) && (res_reg[1] != 0))) {
+ /* If the drive is already playing, it's ok. */
+ if ((res_reg[1] == SONY_AUDIO_PLAYING_ERR)
+ || (res_reg[1] == 0)) {
+ return 0;
+ }
+
+ /* If the drive says it is not spun up (even though we just did it!)
+ then retry the operation at least a few times. */
+ if ((res_reg[1] == SONY_NOT_SPIN_ERR)
+ && (num_spin_ups < MAX_CDU31A_RETRIES)) {
+ num_spin_ups++;
+ goto respinup_on_open;
+ }
+
+ printk("Sony CDROM error %s (scd_open, read toc)\n",
+ translate_error(res_reg[1]));
+ do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+ &res_size);
+ return 1;
+ }
+ return 0;
}
/*
* Open the drive for operations. Spin the drive up and read the table of
* contents if these have not already been done.
*/
-static int
-scd_open(struct cdrom_device_info *cdi, int openmode)
-{
- unsigned char res_reg[12];
- unsigned int res_size;
- unsigned char params[2];
-
- MOD_INC_USE_COUNT;
- if (sony_usage == 0)
- {
- if (scd_spinup() != 0) {
- MOD_DEC_USE_COUNT;
- return -EIO;
- }
- sony_get_toc();
- if (!sony_toc_read)
- {
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
- MOD_DEC_USE_COUNT;
- return -EIO;
- }
-
- /* For XA on the CDU31A only, we have to do special reads.
- The CDU33A handles XA automagically. */
- /* if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
- if ( (sony_toc.disk_type != 0x00)
- && (!is_double_speed))
- {
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x07;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("CDU31A: Unable to set XA params: 0x%2.2x\n", res_reg[1]);
- }
- sony_xa_mode = 1;
- }
- /* A non-XA disk. Set the parms back if necessary. */
- else if (sony_xa_mode)
- {
- params[0] = SONY_SD_DECODE_PARAM;
- params[1] = 0x0f;
- do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
- params,
- 2,
- res_reg,
- &res_size);
- if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
- {
- printk("CDU31A: Unable to reset XA params: 0x%2.2x\n", res_reg[1]);
- }
- sony_xa_mode = 0;
- }
-
- sony_spun_up = 1;
- }
-
- sony_usage++;
-
- return 0;
+static int scd_open(struct cdrom_device_info *cdi, int openmode)
+{
+ unsigned char res_reg[12];
+ unsigned int res_size;
+ unsigned char params[2];
+
+ MOD_INC_USE_COUNT;
+ if (sony_usage == 0) {
+ if (scd_spinup() != 0) {
+ MOD_DEC_USE_COUNT;
+ return -EIO;
+ }
+ sony_get_toc();
+ if (!sony_toc_read) {
+ do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0,
+ res_reg, &res_size);
+ MOD_DEC_USE_COUNT;
+ return -EIO;
+ }
+
+ /* For XA on the CDU31A only, we have to do special reads.
+ The CDU33A handles XA automagically. */
+ /* if ( (sony_toc.disk_type == SONY_XA_DISK_TYPE) */
+ if ((sony_toc.disk_type != 0x00)
+ && (!is_double_speed)) {
+ params[0] = SONY_SD_DECODE_PARAM;
+ params[1] = 0x07;
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params, 2, res_reg, &res_size);
+ if ((res_size < 2)
+ || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk
+ ("CDU31A: Unable to set XA params: 0x%2.2x\n",
+ res_reg[1]);
+ }
+ sony_xa_mode = 1;
+ }
+ /* A non-XA disk. Set the parms back if necessary. */
+ else if (sony_xa_mode) {
+ params[0] = SONY_SD_DECODE_PARAM;
+ params[1] = 0x0f;
+ do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
+ params, 2, res_reg, &res_size);
+ if ((res_size < 2)
+ || ((res_reg[0] & 0xf0) == 0x20)) {
+ printk
+ ("CDU31A: Unable to reset XA params: 0x%2.2x\n",
+ res_reg[1]);
+ }
+ sony_xa_mode = 0;
+ }
+
+ sony_spun_up = 1;
+ }
+
+ sony_usage++;
+
+ return 0;
}
* Close the drive. Spin it down if no task is using it. The spin
* down will fail if playing audio, so audio play is OK.
*/
-static void
-scd_release(struct cdrom_device_info *cdi)
+static void scd_release(struct cdrom_device_info *cdi)
{
- if (sony_usage == 1)
- {
- unsigned char res_reg[12];
- unsigned int res_size;
+ if (sony_usage == 1) {
+ unsigned char res_reg[12];
+ unsigned int res_size;
- do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg, &res_size);
+ do_sony_cd_cmd(SONY_SPIN_DOWN_CMD, NULL, 0, res_reg,
+ &res_size);
- sony_spun_up = 0;
- }
- sony_usage--;
- MOD_DEC_USE_COUNT;
+ sony_spun_up = 0;
+ }
+ sony_usage--;
+ MOD_DEC_USE_COUNT;
}
static struct cdrom_device_ops scd_dops = {
- open: scd_open,
- release: scd_release,
- drive_status: scd_drive_status,
- media_changed: scd_media_changed,
- tray_move: scd_tray_move,
- lock_door: scd_lock_door,
- select_speed: scd_select_speed,
- get_last_session: scd_get_last_session,
- get_mcn: scd_get_mcn,
- reset: scd_reset,
- audio_ioctl: scd_audio_ioctl,
- dev_ioctl: scd_dev_ioctl,
- capability: CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
- CDC_SELECT_SPEED | CDC_MULTI_SESSION |
- CDC_MULTI_SESSION | CDC_MCN |
- CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
- CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
- n_minors: 1,
+ open:scd_open,
+ release:scd_release,
+ drive_status:scd_drive_status,
+ media_changed:scd_media_changed,
+ tray_move:scd_tray_move,
+ lock_door:scd_lock_door,
+ select_speed:scd_select_speed,
+ get_last_session:scd_get_last_session,
+ get_mcn:scd_get_mcn,
+ reset:scd_reset,
+ audio_ioctl:scd_audio_ioctl,
+ dev_ioctl:scd_dev_ioctl,
+ capability:CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK |
+ CDC_SELECT_SPEED | CDC_MULTI_SESSION |
+ CDC_MULTI_SESSION | CDC_MCN |
+ CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO |
+ CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS,
+ n_minors:1,
};
static struct cdrom_device_info scd_info = {
- ops: &scd_dops,
- speed: 2,
- capacity: 1,
- name: "cdu31a"
+ ops:&scd_dops,
+ speed:2,
+ capacity:1,
+ name:"cdu31a"
};
/* The different types of disc loading mechanisms supported */
-static const char *load_mech[] __initdata = { "caddy", "tray", "pop-up", "unknown" };
+static char *load_mech[] __initdata =
+ { "caddy", "tray", "pop-up", "unknown" };
-static void __init
+static void __init
get_drive_configuration(unsigned short base_io,
- unsigned char res_reg[],
- unsigned int *res_size)
-{
- int retry_count;
-
-
- /* Set the base address */
- cdu31a_port = base_io;
-
- /* Set up all the register locations */
- sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
- sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
- sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
- sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
- sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
- sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
- sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
- sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
-
- /*
- * Check to see if anything exists at the status register location.
- * I don't know if this is a good way to check, but it seems to work
- * ok for me.
- */
- if (read_status_register() != 0xff)
- {
- /*
- * Reset the drive and wait for attention from it (to say it's reset).
- * If you don't wait, the next operation will probably fail.
- */
- reset_drive();
- retry_count = jiffies + SONY_RESET_TIMEOUT;
- while (time_before(jiffies, retry_count) && (!is_attention()))
- {
- sony_sleep();
- }
+ unsigned char res_reg[], unsigned int *res_size)
+{
+ int retry_count;
+
+
+ /* Set the base address */
+ cdu31a_port = base_io;
+
+ /* Set up all the register locations */
+ sony_cd_cmd_reg = cdu31a_port + SONY_CMD_REG_OFFSET;
+ sony_cd_param_reg = cdu31a_port + SONY_PARAM_REG_OFFSET;
+ sony_cd_write_reg = cdu31a_port + SONY_WRITE_REG_OFFSET;
+ sony_cd_control_reg = cdu31a_port + SONY_CONTROL_REG_OFFSET;
+ sony_cd_status_reg = cdu31a_port + SONY_STATUS_REG_OFFSET;
+ sony_cd_result_reg = cdu31a_port + SONY_RESULT_REG_OFFSET;
+ sony_cd_read_reg = cdu31a_port + SONY_READ_REG_OFFSET;
+ sony_cd_fifost_reg = cdu31a_port + SONY_FIFOST_REG_OFFSET;
+
+ /*
+ * Check to see if anything exists at the status register location.
+ * I don't know if this is a good way to check, but it seems to work
+ * ok for me.
+ */
+ if (read_status_register() != 0xff) {
+ /*
+ * Reset the drive and wait for attention from it (to say it's reset).
+ * If you don't wait, the next operation will probably fail.
+ */
+ reset_drive();
+ retry_count = jiffies + SONY_RESET_TIMEOUT;
+ while (time_before(jiffies, retry_count)
+ && (!is_attention())) {
+ sony_sleep();
+ }
#if 0
- /* If attention is never seen probably not a CDU31a present */
- if (!is_attention())
- {
- res_reg[0] = 0x20;
- return;
- }
+ /* If attention is never seen probably not a CDU31a present */
+ if (!is_attention()) {
+ res_reg[0] = 0x20;
+ return;
+ }
#endif
- /*
- * Get the drive configuration.
- */
- do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
- NULL,
- 0,
- (unsigned char *) res_reg,
- res_size);
- return;
- }
-
- /* Return an error */
- res_reg[0] = 0x20;
+ /*
+ * Get the drive configuration.
+ */
+ do_sony_cd_cmd(SONY_REQ_DRIVE_CONFIG_CMD,
+ NULL,
+ 0, (unsigned char *) res_reg, res_size);
+ return;
+ }
+
+ /* Return an error */
+ res_reg[0] = 0x20;
}
#ifndef MODULE
*/
-static int __init cdu31a_setup(char *strings)
-{
- int ints[4];
-
- (void)get_options(strings, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0)
- {
- cdu31a_port = ints[1];
- }
- if (ints[0] > 1)
- {
- cdu31a_irq = ints[2];
- }
- if ((strings != NULL) && (*strings != '\0'))
- {
- if (strcmp(strings, "PAS") == 0)
- {
- sony_pas_init = 1;
- }
- else
- {
- printk("CDU31A: Unknown interface type: %s\n", strings);
- }
- }
-
- return 1;
+static int __init cdu31a_setup(char *strings)
+{
+ int ints[4];
+
+ (void) get_options(strings, ARRAY_SIZE(ints), ints);
+
+ if (ints[0] > 0) {
+ cdu31a_port = ints[1];
+ }
+ if (ints[0] > 1) {
+ cdu31a_irq = ints[2];
+ }
+ if ((strings != NULL) && (*strings != '\0')) {
+ if (strcmp(strings, "PAS") == 0) {
+ sony_pas_init = 1;
+ } else {
+ printk("CDU31A: Unknown interface type: %s\n",
+ strings);
+ }
+ }
+
+ return 1;
}
__setup("cdu31a=", cdu31a_setup);
/*
* Initialize the driver.
*/
-int __init
-cdu31a_init(void)
-{
- struct s_sony_drive_config drive_config;
- unsigned int res_size;
- char msg[255];
- char buf[40];
- int i;
- int drive_found;
- int tmp_irq;
-
-
- /*
- * According to Alex Freed (freed@europa.orion.adobe.com), this is
- * required for the Fusion CD-16 package. If the sound driver is
- * loaded, it should work fine, but just in case...
- *
- * The following turn on the CD-ROM interface for a Fusion CD-16.
- */
- if (sony_pas_init)
- {
- outb(0xbc, 0x9a01);
- outb(0xe2, 0x9a01);
- }
-
- drive_found = 0;
-
- /* Setting the base I/O address to 0xffff will disable it. */
- if (cdu31a_port == 0xffff)
- {
- }
- else if (cdu31a_port != 0)
- {
- tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
- cdu31a_irq = 0;
-
- get_drive_configuration(cdu31a_port,
- drive_config.exec_status,
- &res_size);
- if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
- {
- drive_found = 1;
- }
-
- cdu31a_irq = tmp_irq;
- }
- else
- {
- cdu31a_irq = 0;
- i = 0;
- while ( (cdu31a_addresses[i].base != 0)
- && (!drive_found))
- {
- if (check_region(cdu31a_addresses[i].base, 4)) {
- i++;
- continue;
- }
- get_drive_configuration(cdu31a_addresses[i].base,
- drive_config.exec_status,
- &res_size);
- if ((res_size > 2) && ((drive_config.exec_status[0] & 0xf0) == 0x00))
- {
- drive_found = 1;
- cdu31a_irq = cdu31a_addresses[i].int_num;
- }
- else
- {
- i++;
- }
- }
- }
-
- if (drive_found)
- {
- int deficiency=0;
-
- request_region(cdu31a_port, 4,"cdu31a");
-
- if (devfs_register_blkdev(MAJOR_NR,"cdu31a",&cdrom_fops))
- {
- printk("Unable to get major %d for CDU-31a\n", MAJOR_NR);
- goto errout2;
- }
-
- if (SONY_HWC_DOUBLE_SPEED(drive_config))
- {
- is_double_speed = 1;
- }
-
- tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
- cdu31a_irq = 0;
-
- set_drive_params(sony_speed);
-
- cdu31a_irq = tmp_irq;
-
- if (cdu31a_irq > 0)
- {
- if (request_irq(cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT, "cdu31a", NULL))
- {
- printk("Unable to grab IRQ%d for the CDU31A driver\n", cdu31a_irq);
- cdu31a_irq = 0;
- }
- }
-
- sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
- drive_config.vendor_id,
- drive_config.product_id,
- drive_config.product_rev_level);
- sprintf(buf, " Capabilities: %s",
- load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
- strcat(msg, buf);
- if (SONY_HWC_AUDIO_PLAYBACK(drive_config))
- {
- strcat(msg, ", audio");
- } else
- deficiency |= CDC_PLAY_AUDIO;
- if (SONY_HWC_EJECT(drive_config))
- {
- strcat(msg, ", eject");
- } else
- deficiency |= CDC_OPEN_TRAY;
- if (SONY_HWC_LED_SUPPORT(drive_config))
- {
- strcat(msg, ", LED");
- }
- if (SONY_HWC_ELECTRIC_VOLUME(drive_config))
- {
- strcat(msg, ", elec. Vol");
- }
- if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config))
- {
- strcat(msg, ", sep. Vol");
- }
- if (is_double_speed)
- {
- strcat(msg, ", double speed");
- } else
- deficiency |= CDC_SELECT_SPEED;
- if (cdu31a_irq > 0)
- {
- sprintf(buf, ", irq %d", cdu31a_irq);
- strcat(msg, buf);
- }
- strcat(msg, "\n");
-
- is_a_cdu31a = strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
-
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
- read_ahead[MAJOR_NR] = CDU31A_READAHEAD;
- cdu31a_block_size = 1024; /* 1kB default block size */
- /* use 'mount -o block=2048' */
- blksize_size[MAJOR_NR] = &cdu31a_block_size;
-
- init_timer(&cdu31a_abort_timer);
- cdu31a_abort_timer.function = handle_abort_timeout;
-
- scd_info.dev = MKDEV(MAJOR_NR,0);
- scd_info.mask = deficiency;
- strncpy(scd_info.name, "cdu31a", sizeof(scd_info.name));
-
- if (register_cdrom(&scd_info))
- {
- goto errout0;
- }
- }
-
-
- disk_changed = 1;
-
- if (drive_found)
- {
- return(0);
- }
- else
- {
- goto errout3;
- }
-errout0:
- printk("Unable to register CDU-31a with Uniform cdrom driver\n");
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- if (devfs_unregister_blkdev(MAJOR_NR, "cdu31a"))
- {
- printk("Can't unregister block device for cdu31a\n");
- }
-errout2:
- release_region(cdu31a_port,4);
-errout3:
- return -EIO;
-}
-
-
-void __exit
-cdu31a_exit(void)
-{
- if (unregister_cdrom(&scd_info))
- {
- printk("Can't unregister cdu31a from Uniform cdrom driver\n");
- return;
- }
- if ((devfs_unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL))
- {
- printk("Can't unregister cdu31a\n");
- return;
- }
-
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-
- if (cdu31a_irq > 0)
- free_irq(cdu31a_irq, NULL);
-
- release_region(cdu31a_port,4);
- printk(KERN_INFO "cdu31a module released.\n");
-}
+int __init cdu31a_init(void)
+{
+ struct s_sony_drive_config drive_config;
+ unsigned int res_size;
+ char msg[255];
+ char buf[40];
+ int i;
+ int drive_found;
+ int tmp_irq;
+
+
+ /*
+ * According to Alex Freed (freed@europa.orion.adobe.com), this is
+ * required for the Fusion CD-16 package. If the sound driver is
+ * loaded, it should work fine, but just in case...
+ *
+ * The following turn on the CD-ROM interface for a Fusion CD-16.
+ */
+ if (sony_pas_init) {
+ outb(0xbc, 0x9a01);
+ outb(0xe2, 0x9a01);
+ }
+
+ drive_found = 0;
+
+ /* Setting the base I/O address to 0xffff will disable it. */
+ if (cdu31a_port == 0xffff) {
+ } else if (cdu31a_port != 0) {
+ tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
+ cdu31a_irq = 0;
+
+ get_drive_configuration(cdu31a_port,
+ drive_config.exec_status,
+ &res_size);
+ if ((res_size > 2)
+ && ((drive_config.exec_status[0] & 0xf0) == 0x00)) {
+ drive_found = 1;
+ }
+
+ cdu31a_irq = tmp_irq;
+ } else {
+ cdu31a_irq = 0;
+ i = 0;
+ while ((cdu31a_addresses[i].base != 0)
+ && (!drive_found)) {
+ if (check_region(cdu31a_addresses[i].base, 4)) {
+ i++;
+ continue;
+ }
+ get_drive_configuration(cdu31a_addresses[i].base,
+ drive_config.exec_status,
+ &res_size);
+ if ((res_size > 2)
+ && ((drive_config.exec_status[0] & 0xf0) ==
+ 0x00)) {
+ drive_found = 1;
+ cdu31a_irq = cdu31a_addresses[i].int_num;
+ } else {
+ i++;
+ }
+ }
+ }
+
+ if (drive_found) {
+ int deficiency = 0;
+
+ request_region(cdu31a_port, 4, "cdu31a");
+
+ if (devfs_register_blkdev(MAJOR_NR, "cdu31a", &cdrom_fops)) {
+ printk("Unable to get major %d for CDU-31a\n",
+ MAJOR_NR);
+ goto errout2;
+ }
+
+ if (SONY_HWC_DOUBLE_SPEED(drive_config)) {
+ is_double_speed = 1;
+ }
+
+ tmp_irq = cdu31a_irq; /* Need IRQ 0 because we can't sleep here. */
+ cdu31a_irq = 0;
+
+ set_drive_params(sony_speed);
+
+ cdu31a_irq = tmp_irq;
+
+ if (cdu31a_irq > 0) {
+ if (request_irq
+ (cdu31a_irq, cdu31a_interrupt, SA_INTERRUPT,
+ "cdu31a", NULL)) {
+ printk
+ ("Unable to grab IRQ%d for the CDU31A driver\n",
+ cdu31a_irq);
+ cdu31a_irq = 0;
+ }
+ }
+
+ sprintf(msg, "Sony I/F CDROM : %8.8s %16.16s %8.8s\n",
+ drive_config.vendor_id,
+ drive_config.product_id,
+ drive_config.product_rev_level);
+ sprintf(buf, " Capabilities: %s",
+ load_mech[SONY_HWC_GET_LOAD_MECH(drive_config)]);
+ strcat(msg, buf);
+ if (SONY_HWC_AUDIO_PLAYBACK(drive_config)) {
+ strcat(msg, ", audio");
+ } else
+ deficiency |= CDC_PLAY_AUDIO;
+ if (SONY_HWC_EJECT(drive_config)) {
+ strcat(msg, ", eject");
+ } else
+ deficiency |= CDC_OPEN_TRAY;
+ if (SONY_HWC_LED_SUPPORT(drive_config)) {
+ strcat(msg, ", LED");
+ }
+ if (SONY_HWC_ELECTRIC_VOLUME(drive_config)) {
+ strcat(msg, ", elec. Vol");
+ }
+ if (SONY_HWC_ELECTRIC_VOLUME_CTL(drive_config)) {
+ strcat(msg, ", sep. Vol");
+ }
+ if (is_double_speed) {
+ strcat(msg, ", double speed");
+ } else
+ deficiency |= CDC_SELECT_SPEED;
+ if (cdu31a_irq > 0) {
+ sprintf(buf, ", irq %d", cdu31a_irq);
+ strcat(msg, buf);
+ }
+ strcat(msg, "\n");
+
+ is_a_cdu31a =
+ strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR),
+ DEVICE_REQUEST);
+ read_ahead[MAJOR_NR] = CDU31A_READAHEAD;
+ cdu31a_block_size = 1024; /* 1kB default block size */
+ /* use 'mount -o block=2048' */
+ blksize_size[MAJOR_NR] = &cdu31a_block_size;
+
+ init_timer(&cdu31a_abort_timer);
+ cdu31a_abort_timer.function = handle_abort_timeout;
+
+ scd_info.dev = MKDEV(MAJOR_NR, 0);
+ scd_info.mask = deficiency;
+ strncpy(scd_info.name, "cdu31a", sizeof(scd_info.name));
+
+ if (register_cdrom(&scd_info)) {
+ goto errout0;
+ }
+ }
+
+
+ disk_changed = 1;
+
+ if (drive_found) {
+ return (0);
+ } else {
+ goto errout3;
+ }
+ errout0:
+ printk("Unable to register CDU-31a with Uniform cdrom driver\n");
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ if (devfs_unregister_blkdev(MAJOR_NR, "cdu31a")) {
+ printk("Can't unregister block device for cdu31a\n");
+ }
+ errout2:
+ release_region(cdu31a_port, 4);
+ errout3:
+ return -EIO;
+}
+
+
+void __exit cdu31a_exit(void)
+{
+ if (unregister_cdrom(&scd_info)) {
+ printk
+ ("Can't unregister cdu31a from Uniform cdrom driver\n");
+ return;
+ }
+ if ((devfs_unregister_blkdev(MAJOR_NR, "cdu31a") == -EINVAL)) {
+ printk("Can't unregister cdu31a\n");
+ return;
+ }
+
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+
+ if (cdu31a_irq > 0)
+ free_irq(cdu31a_irq, NULL);
+
+ release_region(cdu31a_port, 4);
+ printk(KERN_INFO "cdu31a module released.\n");
+}
#ifdef MODULE
module_init(cdu31a_init);
#endif
module_exit(cdu31a_exit);
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
* David van Leeuwen, david@tm.tno.nl. */
#define REVISION "$Revision: 1.5 $"
-#include <linux/module.h>
+#include <linux/module.h>
#include <linux/errno.h> /* These include what we really need */
#include <linux/delay.h>
address and interrupt request. It can be overridden by the boot
parameter `auto'.
*/
-static int auto_probe=1; /* Yes, why not? */
+static int auto_probe = 1; /* Yes, why not? */
static int cm206_base = CM206_BASE;
-static int cm206_irq = CM206_IRQ;
-static int cm206[2] = {0,0}; /* for compatible `insmod' parameter passing */
+static int cm206_irq = CM206_IRQ;
+#ifdef MODULE
+static int cm206[2] = { 0, 0 }; /* for compatible `insmod' parameter passing */
+#endif
MODULE_PARM(cm206_base, "i"); /* base */
MODULE_PARM(cm206_irq, "i"); /* irq */
MODULE_PARM(cm206, "1-2i"); /* base,irq or irq,base */
MODULE_PARM(auto_probe, "i"); /* auto probe base and irq */
+MODULE_LICENSE("GPL");
#define POLLOOP 100 /* milliseconds */
#define READ_AHEAD 1 /* defines private buffer, waste! */
#define LINUX_BLOCK_SIZE 512 /* WHERE is this defined? */
#define RAW_SECTOR_SIZE 2352 /* ok, is also defined in cdrom.h */
#define ISO_SECTOR_SIZE 2048
-#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
+#define BLOCKS_ISO (ISO_SECTOR_SIZE/LINUX_BLOCK_SIZE) /* 4 */
#define CD_SYNC_HEAD 16 /* CD_SYNC + CD_HEAD */
#ifdef STATISTICS /* keep track of errors in counters */
typedef unsigned char uch; /* 8-bits */
typedef unsigned short ush; /* 16-bits */
-struct toc_struct{ /* private copy of Table of Contents */
- uch track, fsm[3], q0;
+struct toc_struct { /* private copy of Table of Contents */
+ uch track, fsm[3], q0;
};
static int cm206_blocksizes[1] = { 2048 };
struct cm206_struct {
- volatile ush intr_ds; /* data status read on last interrupt */
- volatile ush intr_ls; /* uart line status read on last interrupt*/
- volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */
- volatile uch ur_w, ur_r; /* write/read buffer index */
- volatile uch dsb, cc; /* drive status byte and condition (error) code */
- int command; /* command to be written to the uart */
- int openfiles;
- ush sector[READ_AHEAD*RAW_SECTOR_SIZE/2]; /* buffered cd-sector */
- int sector_first, sector_last; /* range of these sectors */
- wait_queue_head_t uart; /* wait queues for interrupt */
- wait_queue_head_t data;
- struct timer_list timer; /* time-out */
- char timed_out;
- signed char max_sectors; /* number of sectors that fit in adapter mem */
- char wait_back; /* we're waiting for a background-read */
- char background; /* is a read going on in the background? */
- int adapter_first; /* if so, that's the starting sector */
- int adapter_last;
- char fifo_overflowed;
- uch disc_status[7]; /* result of get_disc_status command */
+ volatile ush intr_ds; /* data status read on last interrupt */
+ volatile ush intr_ls; /* uart line status read on last interrupt */
+ volatile uch ur[UR_SIZE]; /* uart receive buffer fifo */
+ volatile uch ur_w, ur_r; /* write/read buffer index */
+ volatile uch dsb, cc; /* drive status byte and condition (error) code */
+ int command; /* command to be written to the uart */
+ int openfiles;
+ ush sector[READ_AHEAD * RAW_SECTOR_SIZE / 2]; /* buffered cd-sector */
+ int sector_first, sector_last; /* range of these sectors */
+ wait_queue_head_t uart; /* wait queues for interrupt */
+ wait_queue_head_t data;
+ struct timer_list timer; /* time-out */
+ char timed_out;
+ signed char max_sectors; /* number of sectors that fit in adapter mem */
+ char wait_back; /* we're waiting for a background-read */
+ char background; /* is a read going on in the background? */
+ int adapter_first; /* if so, that's the starting sector */
+ int adapter_last;
+ char fifo_overflowed;
+ uch disc_status[7]; /* result of get_disc_status command */
#ifdef STATISTICS
- int stats[NR_STATS];
- int last_stat[NR_STATS]; /* `time' at which stat was stat */
- int stat_counter;
-#endif
- struct toc_struct toc[101]; /* The whole table of contents + lead-out */
- uch q[10]; /* Last read q-channel info */
- uch audio_status[5]; /* last read position on pause */
- uch media_changed; /* record if media changed */
+ int stats[NR_STATS];
+ int last_stat[NR_STATS]; /* `time' at which stat was stat */
+ int stat_counter;
+#endif
+ struct toc_struct toc[101]; /* The whole table of contents + lead-out */
+ uch q[10]; /* Last read q-channel info */
+ uch audio_status[5]; /* last read position on pause */
+ uch media_changed; /* record if media changed */
};
#define DISC_STATUS cd->disc_status[0]
#define FIRST_TRACK cd->disc_status[1]
#define LAST_TRACK cd->disc_status[2]
-#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
+#define PAUSED cd->audio_status[0] /* misuse this memory byte! */
#define PLAY_TO cd->toc[0] /* toc[0] records end-time in play */
-static struct cm206_struct * cd; /* the main memory structure */
+static struct cm206_struct *cd; /* the main memory structure */
/* First, we define some polling functions. These are actually
only being used in the initialization. */
void send_command_polled(int command)
{
- int loop=POLLOOP;
- while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0) {
- mdelay(1); /* one millisec delay */
- --loop;
- }
- outw(command, r_uart_transmit);
+ int loop = POLLOOP;
+ while (!(inw(r_line_status) & ls_transmitter_buffer_empty)
+ && loop > 0) {
+ mdelay(1); /* one millisec delay */
+ --loop;
+ }
+ outw(command, r_uart_transmit);
}
uch receive_echo_polled(void)
{
- int loop=POLLOOP;
- while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) {
- mdelay(1);
- --loop;
- }
- return ((uch) inw(r_uart_receive));
+ int loop = POLLOOP;
+ while (!(inw(r_line_status) & ls_receive_buffer_full) && loop > 0) {
+ mdelay(1);
+ --loop;
+ }
+ return ((uch) inw(r_uart_receive));
}
uch send_receive_polled(int command)
{
- send_command_polled(command);
- return receive_echo_polled();
+ send_command_polled(command);
+ return receive_echo_polled();
}
-inline void clear_ur(void) {
- if (cd->ur_r != cd->ur_w) {
- debug(("Deleting bytes from fifo:"));
- for(;cd->ur_r != cd->ur_w; cd->ur_r++, cd->ur_r %= UR_SIZE)
- debug((" 0x%x", cd->ur[cd->ur_r]));
- debug(("\n"));
- }
+inline void clear_ur(void)
+{
+ if (cd->ur_r != cd->ur_w) {
+ debug(("Deleting bytes from fifo:"));
+ for (; cd->ur_r != cd->ur_w;
+ cd->ur_r++, cd->ur_r %= UR_SIZE)
+ debug((" 0x%x", cd->ur[cd->ur_r]));
+ debug(("\n"));
+ }
}
/* The interrupt handler. When the cm260 generates an interrupt, very
as there seems so reason for this to happen.
*/
-static void cm206_interrupt(int sig, void *dev_id, struct pt_regs * regs)
+static void cm206_interrupt(int sig, void *dev_id, struct pt_regs *regs)
/* you rang? */
{
- volatile ush fool;
- cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
- crc_error, sync_error, toc_ready
- interrupts */
- cd->intr_ls = inw(r_line_status); /* resets overrun bit */
- debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls, cd->background));
- if (cd->intr_ls & ls_attention) stats(attention);
- /* receive buffer full? */
- if (cd->intr_ls & ls_receive_buffer_full) {
- cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
- cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
- debug(("receiving #%d: 0x%x\n", cd->ur_w, cd->ur[cd->ur_w]));
- cd->ur_w++; cd->ur_w %= UR_SIZE;
- if (cd->ur_w == cd->ur_r) debug(("cd->ur overflow!\n"));
- if (waitqueue_active(&cd->uart) && cd->background < 2) {
- del_timer(&cd->timer);
- wake_up_interruptible(&cd->uart);
- }
- }
- /* data ready in fifo? */
- else if (cd->intr_ds & ds_data_ready) {
- if (cd->background) ++cd->adapter_last;
- if (waitqueue_active(&cd->data) && (cd->wait_back || !cd->background)) {
- del_timer(&cd->timer);
- wake_up_interruptible(&cd->data);
- }
- stats(data_ready);
- }
- /* ready to issue a write command? */
- else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
- outw(dc_normal | (inw(r_data_status) & 0x7f), r_data_control);
- outw(cd->command, r_uart_transmit);
- cd->command=0;
- if (!cd->background) wake_up_interruptible(&cd->uart);
- }
- /* now treat errors (at least, identify them for debugging) */
- else if (cd->intr_ds & ds_fifo_overflow) {
- debug(("Fifo overflow at sectors 0x%x\n", cd->sector_first));
- fool = inw(r_fifo_output_buffer); /* de-assert the interrupt */
- cd->fifo_overflowed=1; /* signal one word less should be read */
- stats(fifo_overflow);
- }
- else if (cd->intr_ds & ds_data_error) {
- debug(("Data error at sector 0x%x\n", cd->sector_first));
- stats(data_error);
- }
- else if (cd->intr_ds & ds_crc_error) {
- debug(("CRC error at sector 0x%x\n", cd->sector_first));
- stats(crc_error);
- }
- else if (cd->intr_ds & ds_sync_error) {
- debug(("Sync at sector 0x%x\n", cd->sector_first));
- stats(sync_error);
- }
- else if (cd->intr_ds & ds_toc_ready) {
- /* do something appropriate */
- }
- /* couldn't see why this interrupt, maybe due to init */
- else {
- outw(dc_normal | READ_AHEAD, r_data_control);
- stats(lost_intr);
- }
- if (cd->background && (cd->adapter_last-cd->adapter_first == cd->max_sectors
- || cd->fifo_overflowed))
- mark_bh(CM206_BH); /* issue a stop read command */
- stats(interrupt);
+ volatile ush fool;
+ cd->intr_ds = inw(r_data_status); /* resets data_ready, data_error,
+ crc_error, sync_error, toc_ready
+ interrupts */
+ cd->intr_ls = inw(r_line_status); /* resets overrun bit */
+ debug(("Intr, 0x%x 0x%x, %d\n", cd->intr_ds, cd->intr_ls,
+ cd->background));
+ if (cd->intr_ls & ls_attention)
+ stats(attention);
+ /* receive buffer full? */
+ if (cd->intr_ls & ls_receive_buffer_full) {
+ cd->ur[cd->ur_w] = inb(r_uart_receive); /* get order right! */
+ cd->intr_ls = inw(r_line_status); /* resets rbf interrupt */
+ debug(("receiving #%d: 0x%x\n", cd->ur_w,
+ cd->ur[cd->ur_w]));
+ cd->ur_w++;
+ cd->ur_w %= UR_SIZE;
+ if (cd->ur_w == cd->ur_r)
+ debug(("cd->ur overflow!\n"));
+ if (waitqueue_active(&cd->uart) && cd->background < 2) {
+ del_timer(&cd->timer);
+ wake_up_interruptible(&cd->uart);
+ }
+ }
+ /* data ready in fifo? */
+ else if (cd->intr_ds & ds_data_ready) {
+ if (cd->background)
+ ++cd->adapter_last;
+ if (waitqueue_active(&cd->data)
+ && (cd->wait_back || !cd->background)) {
+ del_timer(&cd->timer);
+ wake_up_interruptible(&cd->data);
+ }
+ stats(data_ready);
+ }
+ /* ready to issue a write command? */
+ else if (cd->command && cd->intr_ls & ls_transmitter_buffer_empty) {
+ outw(dc_normal | (inw(r_data_status) & 0x7f),
+ r_data_control);
+ outw(cd->command, r_uart_transmit);
+ cd->command = 0;
+ if (!cd->background)
+ wake_up_interruptible(&cd->uart);
+ }
+ /* now treat errors (at least, identify them for debugging) */
+ else if (cd->intr_ds & ds_fifo_overflow) {
+ debug(("Fifo overflow at sectors 0x%x\n",
+ cd->sector_first));
+ fool = inw(r_fifo_output_buffer); /* de-assert the interrupt */
+ cd->fifo_overflowed = 1; /* signal one word less should be read */
+ stats(fifo_overflow);
+ } else if (cd->intr_ds & ds_data_error) {
+ debug(("Data error at sector 0x%x\n", cd->sector_first));
+ stats(data_error);
+ } else if (cd->intr_ds & ds_crc_error) {
+ debug(("CRC error at sector 0x%x\n", cd->sector_first));
+ stats(crc_error);
+ } else if (cd->intr_ds & ds_sync_error) {
+ debug(("Sync at sector 0x%x\n", cd->sector_first));
+ stats(sync_error);
+ } else if (cd->intr_ds & ds_toc_ready) {
+ /* do something appropriate */
+ }
+ /* couldn't see why this interrupt, maybe due to init */
+ else {
+ outw(dc_normal | READ_AHEAD, r_data_control);
+ stats(lost_intr);
+ }
+ if (cd->background
+ && (cd->adapter_last - cd->adapter_first == cd->max_sectors
+ || cd->fifo_overflowed))
+ mark_bh(CM206_BH); /* issue a stop read command */
+ stats(interrupt);
}
/* we have put the address of the wait queue in who */
void cm206_timeout(unsigned long who)
{
- cd->timed_out = 1;
- debug(("Timing out\n"));
- wake_up_interruptible((wait_queue_head_t *)who);
+ cd->timed_out = 1;
+ debug(("Timing out\n"));
+ wake_up_interruptible((wait_queue_head_t *) who);
}
/* This function returns 1 if a timeout occurred, 0 if an interrupt
happened */
-int sleep_or_timeout(wait_queue_head_t *wait, int timeout)
+int sleep_or_timeout(wait_queue_head_t * wait, int timeout)
{
- cd->timed_out=0;
- cd->timer.data=(unsigned long) wait;
- cd->timer.expires = jiffies + timeout;
- add_timer(&cd->timer);
- debug(("going to sleep\n"));
- interruptible_sleep_on(wait);
- del_timer(&cd->timer);
- if (cd->timed_out) {
- cd->timed_out = 0;
- return 1;
- }
- else return 0;
+ cd->timed_out = 0;
+ cd->timer.data = (unsigned long) wait;
+ cd->timer.expires = jiffies + timeout;
+ add_timer(&cd->timer);
+ debug(("going to sleep\n"));
+ interruptible_sleep_on(wait);
+ del_timer(&cd->timer);
+ if (cd->timed_out) {
+ cd->timed_out = 0;
+ return 1;
+ } else
+ return 0;
}
-void cm206_delay(int nr_jiffies)
+void cm206_delay(int nr_jiffies)
{
- DECLARE_WAIT_QUEUE_HEAD(wait);
- sleep_or_timeout(&wait, nr_jiffies);
+ DECLARE_WAIT_QUEUE_HEAD(wait);
+ sleep_or_timeout(&wait, nr_jiffies);
}
void send_command(int command)
{
- debug(("Sending 0x%x\n", command));
- if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
- cd->command = command;
- cli(); /* don't interrupt before sleep */
- outw(dc_mask_sync_error | dc_no_stop_on_error |
- (inw(r_data_status) & 0x7f), r_data_control);
- /* interrupt routine sends command */
- if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
- debug(("Time out on write-buffer\n"));
- stats(write_timeout);
- outw(command, r_uart_transmit);
- }
- debug(("Write commmand delayed\n"));
- }
- else outw(command, r_uart_transmit);
+ debug(("Sending 0x%x\n", command));
+ if (!(inw(r_line_status) & ls_transmitter_buffer_empty)) {
+ cd->command = command;
+ cli(); /* don't interrupt before sleep */
+ outw(dc_mask_sync_error | dc_no_stop_on_error |
+ (inw(r_data_status) & 0x7f), r_data_control);
+ /* interrupt routine sends command */
+ if (sleep_or_timeout(&cd->uart, UART_TIMEOUT)) {
+ debug(("Time out on write-buffer\n"));
+ stats(write_timeout);
+ outw(command, r_uart_transmit);
+ }
+ debug(("Write commmand delayed\n"));
+ } else
+ outw(command, r_uart_transmit);
}
uch receive_byte(int timeout)
{
- uch ret;
- cli();
- debug(("cli\n"));
- ret = cd->ur[cd->ur_r];
- if (cd->ur_r != cd->ur_w) {
- sti();
- debug(("returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
- cd->ur_r++; cd->ur_r %= UR_SIZE;
- return ret;
- }
- else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
- debug(("Time out on receive-buffer\n"));
+ uch ret;
+ cli();
+ debug(("cli\n"));
+ ret = cd->ur[cd->ur_r];
+ if (cd->ur_r != cd->ur_w) {
+ sti();
+ debug(("returning #%d: 0x%x\n", cd->ur_r,
+ cd->ur[cd->ur_r]));
+ cd->ur_r++;
+ cd->ur_r %= UR_SIZE;
+ return ret;
+ } else if (sleep_or_timeout(&cd->uart, timeout)) { /* does sti() */
+ debug(("Time out on receive-buffer\n"));
#ifdef STATISTICS
- if (timeout==UART_TIMEOUT) stats(receive_timeout) /* no `;'! */
- else stats(dsb_timeout);
+ if (timeout == UART_TIMEOUT)
+ stats(receive_timeout) /* no `;'! */
+ else
+ stats(dsb_timeout);
#endif
- return 0xda;
- }
- ret = cd->ur[cd->ur_r];
- debug(("slept; returning #%d: 0x%x\n", cd->ur_r, cd->ur[cd->ur_r]));
- cd->ur_r++; cd->ur_r %= UR_SIZE;
- return ret;
+ return 0xda;
+ }
+ ret = cd->ur[cd->ur_r];
+ debug(("slept; returning #%d: 0x%x\n", cd->ur_r,
+ cd->ur[cd->ur_r]));
+ cd->ur_r++;
+ cd->ur_r %= UR_SIZE;
+ return ret;
}
inline uch receive_echo(void)
{
- return receive_byte(UART_TIMEOUT);
+ return receive_byte(UART_TIMEOUT);
}
inline uch send_receive(int command)
{
- send_command(command);
- return receive_echo();
+ send_command(command);
+ return receive_echo();
}
inline uch wait_dsb(void)
{
- return receive_byte(DSB_TIMEOUT);
+ return receive_byte(DSB_TIMEOUT);
}
int type_0_command(int command, int expect_dsb)
{
- int e;
- clear_ur();
- if (command != (e=send_receive(command))) {
- debug(("command 0x%x echoed as 0x%x\n", command, e));
- stats(echo);
- return -1;
- }
- if (expect_dsb) {
- cd->dsb = wait_dsb(); /* wait for command to finish */
- }
- return 0;
+ int e;
+ clear_ur();
+ if (command != (e = send_receive(command))) {
+ debug(("command 0x%x echoed as 0x%x\n", command, e));
+ stats(echo);
+ return -1;
+ }
+ if (expect_dsb) {
+ cd->dsb = wait_dsb(); /* wait for command to finish */
+ }
+ return 0;
}
-int type_1_command(int command, int bytes, uch * status) /* returns info */
-{
- int i;
- if (type_0_command(command,0)) return -1;
- for(i=0; i<bytes; i++)
- status[i] = send_receive(c_gimme);
- return 0;
-}
+int type_1_command(int command, int bytes, uch * status)
+{ /* returns info */
+ int i;
+ if (type_0_command(command, 0))
+ return -1;
+ for (i = 0; i < bytes; i++)
+ status[i] = send_receive(c_gimme);
+ return 0;
+}
/* This function resets the adapter card. We'd better not do this too
* often, because it tends to generate `lost interrupts.' */
void reset_cm260(void)
{
- outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
- udelay(10); /* 3.3 mu sec minimum */
- outw(dc_normal | READ_AHEAD, r_data_control);
+ outw(dc_normal | dc_initialize | READ_AHEAD, r_data_control);
+ udelay(10); /* 3.3 mu sec minimum */
+ outw(dc_normal | READ_AHEAD, r_data_control);
}
/* fsm: frame-sec-min from linear address; one of many */
-void fsm(int lba, uch * fsm)
+void fsm(int lba, uch * fsm)
{
- fsm[0] = lba % 75;
- lba /= 75; lba += 2;
- fsm[1] = lba % 60; fsm[2] = lba / 60;
+ fsm[0] = lba % 75;
+ lba /= 75;
+ lba += 2;
+ fsm[1] = lba % 60;
+ fsm[2] = lba / 60;
}
-inline int fsm2lba(uch * fsm)
+inline int fsm2lba(uch * fsm)
{
- return fsm[0] + 75*(fsm[1]-2 + 60*fsm[2]);
+ return fsm[0] + 75 * (fsm[1] - 2 + 60 * fsm[2]);
}
inline int f_s_m2lba(uch f, uch s, uch m)
{
- return f + 75*(s-2 + 60*m);
+ return f + 75 * (s - 2 + 60 * m);
}
-int start_read(int start)
+int start_read(int start)
{
- uch read_sector[4] = {c_read_data, };
- int i, e;
-
- fsm(start, &read_sector[1]);
- clear_ur();
- for (i=0; i<4; i++)
- if (read_sector[i] != (e=send_receive(read_sector[i]))) {
- debug(("read_sector: %x echoes %x\n", read_sector[i], e));
- stats(echo);
- if (e==0xff) { /* this seems to happen often */
- e = receive_echo();
- debug(("Second try %x\n", e));
- if (e!=read_sector[i]) return -1;
- }
- }
- return 0;
+ uch read_sector[4] = { c_read_data, };
+ int i, e;
+
+ fsm(start, &read_sector[1]);
+ clear_ur();
+ for (i = 0; i < 4; i++)
+ if (read_sector[i] != (e = send_receive(read_sector[i]))) {
+ debug(("read_sector: %x echoes %x\n",
+ read_sector[i], e));
+ stats(echo);
+ if (e == 0xff) { /* this seems to happen often */
+ e = receive_echo();
+ debug(("Second try %x\n", e));
+ if (e != read_sector[i])
+ return -1;
+ }
+ }
+ return 0;
}
int stop_read(void)
{
- int e;
- type_0_command(c_stop,0);
- if((e=receive_echo()) != 0xff) {
- debug(("c_stop didn't send 0xff, but 0x%x\n", e));
- stats(stop_0xff);
- return -1;
- }
- return 0;
-}
+ int e;
+ type_0_command(c_stop, 0);
+ if ((e = receive_echo()) != 0xff) {
+ debug(("c_stop didn't send 0xff, but 0x%x\n", e));
+ stats(stop_0xff);
+ return -1;
+ }
+ return 0;
+}
/* This function starts to read sectors in adapter memory, the
interrupt routine should stop the read. In fact, the bottom_half
int read_background(int start, int reading)
{
- if (cd->background) return -1; /* can't do twice */
- outw(dc_normal | BACK_AHEAD, r_data_control);
- if (!reading && start_read(start)) return -2;
- cd->adapter_first = cd->adapter_last = start;
- cd->background = 1; /* flag a read is going on */
- return 0;
+ if (cd->background)
+ return -1; /* can't do twice */
+ outw(dc_normal | BACK_AHEAD, r_data_control);
+ if (!reading && start_read(start))
+ return -2;
+ cd->adapter_first = cd->adapter_last = start;
+ cd->background = 1; /* flag a read is going on */
+ return 0;
}
#ifdef USE_INSW
#else
/* this routine implements insw(,,). There was a time i had the
impression that there would be any difference in error-behaviour. */
-void transport_data(int port, ush * dest, int count)
+void transport_data(int port, ush * dest, int count)
{
- int i;
- ush * d;
- for (i=0, d=dest; i<count; i++, d++)
- *d = inw(port);
+ int i;
+ ush *d;
+ for (i = 0, d = dest; i < count; i++, d++)
+ *d = inw(port);
}
#endif
#define MAX_TRIES 100
int read_sector(int start)
{
- int tries=0;
- if (cd->background) {
- cd->background=0;
- cd->adapter_last = -1; /* invalidate adapter memory */
- stop_read();
- }
- cd->fifo_overflowed=0;
- reset_cm260(); /* empty fifo etc. */
- if (start_read(start)) return -1;
- do {
- if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
- debug(("Read timed out sector 0x%x\n", start));
- stats(read_timeout);
- stop_read();
- return -3;
- }
- tries++;
- } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
- if (tries>1) debug(("Took me some tries\n"))
- else if (tries == MAX_TRIES)
- debug(("MAX_TRIES tries for read sector\n"));
- transport_data(r_fifo_output_buffer, cd->sector,
- READ_AHEAD*RAW_SECTOR_SIZE/2);
- if (read_background(start+READ_AHEAD,1)) stats(read_background);
- cd->sector_first = start; cd->sector_last = start+READ_AHEAD;
- stats(read_restarted);
- return 0;
+ int tries = 0;
+ if (cd->background) {
+ cd->background = 0;
+ cd->adapter_last = -1; /* invalidate adapter memory */
+ stop_read();
+ }
+ cd->fifo_overflowed = 0;
+ reset_cm260(); /* empty fifo etc. */
+ if (start_read(start))
+ return -1;
+ do {
+ if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+ debug(("Read timed out sector 0x%x\n", start));
+ stats(read_timeout);
+ stop_read();
+ return -3;
+ }
+ tries++;
+ } while (cd->intr_ds & ds_fifo_empty && tries < MAX_TRIES);
+ if (tries > 1)
+ debug(("Took me some tries\n"))
+ else
+ if (tries == MAX_TRIES)
+ debug(("MAX_TRIES tries for read sector\n"));
+ transport_data(r_fifo_output_buffer, cd->sector,
+ READ_AHEAD * RAW_SECTOR_SIZE / 2);
+ if (read_background(start + READ_AHEAD, 1))
+ stats(read_background);
+ cd->sector_first = start;
+ cd->sector_last = start + READ_AHEAD;
+ stats(read_restarted);
+ return 0;
}
/* The function of bottom-half is to send a stop command to the drive
void cm206_bh(void)
{
- debug(("bh: %d\n", cd->background));
- switch (cd->background) {
- case 1:
- stats(bh);
- if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
- cd->command = c_stop;
- outw(dc_mask_sync_error | dc_no_stop_on_error |
- (inw(r_data_status) & 0x7f), r_data_control);
- cd->background=2;
- break; /* we'd better not time-out here! */
- }
- else outw(c_stop, r_uart_transmit);
- /* fall into case 2: */
- case 2:
- /* the write has been satisfied by interrupt routine */
- cd->background=3;
- break;
- case 3:
- if (cd->ur_r != cd->ur_w) {
- if (cd->ur[cd->ur_r] != c_stop) {
- debug(("cm206_bh: c_stop echoed 0x%x\n", cd->ur[cd->ur_r]));
- stats(echo);
- }
- cd->ur_r++; cd->ur_r %= UR_SIZE;
- }
- cd->background++;
- break;
- case 4:
- if (cd->ur_r != cd->ur_w) {
- if (cd->ur[cd->ur_r] != 0xff) {
- debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
- stats(stop_0xff);
- }
- cd->ur_r++; cd->ur_r %= UR_SIZE;
- }
- cd->background=0;
- }
+ debug(("bh: %d\n", cd->background));
+ switch (cd->background) {
+ case 1:
+ stats(bh);
+ if (!(cd->intr_ls & ls_transmitter_buffer_empty)) {
+ cd->command = c_stop;
+ outw(dc_mask_sync_error | dc_no_stop_on_error |
+ (inw(r_data_status) & 0x7f), r_data_control);
+ cd->background = 2;
+ break; /* we'd better not time-out here! */
+ } else
+ outw(c_stop, r_uart_transmit);
+ /* fall into case 2: */
+ case 2:
+ /* the write has been satisfied by interrupt routine */
+ cd->background = 3;
+ break;
+ case 3:
+ if (cd->ur_r != cd->ur_w) {
+ if (cd->ur[cd->ur_r] != c_stop) {
+ debug(("cm206_bh: c_stop echoed 0x%x\n",
+ cd->ur[cd->ur_r]));
+ stats(echo);
+ }
+ cd->ur_r++;
+ cd->ur_r %= UR_SIZE;
+ }
+ cd->background++;
+ break;
+ case 4:
+ if (cd->ur_r != cd->ur_w) {
+ if (cd->ur[cd->ur_r] != 0xff) {
+ debug(("cm206_bh: c_stop reacted with 0x%x\n", cd->ur[cd->ur_r]));
+ stats(stop_0xff);
+ }
+ cd->ur_r++;
+ cd->ur_r %= UR_SIZE;
+ }
+ cd->background = 0;
+ }
}
/* This command clears the dsb_possible_media_change flag, so we must
*/
void get_drive_status(void)
{
- uch status[2];
- type_1_command(c_drive_status, 2, status); /* this might be done faster */
- cd->dsb=status[0];
- cd->cc=status[1];
- cd->media_changed |=
- !!(cd->dsb & (dsb_possible_media_change |
- dsb_drive_not_ready | dsb_tray_not_closed));
+ uch status[2];
+ type_1_command(c_drive_status, 2, status); /* this might be done faster */
+ cd->dsb = status[0];
+ cd->cc = status[1];
+ cd->media_changed |=
+ !!(cd->dsb & (dsb_possible_media_change |
+ dsb_drive_not_ready | dsb_tray_not_closed));
}
void get_disc_status(void)
{
- if (type_1_command(c_disc_status, 7, cd->disc_status)) {
- debug(("get_disc_status: error\n"));
- }
+ if (type_1_command(c_disc_status, 7, cd->disc_status)) {
+ debug(("get_disc_status: error\n"));
+ }
}
/* The new open. The real opening strategy is defined in cdrom.c. */
-static int cm206_open(struct cdrom_device_info * cdi, int purpose)
+static int cm206_open(struct cdrom_device_info *cdi, int purpose)
{
- MOD_INC_USE_COUNT;
- if (!cd->openfiles) { /* reset only first time */
- cd->background=0;
- reset_cm260();
- cd->adapter_last = -1; /* invalidate adapter memory */
- cd->sector_last = -1;
- }
- ++cd->openfiles;
- stats(open);
- return 0;
+ MOD_INC_USE_COUNT;
+ if (!cd->openfiles) { /* reset only first time */
+ cd->background = 0;
+ reset_cm260();
+ cd->adapter_last = -1; /* invalidate adapter memory */
+ cd->sector_last = -1;
+ }
+ ++cd->openfiles;
+ stats(open);
+ return 0;
}
-static void cm206_release(struct cdrom_device_info * cdi)
+static void cm206_release(struct cdrom_device_info *cdi)
{
- if (cd->openfiles==1) {
- if (cd->background) {
- cd->background=0;
- stop_read();
- }
- cd->sector_last = -1; /* Make our internal buffer invalid */
- FIRST_TRACK = 0; /* No valid disc status */
- }
- --cd->openfiles;
- MOD_DEC_USE_COUNT;
+ if (cd->openfiles == 1) {
+ if (cd->background) {
+ cd->background = 0;
+ stop_read();
+ }
+ cd->sector_last = -1; /* Make our internal buffer invalid */
+ FIRST_TRACK = 0; /* No valid disc status */
+ }
+ --cd->openfiles;
+ MOD_DEC_USE_COUNT;
}
/* Empty buffer empties $sectors$ sectors of the adapter card buffer,
* and then reads a sector in kernel memory. */
-void empty_buffer(int sectors)
+void empty_buffer(int sectors)
{
- while (sectors>=0) {
- transport_data(r_fifo_output_buffer, cd->sector + cd->fifo_overflowed,
- RAW_SECTOR_SIZE/2 - cd->fifo_overflowed);
- --sectors;
- ++cd->adapter_first; /* update the current adapter sector */
- cd->fifo_overflowed=0; /* reset overflow bit */
- stats(sector_transferred);
- }
- cd->sector_first=cd->adapter_first-1;
- cd->sector_last=cd->adapter_first; /* update the buffer sector */
+ while (sectors >= 0) {
+ transport_data(r_fifo_output_buffer,
+ cd->sector + cd->fifo_overflowed,
+ RAW_SECTOR_SIZE / 2 - cd->fifo_overflowed);
+ --sectors;
+ ++cd->adapter_first; /* update the current adapter sector */
+ cd->fifo_overflowed = 0; /* reset overflow bit */
+ stats(sector_transferred);
+ }
+ cd->sector_first = cd->adapter_first - 1;
+ cd->sector_last = cd->adapter_first; /* update the buffer sector */
}
/* try_adapter. This function determines if the requested sector is
success */
int try_adapter(int sector)
{
- if (cd->adapter_first <= sector && sector < cd->adapter_last) {
- /* sector is in adapter memory */
- empty_buffer(sector - cd->adapter_first);
- return 0;
- }
- else if (cd->background==1 && cd->adapter_first <= sector
- && sector < cd->adapter_first+cd->max_sectors) {
- /* a read is going on, we can wait for it */
- cd->wait_back=1;
- while (sector >= cd->adapter_last) {
- if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
- debug(("Timed out during background wait: %d %d %d %d\n", sector,
- cd->adapter_last, cd->adapter_first, cd->background));
- stats(back_read_timeout);
- cd->wait_back=0;
- return -1;
- }
- }
- cd->wait_back=0;
- empty_buffer(sector - cd->adapter_first);
- return 0;
- }
- else return -2;
+ if (cd->adapter_first <= sector && sector < cd->adapter_last) {
+ /* sector is in adapter memory */
+ empty_buffer(sector - cd->adapter_first);
+ return 0;
+ } else if (cd->background == 1 && cd->adapter_first <= sector
+ && sector < cd->adapter_first + cd->max_sectors) {
+ /* a read is going on, we can wait for it */
+ cd->wait_back = 1;
+ while (sector >= cd->adapter_last) {
+ if (sleep_or_timeout(&cd->data, DATA_TIMEOUT)) {
+ debug(("Timed out during background wait: %d %d %d %d\n", sector, cd->adapter_last, cd->adapter_first, cd->background));
+ stats(back_read_timeout);
+ cd->wait_back = 0;
+ return -1;
+ }
+ }
+ cd->wait_back = 0;
+ empty_buffer(sector - cd->adapter_first);
+ return 0;
+ } else
+ return -2;
}
/* This is not a very smart implementation. We could optimize for
bring down the processor load. */
static void do_cm206_request(request_queue_t * q)
{
- long int i, cd_sec_no;
- int quarter, error;
- uch * source, * dest;
-
- while(1) { /* repeat until all requests have been satisfied */
- INIT_REQUEST;
- if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
- return;
- if (CURRENT->cmd != READ) {
- debug(("Non-read command %d on cdrom\n", CURRENT->cmd));
- end_request(0);
- continue;
- }
- spin_unlock_irq(&io_request_lock);
- error=0;
- for (i=0; i<CURRENT->nr_sectors; i++) {
- int e1, e2;
- cd_sec_no = (CURRENT->sector+i)/BLOCKS_ISO; /* 4 times 512 bytes */
- quarter = (CURRENT->sector+i) % BLOCKS_ISO;
- dest = CURRENT->buffer + i*LINUX_BLOCK_SIZE;
- /* is already in buffer memory? */
- if (cd->sector_first <= cd_sec_no && cd_sec_no < cd->sector_last) {
- source = ((uch *) cd->sector) + 16 + quarter*LINUX_BLOCK_SIZE
- + (cd_sec_no-cd->sector_first)*RAW_SECTOR_SIZE;
- memcpy(dest, source, LINUX_BLOCK_SIZE);
- }
- else if (!(e1=try_adapter(cd_sec_no)) ||
- !(e2=read_sector(cd_sec_no))) {
- source = ((uch *) cd->sector)+16+quarter*LINUX_BLOCK_SIZE;
- memcpy(dest, source, LINUX_BLOCK_SIZE);
- }
- else {
- error=1;
- debug(("cm206_request: %d %d\n", e1, e2));
- }
- }
- spin_lock_irq(&io_request_lock);
- end_request(!error);
- }
+ long int i, cd_sec_no;
+ int quarter, error;
+ uch *source, *dest;
+
+ while (1) { /* repeat until all requests have been satisfied */
+ INIT_REQUEST;
+ if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
+ return;
+ if (CURRENT->cmd != READ) {
+ debug(("Non-read command %d on cdrom\n",
+ CURRENT->cmd));
+ end_request(0);
+ continue;
+ }
+ spin_unlock_irq(&io_request_lock);
+ error = 0;
+ for (i = 0; i < CURRENT->nr_sectors; i++) {
+ int e1, e2;
+ cd_sec_no = (CURRENT->sector + i) / BLOCKS_ISO; /* 4 times 512 bytes */
+ quarter = (CURRENT->sector + i) % BLOCKS_ISO;
+ dest = CURRENT->buffer + i * LINUX_BLOCK_SIZE;
+ /* is already in buffer memory? */
+ if (cd->sector_first <= cd_sec_no
+ && cd_sec_no < cd->sector_last) {
+ source =
+ ((uch *) cd->sector) + 16 +
+ quarter * LINUX_BLOCK_SIZE +
+ (cd_sec_no -
+ cd->sector_first) * RAW_SECTOR_SIZE;
+ memcpy(dest, source, LINUX_BLOCK_SIZE);
+ } else if (!(e1 = try_adapter(cd_sec_no)) ||
+ !(e2 = read_sector(cd_sec_no))) {
+ source =
+ ((uch *) cd->sector) + 16 +
+ quarter * LINUX_BLOCK_SIZE;
+ memcpy(dest, source, LINUX_BLOCK_SIZE);
+ } else {
+ error = 1;
+ debug(("cm206_request: %d %d\n", e1, e2));
+ }
+ }
+ spin_lock_irq(&io_request_lock);
+ end_request(!error);
+ }
}
/* Audio support. I've tried very hard, but the cm206 drive doesn't
/* seek seeks to address lba. It does wait to arrive there. */
void seek(int lba)
{
- int i;
- uch seek_command[4]={c_seek, };
-
- fsm(lba, &seek_command[1]);
- for (i=0; i<4; i++) type_0_command(seek_command[i], 0);
- cd->dsb = wait_dsb();
+ int i;
+ uch seek_command[4] = { c_seek, };
+
+ fsm(lba, &seek_command[1]);
+ for (i = 0; i < 4; i++)
+ type_0_command(seek_command[i], 0);
+ cd->dsb = wait_dsb();
}
-uch bcdbin(unsigned char bcd) /* stolen from mcd.c! */
-{
- return (bcd >> 4)*10 + (bcd & 0xf);
-}
+uch bcdbin(unsigned char bcd)
+{ /* stolen from mcd.c! */
+ return (bcd >> 4) * 10 + (bcd & 0xf);
+}
-inline uch normalize_track(uch track)
+inline uch normalize_track(uch track)
{
- if (track<1) return 1;
- if (track>LAST_TRACK) return LAST_TRACK+1;
- return track;
+ if (track < 1)
+ return 1;
+ if (track > LAST_TRACK)
+ return LAST_TRACK + 1;
+ return track;
}
/* This function does a binary search for track start. It records all
*/
int get_toc_lba(uch track)
{
- int max=74*60*75-150, min=fsm2lba(cd->toc[1].fsm);
- int i, lba, l, old_lba=0;
- uch * q = cd->q;
- uch ct; /* current track */
- int binary=0;
- const int skip = 3*60*75; /* 3 minutes */
-
- for (i=track; i>0; i--) if (cd->toc[i].track) {
- min = fsm2lba(cd->toc[i].fsm);
- break;
- }
- lba = min + skip;
- do {
- seek(lba);
- type_1_command(c_read_current_q, 10, q);
- ct = normalize_track(q[1]);
- if (!cd->toc[ct].track) {
- l = q[9]-bcdbin(q[5]) + 75*(q[8]-bcdbin(q[4])-2 +
- 60*(q[7]-bcdbin(q[3])));
- cd->toc[ct].track=q[1]; /* lead out still 0xaa */
- fsm(l, cd->toc[ct].fsm);
- cd->toc[ct].q0 = q[0]; /* contains adr and ctrl info */
- if (ct==track) return l;
- }
- old_lba=lba;
- if (binary) {
- if (ct < track) min = lba; else max = lba;
- lba = (min+max)/2;
- } else {
- if(ct < track) lba += skip;
- else {
- binary=1;
- max = lba; min = lba - skip;
- lba = (min+max)/2;
- }
- }
- } while (lba!=old_lba);
- return lba;
+ int max = 74 * 60 * 75 - 150, min = fsm2lba(cd->toc[1].fsm);
+ int i, lba, l, old_lba = 0;
+ uch *q = cd->q;
+ uch ct; /* current track */
+ int binary = 0;
+ const int skip = 3 * 60 * 75; /* 3 minutes */
+
+ for (i = track; i > 0; i--)
+ if (cd->toc[i].track) {
+ min = fsm2lba(cd->toc[i].fsm);
+ break;
+ }
+ lba = min + skip;
+ do {
+ seek(lba);
+ type_1_command(c_read_current_q, 10, q);
+ ct = normalize_track(q[1]);
+ if (!cd->toc[ct].track) {
+ l = q[9] - bcdbin(q[5]) + 75 * (q[8] -
+ bcdbin(q[4]) - 2 +
+ 60 * (q[7] -
+ bcdbin(q
+ [3])));
+ cd->toc[ct].track = q[1]; /* lead out still 0xaa */
+ fsm(l, cd->toc[ct].fsm);
+ cd->toc[ct].q0 = q[0]; /* contains adr and ctrl info */
+ if (ct == track)
+ return l;
+ }
+ old_lba = lba;
+ if (binary) {
+ if (ct < track)
+ min = lba;
+ else
+ max = lba;
+ lba = (min + max) / 2;
+ } else {
+ if (ct < track)
+ lba += skip;
+ else {
+ binary = 1;
+ max = lba;
+ min = lba - skip;
+ lba = (min + max) / 2;
+ }
+ }
+ } while (lba != old_lba);
+ return lba;
}
-void update_toc_entry(uch track)
+void update_toc_entry(uch track)
{
- track = normalize_track(track);
- if (!cd->toc[track].track) get_toc_lba(track);
+ track = normalize_track(track);
+ if (!cd->toc[track].track)
+ get_toc_lba(track);
}
/* return 0 upon success */
-int read_toc_header(struct cdrom_tochdr * hp)
+int read_toc_header(struct cdrom_tochdr *hp)
{
- if (!FIRST_TRACK) get_disc_status();
- if (hp) {
- int i;
- hp->cdth_trk0 = FIRST_TRACK;
- hp->cdth_trk1 = LAST_TRACK;
- /* fill in first track position */
- for (i=0; i<3; i++) cd->toc[1].fsm[i] = cd->disc_status[3+i];
- update_toc_entry(LAST_TRACK+1); /* find most entries */
- return 0;
- }
- return -1;
-}
-
-void play_from_to_msf(struct cdrom_msf* msfp)
+ if (!FIRST_TRACK)
+ get_disc_status();
+ if (hp) {
+ int i;
+ hp->cdth_trk0 = FIRST_TRACK;
+ hp->cdth_trk1 = LAST_TRACK;
+ /* fill in first track position */
+ for (i = 0; i < 3; i++)
+ cd->toc[1].fsm[i] = cd->disc_status[3 + i];
+ update_toc_entry(LAST_TRACK + 1); /* find most entries */
+ return 0;
+ }
+ return -1;
+}
+
+void play_from_to_msf(struct cdrom_msf *msfp)
{
- uch play_command[] = {c_play,
- msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
- msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2, 2};
- int i;
- for (i=0; i<9; i++) type_0_command(play_command[i], 0);
- for (i=0; i<3; i++)
- PLAY_TO.fsm[i] = play_command[i+4];
- PLAY_TO.track = 0; /* say no track end */
- cd->dsb = wait_dsb();
-}
+ uch play_command[] = { c_play,
+ msfp->cdmsf_frame0, msfp->cdmsf_sec0, msfp->cdmsf_min0,
+ msfp->cdmsf_frame1, msfp->cdmsf_sec1, msfp->cdmsf_min1, 2,
+ 2
+ };
+ int i;
+ for (i = 0; i < 9; i++)
+ type_0_command(play_command[i], 0);
+ for (i = 0; i < 3; i++)
+ PLAY_TO.fsm[i] = play_command[i + 4];
+ PLAY_TO.track = 0; /* say no track end */
+ cd->dsb = wait_dsb();
+}
void play_from_to_track(int from, int to)
{
- uch play_command[8] = {c_play, };
- int i;
-
- if (from==0) { /* continue paused play */
- for (i=0; i<3; i++) {
- play_command[i+1] = cd->audio_status[i+2];
- play_command[i+4] = PLAY_TO.fsm[i];
- }
- } else {
- update_toc_entry(from); update_toc_entry(to+1);
- for (i=0; i<3; i++) {
- play_command[i+1] = cd->toc[from].fsm[i];
- PLAY_TO.fsm[i] = play_command[i+4] = cd->toc[to+1].fsm[i];
- }
- PLAY_TO.track = to;
- }
- for (i=0; i<7; i++) type_0_command(play_command[i],0);
- for (i=0; i<2; i++) type_0_command(0x2, 0); /* volume */
- cd->dsb = wait_dsb();
+ uch play_command[8] = { c_play, };
+ int i;
+
+ if (from == 0) { /* continue paused play */
+ for (i = 0; i < 3; i++) {
+ play_command[i + 1] = cd->audio_status[i + 2];
+ play_command[i + 4] = PLAY_TO.fsm[i];
+ }
+ } else {
+ update_toc_entry(from);
+ update_toc_entry(to + 1);
+ for (i = 0; i < 3; i++) {
+ play_command[i + 1] = cd->toc[from].fsm[i];
+ PLAY_TO.fsm[i] = play_command[i + 4] =
+ cd->toc[to + 1].fsm[i];
+ }
+ PLAY_TO.track = to;
+ }
+ for (i = 0; i < 7; i++)
+ type_0_command(play_command[i], 0);
+ for (i = 0; i < 2; i++)
+ type_0_command(0x2, 0); /* volume */
+ cd->dsb = wait_dsb();
}
-int get_current_q(struct cdrom_subchnl * qp)
+int get_current_q(struct cdrom_subchnl *qp)
{
- int i;
- uch * q = cd->q;
- if (type_1_command(c_read_current_q, 10, q)) return 0;
+ int i;
+ uch *q = cd->q;
+ if (type_1_command(c_read_current_q, 10, q))
+ return 0;
/* q[0] = bcdbin(q[0]); Don't think so! */
- for (i=2; i<6; i++) q[i]=bcdbin(q[i]);
- qp->cdsc_adr = q[0] & 0xf; qp->cdsc_ctrl = q[0] >> 4; /* from mcd.c */
- qp->cdsc_trk = q[1]; qp->cdsc_ind = q[2];
- if (qp->cdsc_format == CDROM_MSF) {
- qp->cdsc_reladdr.msf.minute = q[3];
- qp->cdsc_reladdr.msf.second = q[4];
- qp->cdsc_reladdr.msf.frame = q[5];
- qp->cdsc_absaddr.msf.minute = q[7];
- qp->cdsc_absaddr.msf.second = q[8];
- qp->cdsc_absaddr.msf.frame = q[9];
- } else {
- qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
- qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
- }
- get_drive_status();
- if (cd->dsb & dsb_play_in_progress)
- qp->cdsc_audiostatus = CDROM_AUDIO_PLAY ;
- else if (PAUSED)
- qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
- else qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
- return 0;
+ for (i = 2; i < 6; i++)
+ q[i] = bcdbin(q[i]);
+ qp->cdsc_adr = q[0] & 0xf;
+ qp->cdsc_ctrl = q[0] >> 4; /* from mcd.c */
+ qp->cdsc_trk = q[1];
+ qp->cdsc_ind = q[2];
+ if (qp->cdsc_format == CDROM_MSF) {
+ qp->cdsc_reladdr.msf.minute = q[3];
+ qp->cdsc_reladdr.msf.second = q[4];
+ qp->cdsc_reladdr.msf.frame = q[5];
+ qp->cdsc_absaddr.msf.minute = q[7];
+ qp->cdsc_absaddr.msf.second = q[8];
+ qp->cdsc_absaddr.msf.frame = q[9];
+ } else {
+ qp->cdsc_reladdr.lba = f_s_m2lba(q[5], q[4], q[3]);
+ qp->cdsc_absaddr.lba = f_s_m2lba(q[9], q[8], q[7]);
+ }
+ get_drive_status();
+ if (cd->dsb & dsb_play_in_progress)
+ qp->cdsc_audiostatus = CDROM_AUDIO_PLAY;
+ else if (PAUSED)
+ qp->cdsc_audiostatus = CDROM_AUDIO_PAUSED;
+ else
+ qp->cdsc_audiostatus = CDROM_AUDIO_NO_STATUS;
+ return 0;
}
void invalidate_toc(void)
{
- memset(cd->toc, 0, sizeof(cd->toc));
- memset(cd->disc_status, 0, sizeof(cd->disc_status));
+ memset(cd->toc, 0, sizeof(cd->toc));
+ memset(cd->disc_status, 0, sizeof(cd->disc_status));
}
/* cdrom.c guarantees that cdte_format == CDROM_MSF */
-void get_toc_entry(struct cdrom_tocentry * ep)
+void get_toc_entry(struct cdrom_tocentry *ep)
{
- uch track = normalize_track(ep->cdte_track);
- update_toc_entry(track);
- ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
- ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
- ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
- ep->cdte_adr = cd->toc[track].q0 & 0xf;
- ep->cdte_ctrl = cd->toc[track].q0 >> 4;
- ep->cdte_datamode=0;
+ uch track = normalize_track(ep->cdte_track);
+ update_toc_entry(track);
+ ep->cdte_addr.msf.frame = cd->toc[track].fsm[0];
+ ep->cdte_addr.msf.second = cd->toc[track].fsm[1];
+ ep->cdte_addr.msf.minute = cd->toc[track].fsm[2];
+ ep->cdte_adr = cd->toc[track].q0 & 0xf;
+ ep->cdte_ctrl = cd->toc[track].q0 >> 4;
+ ep->cdte_datamode = 0;
}
/* Audio ioctl. Ioctl commands connected to audio are in such an
* upon success. Memory checking has been done by cdrom_ioctl(), the
* calling function, as well as LBA/MSF sanitization.
*/
-int cm206_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
- void * arg)
+int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+ void *arg)
{
- switch (cmd) {
- case CDROMREADTOCHDR:
- return read_toc_header((struct cdrom_tochdr *) arg);
- case CDROMREADTOCENTRY:
- get_toc_entry((struct cdrom_tocentry *) arg);
- return 0;
- case CDROMPLAYMSF:
- play_from_to_msf((struct cdrom_msf *) arg);
- return 0;
- case CDROMPLAYTRKIND: /* admittedly, not particularly beautiful */
- play_from_to_track(((struct cdrom_ti *)arg)->cdti_trk0,
- ((struct cdrom_ti *)arg)->cdti_trk1);
- return 0;
- case CDROMSTOP:
- PAUSED=0;
- if (cd->dsb & dsb_play_in_progress) return type_0_command(c_stop, 1);
- else return 0;
- case CDROMPAUSE:
- get_drive_status();
- if (cd->dsb & dsb_play_in_progress) {
- type_0_command(c_stop, 1);
- type_1_command(c_audio_status, 5, cd->audio_status);
- PAUSED=1; /* say we're paused */
- }
- return 0;
- case CDROMRESUME:
- if (PAUSED) play_from_to_track(0,0);
- PAUSED=0;
- return 0;
- case CDROMSTART:
- case CDROMVOLCTRL:
- return 0;
- case CDROMSUBCHNL:
- return get_current_q((struct cdrom_subchnl *)arg);
- default:
- return -EINVAL;
- }
+ switch (cmd) {
+ case CDROMREADTOCHDR:
+ return read_toc_header((struct cdrom_tochdr *) arg);
+ case CDROMREADTOCENTRY:
+ get_toc_entry((struct cdrom_tocentry *) arg);
+ return 0;
+ case CDROMPLAYMSF:
+ play_from_to_msf((struct cdrom_msf *) arg);
+ return 0;
+ case CDROMPLAYTRKIND: /* admittedly, not particularly beautiful */
+ play_from_to_track(((struct cdrom_ti *) arg)->cdti_trk0,
+ ((struct cdrom_ti *) arg)->cdti_trk1);
+ return 0;
+ case CDROMSTOP:
+ PAUSED = 0;
+ if (cd->dsb & dsb_play_in_progress)
+ return type_0_command(c_stop, 1);
+ else
+ return 0;
+ case CDROMPAUSE:
+ get_drive_status();
+ if (cd->dsb & dsb_play_in_progress) {
+ type_0_command(c_stop, 1);
+ type_1_command(c_audio_status, 5,
+ cd->audio_status);
+ PAUSED = 1; /* say we're paused */
+ }
+ return 0;
+ case CDROMRESUME:
+ if (PAUSED)
+ play_from_to_track(0, 0);
+ PAUSED = 0;
+ return 0;
+ case CDROMSTART:
+ case CDROMVOLCTRL:
+ return 0;
+ case CDROMSUBCHNL:
+ return get_current_q((struct cdrom_subchnl *) arg);
+ default:
+ return -EINVAL;
+ }
}
/* Ioctl. These ioctls are specific to the cm206 driver. I have made
some driver statistics accessible through ioctl calls.
*/
-static int cm206_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
+static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
unsigned long arg)
{
- switch (cmd) {
+ switch (cmd) {
#ifdef STATISTICS
- case CM206CTL_GET_STAT:
- if (arg >= NR_STATS) return -EINVAL;
- else return cd->stats[arg];
- case CM206CTL_GET_LAST_STAT:
- if (arg >= NR_STATS) return -EINVAL;
- else return cd->last_stat[arg];
-#endif
- default:
- debug(("Unknown ioctl call 0x%x\n", cmd));
- return -EINVAL;
- }
-}
-
-int cm206_media_changed(struct cdrom_device_info * cdi, int disc_nr)
+ case CM206CTL_GET_STAT:
+ if (arg >= NR_STATS)
+ return -EINVAL;
+ else
+ return cd->stats[arg];
+ case CM206CTL_GET_LAST_STAT:
+ if (arg >= NR_STATS)
+ return -EINVAL;
+ else
+ return cd->last_stat[arg];
+#endif
+ default:
+ debug(("Unknown ioctl call 0x%x\n", cmd));
+ return -EINVAL;
+ }
+}
+
+int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
- if (cd != NULL) {
- int r;
- get_drive_status(); /* ensure cd->media_changed OK */
- r = cd->media_changed;
- cd->media_changed = 0; /* clear bit */
- return r;
- }
- else return -EIO;
+ if (cd != NULL) {
+ int r;
+ get_drive_status(); /* ensure cd->media_changed OK */
+ r = cd->media_changed;
+ cd->media_changed = 0; /* clear bit */
+ return r;
+ } else
+ return -EIO;
}
/* The new generic cdrom support. Routines should be concise, most of
the logic should be in cdrom.c */
/* returns number of times device is in use */
-int cm206_open_files(struct cdrom_device_info * cdi)
+int cm206_open_files(struct cdrom_device_info *cdi)
{
- if (cd) return cd->openfiles;
- return -1;
+ if (cd)
+ return cd->openfiles;
+ return -1;
}
/* controls tray movement */
-int cm206_tray_move(struct cdrom_device_info * cdi, int position)
+int cm206_tray_move(struct cdrom_device_info *cdi, int position)
{
- if (position) { /* 1: eject */
- type_0_command(c_open_tray,1);
- invalidate_toc();
- }
- else type_0_command(c_close_tray, 1); /* 0: close */
- return 0;
+ if (position) { /* 1: eject */
+ type_0_command(c_open_tray, 1);
+ invalidate_toc();
+ } else
+ type_0_command(c_close_tray, 1); /* 0: close */
+ return 0;
}
/* gives current state of the drive */
-int cm206_drive_status(struct cdrom_device_info * cdi, int slot_nr)
+int cm206_drive_status(struct cdrom_device_info *cdi, int slot_nr)
{
- get_drive_status();
- if (cd->dsb & dsb_tray_not_closed) return CDS_TRAY_OPEN;
- if (!(cd->dsb & dsb_disc_present)) return CDS_NO_DISC;
- if (cd->dsb & dsb_drive_not_ready) return CDS_DRIVE_NOT_READY;
- return CDS_DISC_OK;
+ get_drive_status();
+ if (cd->dsb & dsb_tray_not_closed)
+ return CDS_TRAY_OPEN;
+ if (!(cd->dsb & dsb_disc_present))
+ return CDS_NO_DISC;
+ if (cd->dsb & dsb_drive_not_ready)
+ return CDS_DRIVE_NOT_READY;
+ return CDS_DISC_OK;
}
-
+
/* locks or unlocks door lock==1: lock; return 0 upon success */
-int cm206_lock_door(struct cdrom_device_info * cdi, int lock)
+int cm206_lock_door(struct cdrom_device_info *cdi, int lock)
{
- uch command = (lock) ? c_lock_tray : c_unlock_tray;
- type_0_command(command, 1); /* wait and get dsb */
- /* the logic calculates the success, 0 means successful */
- return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
+ uch command = (lock) ? c_lock_tray : c_unlock_tray;
+ type_0_command(command, 1); /* wait and get dsb */
+ /* the logic calculates the success, 0 means successful */
+ return lock ^ ((cd->dsb & dsb_tray_locked) != 0);
}
-
+
/* Although a session start should be in LBA format, we return it in
MSF format because it is slightly easier, and the new generic ioctl
will take care of the necessary conversion. */
-int cm206_get_last_session(struct cdrom_device_info * cdi,
- struct cdrom_multisession * mssp)
+int cm206_get_last_session(struct cdrom_device_info *cdi,
+ struct cdrom_multisession *mssp)
{
- if (!FIRST_TRACK) get_disc_status();
- if (mssp != NULL) {
- if (DISC_STATUS & cds_multi_session) { /* multi-session */
- mssp->addr.msf.frame = cd->disc_status[3];
- mssp->addr.msf.second = cd->disc_status[4];
- mssp->addr.msf.minute = cd->disc_status[5];
- mssp->addr_format = CDROM_MSF;
- mssp->xa_flag = 1;
- } else {
- mssp->xa_flag = 0;
- }
- return 1;
- }
- return 0;
+ if (!FIRST_TRACK)
+ get_disc_status();
+ if (mssp != NULL) {
+ if (DISC_STATUS & cds_multi_session) { /* multi-session */
+ mssp->addr.msf.frame = cd->disc_status[3];
+ mssp->addr.msf.second = cd->disc_status[4];
+ mssp->addr.msf.minute = cd->disc_status[5];
+ mssp->addr_format = CDROM_MSF;
+ mssp->xa_flag = 1;
+ } else {
+ mssp->xa_flag = 0;
+ }
+ return 1;
+ }
+ return 0;
}
-int cm206_get_upc(struct cdrom_device_info * cdi, struct cdrom_mcn * mcn)
+int cm206_get_upc(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
{
- uch upc[10];
- char * ret = mcn->medium_catalog_number;
- int i;
-
- if (type_1_command(c_read_upc, 10, upc)) return -EIO;
- for (i=0; i<13; i++) {
- int w=i/2+1, r=i%2;
- if (r) ret[i] = 0x30 | (upc[w] & 0x0f);
- else ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
- }
- ret[13] = '\0';
- return 0;
-}
-
-int cm206_reset(struct cdrom_device_info * cdi)
+ uch upc[10];
+ char *ret = mcn->medium_catalog_number;
+ int i;
+
+ if (type_1_command(c_read_upc, 10, upc))
+ return -EIO;
+ for (i = 0; i < 13; i++) {
+ int w = i / 2 + 1, r = i % 2;
+ if (r)
+ ret[i] = 0x30 | (upc[w] & 0x0f);
+ else
+ ret[i] = 0x30 | ((upc[w] >> 4) & 0x0f);
+ }
+ ret[13] = '\0';
+ return 0;
+}
+
+int cm206_reset(struct cdrom_device_info *cdi)
{
- stop_read();
- reset_cm260();
- outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
- mdelay(1); /* 750 musec minimum */
- outw(dc_normal | READ_AHEAD, r_data_control);
- cd->sector_last = -1; /* flag no data buffered */
- cd->adapter_last = -1;
- invalidate_toc();
- return 0;
+ stop_read();
+ reset_cm260();
+ outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
+ mdelay(1); /* 750 musec minimum */
+ outw(dc_normal | READ_AHEAD, r_data_control);
+ cd->sector_last = -1; /* flag no data buffered */
+ cd->adapter_last = -1;
+ invalidate_toc();
+ return 0;
}
-int cm206_select_speed(struct cdrom_device_info * cdi, int speed)
+int cm206_select_speed(struct cdrom_device_info *cdi, int speed)
{
- int r;
- switch (speed) {
- case 0:
- r = type_0_command(c_auto_mode, 1);
- break;
- case 1:
- r = type_0_command(c_force_1x, 1);
- break;
- case 2:
- r = type_0_command(c_force_2x, 1);
- break;
- default:
- return -1;
- }
- if (r<0) return r;
- else return 1;
+ int r;
+ switch (speed) {
+ case 0:
+ r = type_0_command(c_auto_mode, 1);
+ break;
+ case 1:
+ r = type_0_command(c_force_1x, 1);
+ break;
+ case 2:
+ r = type_0_command(c_force_2x, 1);
+ break;
+ default:
+ return -1;
+ }
+ if (r < 0)
+ return r;
+ else
+ return 1;
}
static struct cdrom_device_ops cm206_dops = {
- open: cm206_open,
- release: cm206_release,
- drive_status: cm206_drive_status,
- media_changed: cm206_media_changed,
- tray_move: cm206_tray_move,
- lock_door: cm206_lock_door,
- select_speed: cm206_select_speed,
- get_last_session: cm206_get_last_session,
- get_mcn: cm206_get_upc,
- reset: cm206_reset,
- audio_ioctl: cm206_audio_ioctl,
- dev_ioctl: cm206_ioctl,
- capability: CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
- CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
- CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
- CDC_IOCTLS | CDC_DRIVE_STATUS,
- n_minors: 1,
+ open:cm206_open,
+ release:cm206_release,
+ drive_status:cm206_drive_status,
+ media_changed:cm206_media_changed,
+ tray_move:cm206_tray_move,
+ lock_door:cm206_lock_door,
+ select_speed:cm206_select_speed,
+ get_last_session:cm206_get_last_session,
+ get_mcn:cm206_get_upc,
+ reset:cm206_reset,
+ audio_ioctl:cm206_audio_ioctl,
+ dev_ioctl:cm206_ioctl,
+ capability:CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
+ CDC_MULTI_SESSION | CDC_MEDIA_CHANGED |
+ CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED |
+ CDC_IOCTLS | CDC_DRIVE_STATUS,
+ n_minors:1,
};
static struct cdrom_device_info cm206_info = {
- ops: &cm206_dops,
- speed: 2,
- capacity: 1,
- name: "cm206",
+ ops:&cm206_dops,
+ speed:2,
+ capacity:1,
+ name:"cm206",
};
/* This routine gets called during initialization if things go wrong,
* can be used in cleanup_module as well. */
static void cleanup(int level)
{
- switch (level) {
- case 4:
- if (unregister_cdrom(&cm206_info)) {
- printk("Can't unregister cdrom cm206\n");
- return;
- }
- if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
- printk("Can't unregister major cm206\n");
- return;
- }
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- case 3:
- free_irq(cm206_irq, NULL);
- case 2:
- case 1:
- kfree(cd);
- release_region(cm206_base, 16);
- default:;
- }
+ switch (level) {
+ case 4:
+ if (unregister_cdrom(&cm206_info)) {
+ printk("Can't unregister cdrom cm206\n");
+ return;
+ }
+ if (devfs_unregister_blkdev(MAJOR_NR, "cm206")) {
+ printk("Can't unregister major cm206\n");
+ return;
+ }
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ case 3:
+ free_irq(cm206_irq, NULL);
+ case 2:
+ case 1:
+ kfree(cd);
+ release_region(cm206_base, 16);
+ default:;
+ }
}
/* This function probes for the adapter card. It returns the base
*/
int __init probe_base_port(int base)
{
- int b=0x300, e=0x370; /* this is the range of start addresses */
- volatile int fool, i;
-
- if (base) b=e=base;
- for (base=b; base<=e; base += 0x10) {
- if (check_region(base, 0x10)) continue;
- for (i=0; i<3; i++)
- fool = inw(base+2); /* empty possibly uart_receive_buffer */
- if((inw(base+6) & 0xffef) != 0x0001 || /* line_status */
- (inw(base) & 0xad00) != 0) /* data status */
- continue;
- return(base);
- }
- return 0;
+ int b = 0x300, e = 0x370; /* this is the range of start addresses */
+ volatile int fool, i;
+
+ if (base)
+ b = e = base;
+ for (base = b; base <= e; base += 0x10) {
+ if (check_region(base, 0x10))
+ continue;
+ for (i = 0; i < 3; i++)
+ fool = inw(base + 2); /* empty possibly uart_receive_buffer */
+ if ((inw(base + 6) & 0xffef) != 0x0001 || /* line_status */
+ (inw(base) & 0xad00) != 0) /* data status */
+ continue;
+ return (base);
+ }
+ return 0;
}
#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
/* Probe for irq# nr. If nr==0, probe for all possible irq's. */
-int __init probe_irq(int nr){
- int irqs, irq;
- outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */
- sti();
- irqs = probe_irq_on();
- reset_cm260(); /* causes interrupt */
- udelay(100); /* wait for it */
- irq = probe_irq_off(irqs);
- outw(dc_normal | READ_AHEAD, r_data_control); /* services interrupt */
- if (nr && irq!=nr && irq>0) return 0; /* wrong interrupt happened */
- else return irq;
+int __init probe_irq(int nr)
+{
+ int irqs, irq;
+ outw(dc_normal | READ_AHEAD, r_data_control); /* disable irq-generation */
+ sti();
+ irqs = probe_irq_on();
+ reset_cm260(); /* causes interrupt */
+ udelay(100); /* wait for it */
+ irq = probe_irq_off(irqs);
+ outw(dc_normal | READ_AHEAD, r_data_control); /* services interrupt */
+ if (nr && irq != nr && irq > 0)
+ return 0; /* wrong interrupt happened */
+ else
+ return irq;
}
#endif
int __init cm206_init(void)
{
- uch e=0;
- long int size=sizeof(struct cm206_struct);
-
- printk(KERN_INFO "cm206 cdrom driver " REVISION);
- cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
- if (!cm206_base) {
- printk(" can't find adapter!\n");
- return -EIO;
- }
- printk(" adapter at 0x%x", cm206_base);
- request_region(cm206_base, 16, "cm206");
- cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
- if (!cd) return -EIO;
- /* Now we have found the adaptor card, try to reset it. As we have
- * found out earlier, this process generates an interrupt as well,
- * so we might just exploit that fact for irq probing! */
+ uch e = 0;
+ long int size = sizeof(struct cm206_struct);
+
+ printk(KERN_INFO "cm206 cdrom driver " REVISION);
+ cm206_base = probe_base_port(auto_probe ? 0 : cm206_base);
+ if (!cm206_base) {
+ printk(" can't find adapter!\n");
+ return -EIO;
+ }
+ printk(" adapter at 0x%x", cm206_base);
+ request_region(cm206_base, 16, "cm206");
+ cd = (struct cm206_struct *) kmalloc(size, GFP_KERNEL);
+ if (!cd)
+ return -EIO;
+ /* Now we have found the adaptor card, try to reset it. As we have
+ * found out earlier, this process generates an interrupt as well,
+ * so we might just exploit that fact for irq probing! */
#if !defined(MODULE) || defined(AUTO_PROBE_MODULE)
- cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
- if (cm206_irq<=0) {
- printk("can't find IRQ!\n");
- cleanup(1);
- return -EIO;
- }
- else printk(" IRQ %d found\n", cm206_irq);
+ cm206_irq = probe_irq(auto_probe ? 0 : cm206_irq);
+ if (cm206_irq <= 0) {
+ printk("can't find IRQ!\n");
+ cleanup(1);
+ return -EIO;
+ } else
+ printk(" IRQ %d found\n", cm206_irq);
#else
- cli();
- reset_cm260();
- /* Now, the problem here is that reset_cm260 can generate an
- interrupt. It seems that this can cause a kernel oops some time
- later. So we wait a while and `service' this interrupt. */
- mdelay(1);
- outw(dc_normal | READ_AHEAD, r_data_control);
- sti();
- printk(" using IRQ %d\n", cm206_irq);
+ cli();
+ reset_cm260();
+ /* Now, the problem here is that reset_cm260 can generate an
+ interrupt. It seems that this can cause a kernel oops some time
+ later. So we wait a while and `service' this interrupt. */
+ mdelay(1);
+ outw(dc_normal | READ_AHEAD, r_data_control);
+ sti();
+ printk(" using IRQ %d\n", cm206_irq);
#endif
- if (send_receive_polled(c_drive_configuration) != c_drive_configuration)
- {
- printk(KERN_INFO " drive not there\n");
- cleanup(1);
- return -EIO;
- }
- e = send_receive_polled(c_gimme);
- printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
- if (e & dcf_transfer_rate) printk(" double");
- else printk(" single");
- printk(" speed drive");
- if (e & dcf_motorized_tray) printk(", motorized tray");
- if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
- printk("\nUnable to reserve IRQ---aborted\n");
- cleanup(2);
- return -EIO;
- }
- printk(".\n");
- if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
- printk(KERN_INFO "Cannot register for major %d!\n", MAJOR_NR);
- cleanup(3);
- return -EIO;
- }
- cm206_info.dev = MKDEV(MAJOR_NR,0);
- if (register_cdrom(&cm206_info) != 0) {
- printk(KERN_INFO "Cannot register for cdrom %d!\n", MAJOR_NR);
- cleanup(3);
- return -EIO;
- }
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
- blksize_size[MAJOR_NR] = cm206_blocksizes;
- read_ahead[MAJOR_NR] = 16; /* reads ahead what? */
- init_bh(CM206_BH, cm206_bh);
-
- memset(cd, 0, sizeof(*cd)); /* give'm some reasonable value */
- cd->sector_last = -1; /* flag no data buffered */
- cd->adapter_last = -1;
- cd->timer.function = cm206_timeout;
- cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
- printk(KERN_INFO "%d kB adapter memory available, "
- " %ld bytes kernel memory used.\n", cd->max_sectors*2, size);
- return 0;
+ if (send_receive_polled(c_drive_configuration) !=
+ c_drive_configuration) {
+ printk(KERN_INFO " drive not there\n");
+ cleanup(1);
+ return -EIO;
+ }
+ e = send_receive_polled(c_gimme);
+ printk(KERN_INFO "Firmware revision %d", e & dcf_revision_code);
+ if (e & dcf_transfer_rate)
+ printk(" double");
+ else
+ printk(" single");
+ printk(" speed drive");
+ if (e & dcf_motorized_tray)
+ printk(", motorized tray");
+ if (request_irq(cm206_irq, cm206_interrupt, 0, "cm206", NULL)) {
+ printk("\nUnable to reserve IRQ---aborted\n");
+ cleanup(2);
+ return -EIO;
+ }
+ printk(".\n");
+ if (devfs_register_blkdev(MAJOR_NR, "cm206", &cdrom_fops) != 0) {
+ printk(KERN_INFO "Cannot register for major %d!\n",
+ MAJOR_NR);
+ cleanup(3);
+ return -EIO;
+ }
+ cm206_info.dev = MKDEV(MAJOR_NR, 0);
+ if (register_cdrom(&cm206_info) != 0) {
+ printk(KERN_INFO "Cannot register for cdrom %d!\n",
+ MAJOR_NR);
+ cleanup(3);
+ return -EIO;
+ }
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+ blksize_size[MAJOR_NR] = cm206_blocksizes;
+ read_ahead[MAJOR_NR] = 16; /* reads ahead what? */
+ init_bh(CM206_BH, cm206_bh);
+
+ memset(cd, 0, sizeof(*cd)); /* give'm some reasonable value */
+ cd->sector_last = -1; /* flag no data buffered */
+ cd->adapter_last = -1;
+ cd->timer.function = cm206_timeout;
+ cd->max_sectors = (inw(r_data_status) & ds_ram_size) ? 24 : 97;
+ printk(KERN_INFO "%d kB adapter memory available, "
+ " %ld bytes kernel memory used.\n", cd->max_sectors * 2,
+ size);
+ return 0;
}
#ifdef MODULE
static void __init parse_options(void)
{
- int i;
- for (i=0; i<2; i++) {
- if (0x300 <= cm206[i] && i<= 0x370 && cm206[i] % 0x10 == 0) {
- cm206_base = cm206[i];
- auto_probe=0;
- }
- else if (3 <= cm206[i] && cm206[i] <= 15) {
- cm206_irq = cm206[i];
- auto_probe=0;
- }
- }
+ int i;
+ for (i = 0; i < 2; i++) {
+ if (0x300 <= cm206[i] && i <= 0x370
+ && cm206[i] % 0x10 == 0) {
+ cm206_base = cm206[i];
+ auto_probe = 0;
+ } else if (3 <= cm206[i] && cm206[i] <= 15) {
+ cm206_irq = cm206[i];
+ auto_probe = 0;
+ }
+ }
}
int __cm206_init(void)
{
parse_options();
#if !defined(AUTO_PROBE_MODULE)
- auto_probe=0;
+ auto_probe = 0;
#endif
return cm206_init();
}
void __exit cm206_exit(void)
{
- cleanup(4);
- printk(KERN_INFO "cm206 removed\n");
+ cleanup(4);
+ printk(KERN_INFO "cm206 removed\n");
}
module_init(__cm206_init);
module_exit(cm206_exit);
-
-#else /* !MODULE */
+
+#else /* !MODULE */
/* This setup function accepts either `auto' or numbers in the range
* 3--11 (for irq) or 0x300--0x370 (for base port) or both. */
static int __init cm206_setup(char *s)
{
- int i, p[4];
-
- (void)get_options(s, ARRAY_SIZE(p), p);
-
- if (!strcmp(s, "auto")) auto_probe=1;
- for(i=1; i<=p[0]; i++) {
- if (0x300 <= p[i] && i<= 0x370 && p[i] % 0x10 == 0) {
- cm206_base = p[i];
- auto_probe = 0;
- }
- else if (3 <= p[i] && p[i] <= 15) {
- cm206_irq = p[i];
- auto_probe = 0;
- }
- }
- return 1;
+ int i, p[4];
+
+ (void) get_options(s, ARRAY_SIZE(p), p);
+
+ if (!strcmp(s, "auto"))
+ auto_probe = 1;
+ for (i = 1; i <= p[0]; i++) {
+ if (0x300 <= p[i] && i <= 0x370 && p[i] % 0x10 == 0) {
+ cm206_base = p[i];
+ auto_probe = 0;
+ } else if (3 <= p[i] && p[i] <= 15) {
+ cm206_irq = p[i];
+ auto_probe = 0;
+ }
+ }
+ return 1;
}
__setup("cm206=", cm206_setup);
-#endif /* !MODULE */
+#endif /* !MODULE */
+
+
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h -c -o cm206.o cm206.c"
*/
-/* These settings are for various debug-level. Leave they untouched ... */
-#define NO_GSCD_DEBUG
+/* These settings are for various debug-level. Leave they untouched ... */
+#define NO_GSCD_DEBUG
#define NO_IOCTL_DEBUG
#define NO_MODULE_DEBUG
#define NO_FUTURE_WORK
#define MAJOR_NR GOLDSTAR_CDROM_MAJOR
#include <linux/blk.h>
-#define gscd_port gscd /* for compatible parameter passing with "insmod" */
+#define gscd_port gscd /* for compatible parameter passing with "insmod" */
#include "gscd.h"
-static int gscd_blocksizes[1] = {512};
+static int gscd_blocksizes[1] = { 512 };
-static int gscdPresent = 0;
+static int gscdPresent = 0;
-static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
-static int gscd_bn = -1;
-static short gscd_port = GSCD_BASE_ADDR;
+static unsigned char gscd_buf[2048]; /* buffer for block size conversion */
+static int gscd_bn = -1;
+static short gscd_port = GSCD_BASE_ADDR;
MODULE_PARM(gscd, "h");
/* Kommt spaeter vielleicht noch mal dran ...
* static DECLARE_WAIT_QUEUE_HEAD(gscd_waitq);
- */
+ */
-static void gscd_transfer (void);
-static void gscd_read_cmd (void);
-static void gscd_hsg2msf (long hsg, struct msf *msf);
-static void gscd_bin2bcd (unsigned char *p);
+static void gscd_transfer(void);
+static void gscd_read_cmd(void);
+static void gscd_hsg2msf(long hsg, struct msf *msf);
+static void gscd_bin2bcd(unsigned char *p);
/* Schnittstellen zum Kern/FS */
-static void do_gscd_request (request_queue_t *);
-static void __do_gscd_request (unsigned long dummy);
-static int gscd_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
-static int gscd_open (struct inode *, struct file *);
-static int gscd_release (struct inode *, struct file *);
-static int check_gscd_med_chg (kdev_t);
+static void do_gscd_request(request_queue_t *);
+static void __do_gscd_request(unsigned long dummy);
+static int gscd_ioctl(struct inode *, struct file *, unsigned int,
+ unsigned long);
+static int gscd_open(struct inode *, struct file *);
+static int gscd_release(struct inode *, struct file *);
+static int check_gscd_med_chg(kdev_t);
/* GoldStar Funktionen */
-static void cc_Reset (void);
-static int wait_drv_ready (void);
-static int find_drives (void);
-static void cmd_out (int, char *, char *, int);
-static void cmd_status (void);
-static void cc_Ident (char *);
-static void cc_SetSpeed (void);
-static void init_cd_drive (int);
+static void cc_Reset(void);
+static int wait_drv_ready(void);
+static int find_drives(void);
+static void cmd_out(int, char *, char *, int);
+static void cmd_status(void);
+static void cc_Ident(char *);
+static void cc_SetSpeed(void);
+static void init_cd_drive(int);
-static int get_status (void);
-static void clear_Audio (void);
-static void cc_invalidate (void);
+static int get_status(void);
+static void clear_Audio(void);
+static void cc_invalidate(void);
/* some things for the next version */
#ifdef FUTURE_WORK
-static void update_state (void);
-static long gscd_msf2hsg (struct msf *mp);
-static int gscd_bcd2bin (unsigned char bcd);
+static void update_state(void);
+static long gscd_msf2hsg(struct msf *mp);
+static int gscd_bcd2bin(unsigned char bcd);
#endif
/* common GoldStar Initialization */
-static int my_gscd_init (void);
+static int my_gscd_init(void);
/* lo-level cmd-Funktionen */
-static void cmd_info_in ( char *, int );
-static void cmd_end ( void );
-static void cmd_read_b ( char *, int, int );
-static void cmd_read_w ( char *, int, int );
-static int cmd_unit_alive ( void );
-static void cmd_write_cmd ( char * );
+static void cmd_info_in(char *, int);
+static void cmd_end(void);
+static void cmd_read_b(char *, int, int);
+static void cmd_read_w(char *, int, int);
+static int cmd_unit_alive(void);
+static void cmd_write_cmd(char *);
/* GoldStar Variablen */
-static int curr_drv_state;
-static int drv_states[] = {0,0,0,0,0,0,0,0};
-static int drv_mode;
-static int disk_state;
-static int speed;
-static int ndrives;
+static int curr_drv_state;
+static int drv_states[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static int drv_mode;
+static int disk_state;
+static int speed;
+static int ndrives;
static unsigned char drv_num_read;
static unsigned char f_dsk_valid;
static char f_AudioPlay;
static char f_AudioPause;
-static int AudioStart_m;
-static int AudioStart_f;
-static int AudioEnd_m;
-static int AudioEnd_f;
-
+static int AudioStart_m;
+static int AudioStart_f;
+static int AudioEnd_m;
+static int AudioEnd_f;
+
static struct timer_list gscd_timer;
static struct block_device_operations gscd_fops = {
- open: gscd_open,
- release: gscd_release,
- ioctl: gscd_ioctl,
- check_media_change: check_gscd_med_chg,
+ open:gscd_open,
+ release:gscd_release,
+ ioctl:gscd_ioctl,
+ check_media_change:check_gscd_med_chg,
};
/*
* Checking if the media has been changed
* (not yet implemented)
*/
-static int check_gscd_med_chg (kdev_t full_dev)
+static int check_gscd_med_chg(kdev_t full_dev)
{
- int target;
+ int target;
- target = MINOR(full_dev);
+ target = MINOR(full_dev);
- if (target > 0)
- {
- printk("GSCD: GoldStar CD-ROM request error: invalid device.\n");
- return 0;
- }
+ if (target > 0) {
+ printk
+ ("GSCD: GoldStar CD-ROM request error: invalid device.\n");
+ return 0;
+ }
+#ifdef GSCD_DEBUG
+ printk("gscd: check_med_change\n");
+#endif
- #ifdef GSCD_DEBUG
- printk ("gscd: check_med_change\n");
- #endif
-
- return 0;
+ return 0;
}
#ifndef MODULE
/* Using new interface for kernel-parameters */
-
-static int __init gscd_setup (char *str)
+
+static int __init gscd_setup(char *str)
{
- int ints[2];
- (void)get_options(str, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0)
- {
- gscd_port = ints[1];
- }
- return 1;
+ int ints[2];
+ (void) get_options(str, ARRAY_SIZE(ints), ints);
+
+ if (ints[0] > 0) {
+ gscd_port = ints[1];
+ }
+ return 1;
}
__setup("gscd=", gscd_setup);
#endif
-static int gscd_ioctl (struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg)
+static int gscd_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+ unsigned long arg)
{
-unsigned char to_do[10];
-unsigned char dummy;
+ unsigned char to_do[10];
+ unsigned char dummy;
-
- switch (cmd)
- {
- case CDROMSTART: /* Spin up the drive */
+
+ switch (cmd) {
+ case CDROMSTART: /* Spin up the drive */
/* Don't think we can do this. Even if we could,
- * I think the drive times out and stops after a while
+ * I think the drive times out and stops after a while
* anyway. For now, ignore it.
*/
- return 0;
+ return 0;
- case CDROMRESUME: /* keine Ahnung was das ist */
- return 0;
+ case CDROMRESUME: /* keine Ahnung was das ist */
+ return 0;
- case CDROMEJECT:
- cmd_status ();
- to_do[0] = CMD_TRAY_CTL;
- cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+ case CDROMEJECT:
+ cmd_status();
+ to_do[0] = CMD_TRAY_CTL;
+ cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
- return 0;
+ return 0;
- default:
- return -EINVAL;
- }
+ default:
+ return -EINVAL;
+ }
}
* When Linux gets variable block sizes this will probably go away.
*/
-static void gscd_transfer (void)
+static void gscd_transfer(void)
{
-long offs;
-
- while (CURRENT -> nr_sectors > 0 && gscd_bn == CURRENT -> sector / 4)
- {
- offs = (CURRENT -> sector & 3) * 512;
- memcpy(CURRENT -> buffer, gscd_buf + offs, 512);
- CURRENT -> nr_sectors--;
- CURRENT -> sector++;
- CURRENT -> buffer += 512;
+ long offs;
+
+ while (CURRENT->nr_sectors > 0 && gscd_bn == CURRENT->sector / 4) {
+ offs = (CURRENT->sector & 3) * 512;
+ memcpy(CURRENT->buffer, gscd_buf + offs, 512);
+ CURRENT->nr_sectors--;
+ CURRENT->sector++;
+ CURRENT->buffer += 512;
}
}
* I/O request routine called from Linux kernel.
*/
-static void do_gscd_request (request_queue_t * q)
+static void do_gscd_request(request_queue_t * q)
{
- __do_gscd_request(0);
+ __do_gscd_request(0);
}
-static void __do_gscd_request (unsigned long dummy)
+static void __do_gscd_request(unsigned long dummy)
{
-unsigned int block,dev;
-unsigned int nsect;
+ unsigned int block, dev;
+ unsigned int nsect;
-repeat:
+ repeat:
if (QUEUE_EMPTY || CURRENT->rq_status == RQ_INACTIVE)
goto out;
INIT_REQUEST;
block = CURRENT->sector;
nsect = CURRENT->nr_sectors;
- if (QUEUE_EMPTY || CURRENT -> sector == -1)
+ if (QUEUE_EMPTY || CURRENT->sector == -1)
goto out;
- if (CURRENT -> cmd != READ)
- {
- printk("GSCD: bad cmd %d\n", CURRENT -> cmd);
+ if (CURRENT->cmd != READ) {
+ printk("GSCD: bad cmd %d\n", CURRENT->cmd);
end_request(0);
goto repeat;
}
- if (MINOR(CURRENT -> rq_dev) != 0)
- {
+ if (MINOR(CURRENT->rq_dev) != 0) {
printk("GSCD: this version supports only one device\n");
end_request(0);
goto repeat;
/* if we satisfied the request from the buffer, we're done. */
- if (CURRENT -> nr_sectors == 0)
- {
+ if (CURRENT->nr_sectors == 0) {
end_request(1);
goto repeat;
}
-
#ifdef GSCD_DEBUG
- printk ("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect );
+ printk("GSCD: dev %d, block %d, nsect %d\n", dev, block, nsect);
#endif
- gscd_read_cmd ();
-out:
+ gscd_read_cmd();
+ out:
return;
}
* read-data command.
*/
-static void
-gscd_read_cmd (void)
+static void gscd_read_cmd(void)
{
-long block;
-struct gscd_Play_msf gscdcmd;
-char cmd[] = { CMD_READ, 0x80, 0,0,0, 0,1 }; /* cmd mode M-S-F secth sectl */
-
-
-
- cmd_status ();
- if ( disk_state & (ST_NO_DISK | ST_DOOR_OPEN) )
- {
- printk ( "GSCD: no disk or door open\n" );
- end_request (0);
- }
- else
- {
- if ( disk_state & ST_INVALID )
- {
- printk ( "GSCD: disk invalid\n" );
- end_request (0);
- }
- else
- {
- gscd_bn = -1; /* purge our buffer */
- block = CURRENT -> sector / 4;
- gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
-
- cmd[2] = gscdcmd.start.min;
- cmd[3] = gscdcmd.start.sec;
- cmd[4] = gscdcmd.start.frame;
+ long block;
+ struct gscd_Play_msf gscdcmd;
+ char cmd[] = { CMD_READ, 0x80, 0, 0, 0, 0, 1 }; /* cmd mode M-S-F secth sectl */
+
+
+
+ cmd_status();
+ if (disk_state & (ST_NO_DISK | ST_DOOR_OPEN)) {
+ printk("GSCD: no disk or door open\n");
+ end_request(0);
+ } else {
+ if (disk_state & ST_INVALID) {
+ printk("GSCD: disk invalid\n");
+ end_request(0);
+ } else {
+ gscd_bn = -1; /* purge our buffer */
+ block = CURRENT->sector / 4;
+ gscd_hsg2msf(block, &gscdcmd.start); /* cvt to msf format */
+
+ cmd[2] = gscdcmd.start.min;
+ cmd[3] = gscdcmd.start.sec;
+ cmd[4] = gscdcmd.start.frame;
#ifdef GSCD_DEBUG
- printk ("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3], cmd[4] );
-#endif
- cmd_out ( TYPE_DATA, (char *)&cmd, (char *)&gscd_buf[0], 1 );
-
- gscd_bn = CURRENT -> sector / 4;
- gscd_transfer();
- end_request(1);
- }
+ printk("GSCD: read msf %d:%d:%d\n", cmd[2], cmd[3],
+ cmd[4]);
+#endif
+ cmd_out(TYPE_DATA, (char *) &cmd,
+ (char *) &gscd_buf[0], 1);
+
+ gscd_bn = CURRENT->sector / 4;
+ gscd_transfer();
+ end_request(1);
+ }
}
SET_TIMER(__do_gscd_request, 1);
}
* Open the device special file. Check that a disk is in.
*/
-static int gscd_open (struct inode *ip, struct file *fp)
+static int gscd_open(struct inode *ip, struct file *fp)
{
-int st;
+ int st;
#ifdef GSCD_DEBUG
-printk ( "GSCD: open\n" );
+ printk("GSCD: open\n");
#endif
if (gscdPresent == 0)
- return -ENXIO; /* no hardware */
+ return -ENXIO; /* no hardware */
MOD_INC_USE_COUNT;
- get_status ();
- st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
- if ( st )
- {
- printk ( "GSCD: no disk or door open\n" );
- MOD_DEC_USE_COUNT;
- return -ENXIO;
- }
-
+ get_status();
+ st = disk_state & (ST_NO_DISK | ST_DOOR_OPEN);
+ if (st) {
+ printk("GSCD: no disk or door open\n");
+ MOD_DEC_USE_COUNT;
+ return -ENXIO;
+ }
+
/* if (updateToc() < 0)
return -EIO;
*/
* On close, we flush all gscd blocks from the buffer cache.
*/
-static int gscd_release (struct inode * inode, struct file * file)
+static int gscd_release(struct inode *inode, struct file *file)
{
#ifdef GSCD_DEBUG
-printk ( "GSCD: release\n" );
+ printk("GSCD: release\n");
#endif
gscd_bn = -1;
}
-int get_status (void)
+int get_status(void)
{
-int status;
-
- cmd_status ();
- status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
-
- if ( status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01) )
- {
- cc_invalidate ();
- return 1;
- }
- else
- {
- return 0;
- }
+ int status;
+
+ cmd_status();
+ status = disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01);
+
+ if (status == (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) {
+ cc_invalidate();
+ return 1;
+ } else {
+ return 0;
+ }
}
-void cc_invalidate (void)
+void cc_invalidate(void)
{
- drv_num_read = 0xFF;
- f_dsk_valid = 0xFF;
- current_drive = 0xFF;
- f_drv_ok = 0xFF;
+ drv_num_read = 0xFF;
+ f_dsk_valid = 0xFF;
+ current_drive = 0xFF;
+ f_drv_ok = 0xFF;
- clear_Audio ();
-
-}
+ clear_Audio();
+
+}
-void clear_Audio (void)
+void clear_Audio(void)
{
- f_AudioPlay = 0;
- f_AudioPause = 0;
- AudioStart_m = 0;
- AudioStart_f = 0;
- AudioEnd_m = 0;
- AudioEnd_f = 0;
-
+ f_AudioPlay = 0;
+ f_AudioPause = 0;
+ AudioStart_m = 0;
+ AudioStart_f = 0;
+ AudioEnd_m = 0;
+ AudioEnd_f = 0;
+
}
/*
* waiting ?
*/
-int wait_drv_ready (void)
+int wait_drv_ready(void)
{
-int found, read;
-
- do
- {
- found = inb ( GSCDPORT(0) );
- found &= 0x0f;
- read = inb ( GSCDPORT(0) );
- read &= 0x0f;
- } while ( read != found );
-
+ int found, read;
+
+ do {
+ found = inb(GSCDPORT(0));
+ found &= 0x0f;
+ read = inb(GSCDPORT(0));
+ read &= 0x0f;
+ } while (read != found);
+
#ifdef GSCD_DEBUG
-printk ( "Wait for: %d\n", read );
-#endif
-
- return read;
+ printk("Wait for: %d\n", read);
+#endif
+
+ return read;
}
-void cc_Ident (char * respons)
+void cc_Ident(char *respons)
{
-char to_do [] = {CMD_IDENT, 0, 0};
+ char to_do[] = { CMD_IDENT, 0, 0 };
- cmd_out (TYPE_INFO, (char *)&to_do, (char *)respons, (int)0x1E );
+ cmd_out(TYPE_INFO, (char *) &to_do, (char *) respons, (int) 0x1E);
}
-void cc_SetSpeed (void)
+void cc_SetSpeed(void)
{
-char to_do [] = {CMD_SETSPEED, 0, 0};
-char dummy;
-
- if ( speed > 0 )
- {
- to_do[1] = speed & 0x0F;
- cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
- }
+ char to_do[] = { CMD_SETSPEED, 0, 0 };
+ char dummy;
+
+ if (speed > 0) {
+ to_do[1] = speed & 0x0F;
+ cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
+ }
}
-void cc_Reset (void)
+void cc_Reset(void)
{
-char to_do [] = {CMD_RESET, 0};
-char dummy;
+ char to_do[] = { CMD_RESET, 0 };
+ char dummy;
- cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+ cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
}
-void cmd_status (void)
+void cmd_status(void)
{
-char to_do [] = {CMD_STATUS, 0};
-char dummy;
+ char to_do[] = { CMD_STATUS, 0 };
+ char dummy;
- cmd_out (TYPE_INFO, (char *)&to_do, (char *)&dummy, 0);
+ cmd_out(TYPE_INFO, (char *) &to_do, (char *) &dummy, 0);
#ifdef GSCD_DEBUG
-printk ("GSCD: Status: %d\n", disk_state );
+ printk("GSCD: Status: %d\n", disk_state);
#endif
}
-void cmd_out ( int cmd_type, char * cmd, char * respo_buf, int respo_count )
+void cmd_out(int cmd_type, char *cmd, char *respo_buf, int respo_count)
{
-int result;
-
-
- result = wait_drv_ready ();
- if ( result != drv_mode )
- {
- unsigned long test_loops = 0xFFFF;
- int i,dummy;
-
- outb ( curr_drv_state, GSCDPORT(0));
-
- /* LOCLOOP_170 */
- do
- {
- result = wait_drv_ready ();
- test_loops--;
- } while ( (result != drv_mode) && (test_loops > 0) );
-
- if ( result != drv_mode )
- {
- disk_state = ST_x08 | ST_x04 | ST_INVALID;
- return;
- }
-
- /* ...and waiting */
- for ( i=1,dummy=1 ; i<0xFFFF ; i++ )
- {
- dummy *= i;
- }
- }
-
- /* LOC_172 */
- /* check the unit */
- /* and wake it up */
- if ( cmd_unit_alive () != 0x08 )
- {
- /* LOC_174 */
- /* game over for this unit */
- disk_state = ST_x08 | ST_x04 | ST_INVALID;
- return;
- }
-
- /* LOC_176 */
- #ifdef GSCD_DEBUG
- printk ("LOC_176 ");
- #endif
- if ( drv_mode == 0x09 )
- {
- /* magic... */
- printk ("GSCD: magic ...\n");
- outb ( result, GSCDPORT(2));
- }
-
- /* write the command to the drive */
- cmd_write_cmd (cmd);
-
- /* LOC_178 */
- for (;;)
- {
- result = wait_drv_ready ();
- if ( result != drv_mode )
- {
- /* LOC_179 */
- if ( result == 0x04 ) /* Mode 4 */
- {
- /* LOC_205 */
- #ifdef GSCD_DEBUG
- printk ("LOC_205 ");
- #endif
- disk_state = inb ( GSCDPORT (2));
-
- do
- {
- result = wait_drv_ready ();
- } while ( result != drv_mode );
- return;
-
- }
- else
- {
- if ( result == 0x06 ) /* Mode 6 */
- {
- /* LOC_181 */
- #ifdef GSCD_DEBUG
- printk ("LOC_181 ");
- #endif
-
- if (cmd_type == TYPE_DATA)
- {
- /* read data */
- /* LOC_184 */
- if ( drv_mode == 9 )
- {
- /* read the data to the buffer (word) */
-
- /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
- cmd_read_w ( respo_buf, respo_count, CD_FRAMESIZE/2 );
- return;
- }
- else
- {
- /* read the data to the buffer (byte) */
-
- /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
- cmd_read_b ( respo_buf, respo_count, CD_FRAMESIZE );
- return;
- }
- }
- else
- {
- /* read the info to the buffer */
- cmd_info_in ( respo_buf, respo_count );
- return;
- }
-
- return;
- }
- }
-
- }
- else
- {
- disk_state = ST_x08 | ST_x04 | ST_INVALID;
- return;
- }
- } /* for (;;) */
+ int result;
+ result = wait_drv_ready();
+ if (result != drv_mode) {
+ unsigned long test_loops = 0xFFFF;
+ int i, dummy;
+
+ outb(curr_drv_state, GSCDPORT(0));
+
+ /* LOCLOOP_170 */
+ do {
+ result = wait_drv_ready();
+ test_loops--;
+ } while ((result != drv_mode) && (test_loops > 0));
+
+ if (result != drv_mode) {
+ disk_state = ST_x08 | ST_x04 | ST_INVALID;
+ return;
+ }
+
+ /* ...and waiting */
+ for (i = 1, dummy = 1; i < 0xFFFF; i++) {
+ dummy *= i;
+ }
+ }
+
+ /* LOC_172 */
+ /* check the unit */
+ /* and wake it up */
+ if (cmd_unit_alive() != 0x08) {
+ /* LOC_174 */
+ /* game over for this unit */
+ disk_state = ST_x08 | ST_x04 | ST_INVALID;
+ return;
+ }
+
+ /* LOC_176 */
+#ifdef GSCD_DEBUG
+ printk("LOC_176 ");
+#endif
+ if (drv_mode == 0x09) {
+ /* magic... */
+ printk("GSCD: magic ...\n");
+ outb(result, GSCDPORT(2));
+ }
+
+ /* write the command to the drive */
+ cmd_write_cmd(cmd);
+
+ /* LOC_178 */
+ for (;;) {
+ result = wait_drv_ready();
+ if (result != drv_mode) {
+ /* LOC_179 */
+ if (result == 0x04) { /* Mode 4 */
+ /* LOC_205 */
+#ifdef GSCD_DEBUG
+ printk("LOC_205 ");
+#endif
+ disk_state = inb(GSCDPORT(2));
+
+ do {
+ result = wait_drv_ready();
+ } while (result != drv_mode);
+ return;
+
+ } else {
+ if (result == 0x06) { /* Mode 6 */
+ /* LOC_181 */
#ifdef GSCD_DEBUG
-printk ("\n");
-#endif
+ printk("LOC_181 ");
+#endif
+
+ if (cmd_type == TYPE_DATA) {
+ /* read data */
+ /* LOC_184 */
+ if (drv_mode == 9) {
+ /* read the data to the buffer (word) */
+
+ /* (*(cmd+1))?(CD_FRAMESIZE/2):(CD_FRAMESIZE_RAW/2) */
+ cmd_read_w
+ (respo_buf,
+ respo_count,
+ CD_FRAMESIZE /
+ 2);
+ return;
+ } else {
+ /* read the data to the buffer (byte) */
+
+ /* (*(cmd+1))?(CD_FRAMESIZE):(CD_FRAMESIZE_RAW) */
+ cmd_read_b
+ (respo_buf,
+ respo_count,
+ CD_FRAMESIZE);
+ return;
+ }
+ } else {
+ /* read the info to the buffer */
+ cmd_info_in(respo_buf,
+ respo_count);
+ return;
+ }
+
+ return;
+ }
+ }
+
+ } else {
+ disk_state = ST_x08 | ST_x04 | ST_INVALID;
+ return;
+ }
+ } /* for (;;) */
+
+
+#ifdef GSCD_DEBUG
+ printk("\n");
+#endif
}
-static void cmd_write_cmd ( char *pstr )
+static void cmd_write_cmd(char *pstr)
{
-int i,j;
-
- /* LOC_177 */
- #ifdef GSCD_DEBUG
- printk ("LOC_177 ");
- #endif
-
- /* calculate the number of parameter */
- j = *pstr & 0x0F;
-
- /* shift it out */
- for ( i=0 ; i<j ; i++ )
- {
- outb ( *pstr, GSCDPORT(2) );
- pstr++;
- }
+ int i, j;
+
+ /* LOC_177 */
+#ifdef GSCD_DEBUG
+ printk("LOC_177 ");
+#endif
+
+ /* calculate the number of parameter */
+ j = *pstr & 0x0F;
+
+ /* shift it out */
+ for (i = 0; i < j; i++) {
+ outb(*pstr, GSCDPORT(2));
+ pstr++;
+ }
}
-static int cmd_unit_alive ( void )
+static int cmd_unit_alive(void)
{
-int result;
-unsigned long max_test_loops;
+ int result;
+ unsigned long max_test_loops;
+
+ /* LOC_172 */
+#ifdef GSCD_DEBUG
+ printk("LOC_172 ");
+#endif
- /* LOC_172 */
- #ifdef GSCD_DEBUG
- printk ("LOC_172 ");
- #endif
+ outb(curr_drv_state, GSCDPORT(0));
+ max_test_loops = 0xFFFF;
- outb ( curr_drv_state, GSCDPORT(0));
- max_test_loops = 0xFFFF;
-
- do
- {
- result = wait_drv_ready ();
- max_test_loops--;
- } while ( (result != 0x08) && (max_test_loops > 0) );
+ do {
+ result = wait_drv_ready();
+ max_test_loops--;
+ } while ((result != 0x08) && (max_test_loops > 0));
- return result;
-}
+ return result;
+}
-static void cmd_info_in ( char *pb, int count )
+static void cmd_info_in(char *pb, int count)
{
-int result;
-char read;
-
-
- /* read info */
- /* LOC_182 */
- #ifdef GSCD_DEBUG
- printk ("LOC_182 ");
- #endif
-
- do
- {
- read = inb (GSCDPORT(2));
- if ( count > 0 )
- {
- *pb = read;
- pb++;
- count--;
- }
-
- /* LOC_183 */
- do
- {
- result = wait_drv_ready ();
- } while ( result == 0x0E );
- } while ( result == 6 );
-
- cmd_end ();
- return;
+ int result;
+ char read;
+
+
+ /* read info */
+ /* LOC_182 */
+#ifdef GSCD_DEBUG
+ printk("LOC_182 ");
+#endif
+
+ do {
+ read = inb(GSCDPORT(2));
+ if (count > 0) {
+ *pb = read;
+ pb++;
+ count--;
+ }
+
+ /* LOC_183 */
+ do {
+ result = wait_drv_ready();
+ } while (result == 0x0E);
+ } while (result == 6);
+
+ cmd_end();
+ return;
}
-static void cmd_read_b ( char *pb, int count, int size )
+static void cmd_read_b(char *pb, int count, int size)
{
-int result;
-int i;
-
-
- /* LOC_188 */
- /* LOC_189 */
- #ifdef GSCD_DEBUG
- printk ("LOC_189 ");
- #endif
-
- do
- {
- do
- {
- result = wait_drv_ready ();
- } while ( result != 6 || result == 0x0E );
-
- if ( result != 6 )
- {
- cmd_end ();
- return;
- }
-
- #ifdef GSCD_DEBUG
- printk ("LOC_191 ");
- #endif
-
- for ( i=0 ; i< size ; i++ )
- {
- *pb = inb (GSCDPORT(2));
- pb++;
- }
- count--;
- } while ( count > 0 );
-
- cmd_end ();
- return;
+ int result;
+ int i;
+
+
+ /* LOC_188 */
+ /* LOC_189 */
+#ifdef GSCD_DEBUG
+ printk("LOC_189 ");
+#endif
+
+ do {
+ do {
+ result = wait_drv_ready();
+ } while (result != 6 || result == 0x0E);
+
+ if (result != 6) {
+ cmd_end();
+ return;
+ }
+#ifdef GSCD_DEBUG
+ printk("LOC_191 ");
+#endif
+
+ for (i = 0; i < size; i++) {
+ *pb = inb(GSCDPORT(2));
+ pb++;
+ }
+ count--;
+ } while (count > 0);
+
+ cmd_end();
+ return;
}
-static void cmd_end (void)
+static void cmd_end(void)
{
-int result;
-
-
- /* LOC_204 */
- #ifdef GSCD_DEBUG
- printk ("LOC_204 ");
- #endif
-
- do
- {
- result = wait_drv_ready ();
- if ( result == drv_mode )
- {
- return;
- }
- } while ( result != 4 );
-
- /* LOC_205 */
- #ifdef GSCD_DEBUG
- printk ("LOC_205 ");
- #endif
-
- disk_state = inb ( GSCDPORT (2));
-
- do
- {
- result = wait_drv_ready ();
- } while ( result != drv_mode );
- return;
+ int result;
+
+
+ /* LOC_204 */
+#ifdef GSCD_DEBUG
+ printk("LOC_204 ");
+#endif
+
+ do {
+ result = wait_drv_ready();
+ if (result == drv_mode) {
+ return;
+ }
+ } while (result != 4);
+
+ /* LOC_205 */
+#ifdef GSCD_DEBUG
+ printk("LOC_205 ");
+#endif
+
+ disk_state = inb(GSCDPORT(2));
+
+ do {
+ result = wait_drv_ready();
+ } while (result != drv_mode);
+ return;
}
-static void cmd_read_w ( char *pb, int count, int size )
+static void cmd_read_w(char *pb, int count, int size)
{
-int result;
-int i;
-
-
- #ifdef GSCD_DEBUG
- printk ("LOC_185 ");
- #endif
-
- do
- {
- /* LOC_185 */
- do
- {
- result = wait_drv_ready ();
- } while ( result != 6 || result == 0x0E );
-
- if ( result != 6 )
- {
- cmd_end ();
- return;
- }
-
- for ( i=0 ; i<size ; i++ )
- {
- /* na, hier muss ich noch mal drueber nachdenken */
- *pb = inw(GSCDPORT(2));
- pb++;
- }
- count--;
- } while ( count > 0 );
-
- cmd_end ();
- return;
+ int result;
+ int i;
+
+
+#ifdef GSCD_DEBUG
+ printk("LOC_185 ");
+#endif
+
+ do {
+ /* LOC_185 */
+ do {
+ result = wait_drv_ready();
+ } while (result != 6 || result == 0x0E);
+
+ if (result != 6) {
+ cmd_end();
+ return;
+ }
+
+ for (i = 0; i < size; i++) {
+ /* na, hier muss ich noch mal drueber nachdenken */
+ *pb = inw(GSCDPORT(2));
+ pb++;
+ }
+ count--;
+ } while (count > 0);
+
+ cmd_end();
+ return;
}
-int __init find_drives (void)
+int __init find_drives(void)
{
-int *pdrv;
-int drvnum;
-int subdrv;
-int i;
-
- speed = 0;
- pdrv = (int *)&drv_states;
- curr_drv_state = 0xFE;
- subdrv = 0;
- drvnum = 0;
-
- for ( i=0 ; i<8 ; i++ )
- {
- subdrv++;
- cmd_status ();
- disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
- if ( disk_state != (ST_x08 | ST_x04 | ST_INVALID) )
- {
- /* LOC_240 */
- *pdrv = curr_drv_state;
- init_cd_drive (drvnum);
- pdrv++;
- drvnum++;
- }
- else
- {
- if ( subdrv < 2 )
- {
- continue;
- }
- else
- {
- subdrv = 0;
- }
- }
-
-/* curr_drv_state<<1; <-- das geht irgendwie nicht */
+ int *pdrv;
+ int drvnum;
+ int subdrv;
+ int i;
+
+ speed = 0;
+ pdrv = (int *) &drv_states;
+ curr_drv_state = 0xFE;
+ subdrv = 0;
+ drvnum = 0;
+
+ for (i = 0; i < 8; i++) {
+ subdrv++;
+ cmd_status();
+ disk_state &= ST_x08 | ST_x04 | ST_INVALID | ST_x01;
+ if (disk_state != (ST_x08 | ST_x04 | ST_INVALID)) {
+ /* LOC_240 */
+ *pdrv = curr_drv_state;
+ init_cd_drive(drvnum);
+ pdrv++;
+ drvnum++;
+ } else {
+ if (subdrv < 2) {
+ continue;
+ } else {
+ subdrv = 0;
+ }
+ }
+
+/* curr_drv_state<<1; <-- das geht irgendwie nicht */
/* muss heissen: curr_drv_state <<= 1; (ist ja Wert-Zuweisung) */
- curr_drv_state *= 2;
- curr_drv_state |= 1;
+ curr_drv_state *= 2;
+ curr_drv_state |= 1;
#ifdef GSCD_DEBUG
- printk ("DriveState: %d\n", curr_drv_state );
+ printk("DriveState: %d\n", curr_drv_state);
#endif
- }
+ }
- ndrives = drvnum;
- return drvnum;
-}
+ ndrives = drvnum;
+ return drvnum;
+}
-void __init init_cd_drive ( int num )
+void __init init_cd_drive(int num)
{
-char resp [50];
-int i;
+ char resp[50];
+ int i;
- printk ("GSCD: init unit %d\n", num );
- cc_Ident ((char *)&resp);
+ printk("GSCD: init unit %d\n", num);
+ cc_Ident((char *) &resp);
- printk ("GSCD: identification: ");
- for ( i=0 ; i<0x1E; i++ )
- {
- printk ( "%c", resp[i] );
- }
- printk ("\n");
-
- cc_SetSpeed ();
+ printk("GSCD: identification: ");
+ for (i = 0; i < 0x1E; i++) {
+ printk("%c", resp[i]);
+ }
+ printk("\n");
-}
+ cc_SetSpeed();
+
+}
#ifdef FUTURE_WORK
/* return_done */
-static void update_state ( void )
+static void update_state(void)
{
-unsigned int AX;
-
-
- if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
- {
- if ( disk_state == (ST_x08 | ST_x04 | ST_INVALID))
- {
- AX = ST_INVALID;
- }
-
- if ( (disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0 )
- {
- invalidate ();
- f_drv_ok = 0;
- }
-
- AX |= 0x8000;
- }
-
- if ( disk_state & ST_PLAYING )
- {
- AX |= 0x200;
- }
-
- AX |= 0x100;
- /* pkt_esbx = AX; */
-
- disk_state = 0;
-
+ unsigned int AX;
+
+
+ if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01)) == 0) {
+ if (disk_state == (ST_x08 | ST_x04 | ST_INVALID)) {
+ AX = ST_INVALID;
+ }
+
+ if ((disk_state & (ST_x08 | ST_x04 | ST_INVALID | ST_x01))
+ == 0) {
+ invalidate();
+ f_drv_ok = 0;
+ }
+
+ AX |= 0x8000;
+ }
+
+ if (disk_state & ST_PLAYING) {
+ AX |= 0x200;
+ }
+
+ AX |= 0x100;
+ /* pkt_esbx = AX; */
+
+ disk_state = 0;
+
}
#endif
/* Init for the Module-Version */
int init_gscd(void)
{
-long err;
+ long err;
- /* call the GoldStar-init */
- err = my_gscd_init ( );
+ /* call the GoldStar-init */
+ err = my_gscd_init();
- if ( err < 0 )
- {
- return err;
- }
- else
- {
- printk (KERN_INFO "Happy GoldStar !\n" );
- return 0;
- }
+ if (err < 0) {
+ return err;
+ } else {
+ printk(KERN_INFO "Happy GoldStar !\n");
+ return 0;
+ }
}
void __exit exit_gscd(void)
{
- CLEAR_TIMER;
-
- devfs_unregister(devfs_find_handle(NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK,
- 0));
- if ((devfs_unregister_blkdev(MAJOR_NR, "gscd" ) == -EINVAL))
- {
- printk("What's that: can't unregister GoldStar-module\n" );
- return;
- }
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- release_region (gscd_port,4);
- printk(KERN_INFO "GoldStar-module released.\n" );
+ CLEAR_TIMER;
+
+ devfs_unregister(devfs_find_handle
+ (NULL, "gscd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+ if ((devfs_unregister_blkdev(MAJOR_NR, "gscd") == -EINVAL)) {
+ printk("What's that: can't unregister GoldStar-module\n");
+ return;
+ }
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ release_region(gscd_port, 4);
+ printk(KERN_INFO "GoldStar-module released.\n");
}
#ifdef MODULE
module_init(init_gscd);
-#endif
+#endif
module_exit(exit_gscd);
/* Test for presence of drive and initialize it. Called only at boot time. */
-int __init gscd_init (void)
+int __init gscd_init(void)
{
- return my_gscd_init ();
+ return my_gscd_init();
}
/* This is the common initialisation for the GoldStar drive. */
/* It is called at boot time AND for module init. */
-int __init my_gscd_init (void)
+int __init my_gscd_init(void)
{
-int i;
-int result;
+ int i;
+ int result;
+
+ printk(KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
+ printk(KERN_INFO
+ "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n",
+ gscd_port);
+
+ if (check_region(gscd_port, 4)) {
+ printk
+ ("GSCD: Init failed, I/O port (%X) already in use.\n",
+ gscd_port);
+ return -EIO;
+ }
- printk (KERN_INFO "GSCD: version %s\n", GSCD_VERSION);
- printk (KERN_INFO "GSCD: Trying to detect a Goldstar R420 CD-ROM drive at 0x%X.\n", gscd_port);
- if (check_region(gscd_port, 4))
- {
- printk("GSCD: Init failed, I/O port (%X) already in use.\n", gscd_port);
- return -EIO;
+ /* check for card */
+ result = wait_drv_ready();
+ if (result == 0x09) {
+ printk("GSCD: DMA kann ich noch nicht!\n");
+ return -EIO;
}
-
- /* check for card */
- result = wait_drv_ready ();
- if ( result == 0x09 )
- {
- printk ("GSCD: DMA kann ich noch nicht!\n" );
- return -EIO;
- }
-
- if ( result == 0x0b )
- {
- drv_mode = result;
- i = find_drives ();
- if ( i == 0 )
- {
- printk ( "GSCD: GoldStar CD-ROM Drive is not found.\n" );
- return -EIO;
- }
- }
-
- if ( (result != 0x0b) && (result != 0x09) )
- {
- printk ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n" );
- return -EIO;
- }
-
- /* reset all drives */
- i = 0;
- while ( drv_states[i] != 0 )
- {
- curr_drv_state = drv_states[i];
- printk (KERN_INFO "GSCD: Reset unit %d ... ",i );
- cc_Reset ();
- printk ( "done\n" );
- i++;
- }
-
- if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0)
- {
- printk("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
- MAJOR_NR);
+ if (result == 0x0b) {
+ drv_mode = result;
+ i = find_drives();
+ if (i == 0) {
+ printk
+ ("GSCD: GoldStar CD-ROM Drive is not found.\n");
+ return -EIO;
+ }
+ }
+
+ if ((result != 0x0b) && (result != 0x09)) {
+ printk
+ ("GSCD: GoldStar Interface Adapter does not exist or H/W error\n");
return -EIO;
}
- devfs_register (NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
- S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
+
+ /* reset all drives */
+ i = 0;
+ while (drv_states[i] != 0) {
+ curr_drv_state = drv_states[i];
+ printk(KERN_INFO "GSCD: Reset unit %d ... ", i);
+ cc_Reset();
+ printk("done\n");
+ i++;
+ }
+
+ if (devfs_register_blkdev(MAJOR_NR, "gscd", &gscd_fops) != 0) {
+ printk
+ ("GSCD: Unable to get major %d for GoldStar CD-ROM\n",
+ MAJOR_NR);
+ return -EIO;
+ }
+ devfs_register(NULL, "gscd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+ S_IFBLK | S_IRUGO | S_IWUGO, &gscd_fops, NULL);
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
blksize_size[MAJOR_NR] = gscd_blocksizes;
read_ahead[MAJOR_NR] = 4;
-
- disk_state = 0;
- gscdPresent = 1;
+
+ disk_state = 0;
+ gscdPresent = 1;
request_region(gscd_port, 4, "gscd");
- register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &gscd_fops, 0);
+ register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &gscd_fops, 0);
- printk (KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n" );
+ printk(KERN_INFO "GSCD: GoldStar CD-ROM Drive found.\n");
return 0;
}
-static void gscd_hsg2msf (long hsg, struct msf *msf)
+static void gscd_hsg2msf(long hsg, struct msf *msf)
{
hsg += CD_MSF_OFFSET;
- msf -> min = hsg / (CD_FRAMES*CD_SECS);
- hsg %= CD_FRAMES*CD_SECS;
- msf -> sec = hsg / CD_FRAMES;
- msf -> frame = hsg % CD_FRAMES;
-
- gscd_bin2bcd(&msf -> min); /* convert to BCD */
- gscd_bin2bcd(&msf -> sec);
- gscd_bin2bcd(&msf -> frame);
+ msf->min = hsg / (CD_FRAMES * CD_SECS);
+ hsg %= CD_FRAMES * CD_SECS;
+ msf->sec = hsg / CD_FRAMES;
+ msf->frame = hsg % CD_FRAMES;
+
+ gscd_bin2bcd(&msf->min); /* convert to BCD */
+ gscd_bin2bcd(&msf->sec);
+ gscd_bin2bcd(&msf->frame);
}
-
-static void gscd_bin2bcd (unsigned char *p)
+
+static void gscd_bin2bcd(unsigned char *p)
{
-int u, t;
+ int u, t;
u = *p % 10;
t = *p / 10;
#ifdef FUTURE_WORK
-static long gscd_msf2hsg (struct msf *mp)
+static long gscd_msf2hsg(struct msf *mp)
{
- return gscd_bcd2bin(mp -> frame)
- + gscd_bcd2bin(mp -> sec) * CD_FRAMES
- + gscd_bcd2bin(mp -> min) * CD_FRAMES * CD_SECS
- - CD_MSF_OFFSET;
+ return gscd_bcd2bin(mp->frame)
+ + gscd_bcd2bin(mp->sec) * CD_FRAMES
+ + gscd_bcd2bin(mp->min) * CD_FRAMES * CD_SECS - CD_MSF_OFFSET;
}
-static int gscd_bcd2bin (unsigned char bcd)
+static int gscd_bcd2bin(unsigned char bcd)
{
return (bcd >> 4) * 10 + (bcd & 0xF);
}
#endif
-
+MODULE_AUTHOR("Oliver Raupach <raupach@nwfs1.rz.fh-hannover.de>");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
#define ISP16_VERSION_MAJOR 0
#define ISP16_VERSION_MINOR 6
-#ifdef MODULE
#include <linux/module.h>
-#endif /* MODULE */
#include <linux/fs.h>
#include <linux/kernel.h>
static short isp16_detect(void);
static short isp16_c928__detect(void);
static short isp16_c929__detect(void);
-static short isp16_cdi_config(int base, u_char drive_type, int irq, int dma);
-static short isp16_type; /* dependent on type of interface card */
+static short isp16_cdi_config(int base, u_char drive_type, int irq,
+ int dma);
+static short isp16_type; /* dependent on type of interface card */
static u_char isp16_ctrl;
static u_short isp16_enable_port;
static int isp16_cdrom_dma = ISP16_CDROM_DMA;
static char *isp16_cdrom_type = ISP16_CDROM_TYPE;
-#ifdef MODULE
MODULE_PARM(isp16_cdrom_base, "i");
MODULE_PARM(isp16_cdrom_irq, "i");
MODULE_PARM(isp16_cdrom_dma, "i");
MODULE_PARM(isp16_cdrom_type, "s");
+
+#ifdef MODULE
void isp16_exit(void);
#endif
#ifndef MODULE
-static int
+static int
__init isp16_setup(char *str)
{
- int ints[4];
-
- (void)get_options(str, ARRAY_SIZE(ints), ints);
- if ( ints[0] > 0 )
- isp16_cdrom_base = ints[1];
- if ( ints[0] > 1 )
- isp16_cdrom_irq = ints[2];
- if ( ints[0] > 2 )
- isp16_cdrom_dma = ints[3];
- if ( str )
- isp16_cdrom_type = str;
-
- return 1;
+ int ints[4];
+
+ (void) get_options(str, ARRAY_SIZE(ints), ints);
+ if (ints[0] > 0)
+ isp16_cdrom_base = ints[1];
+ if (ints[0] > 1)
+ isp16_cdrom_irq = ints[2];
+ if (ints[0] > 2)
+ isp16_cdrom_dma = ints[3];
+ if (str)
+ isp16_cdrom_type = str;
+
+ return 1;
}
__setup("isp16=", isp16_setup);
-#endif /* MODULE */
+#endif /* MODULE */
/*
* ISP16 initialisation.
*
*/
-int __init
-isp16_init(void)
+int __init isp16_init(void)
{
- u_char expected_drive;
-
- printk(KERN_INFO "ISP16: configuration cdrom interface, version %d.%d.\n", ISP16_VERSION_MAJOR,
- ISP16_VERSION_MINOR);
-
- if ( !strcmp(isp16_cdrom_type, "noisp16") ) {
- printk("ISP16: no cdrom interface configured.\n");
- return(0);
- }
-
- if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
- printk("ISP16: i/o ports already in use.\n");
- return(-EIO);
- }
-
- if ( (isp16_type=isp16_detect()) < 0 ) {
- printk("ISP16: no cdrom interface found.\n");
- return(-EIO);
- }
-
- printk(KERN_INFO "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
- (isp16_type==2) ? 9 : 8);
-
- if ( !strcmp(isp16_cdrom_type, "Sanyo") )
- expected_drive = (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
- else if ( !strcmp(isp16_cdrom_type, "Sony") )
- expected_drive = ISP16_SONY;
- else if ( !strcmp(isp16_cdrom_type, "Panasonic") )
- expected_drive = (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
- else if ( !strcmp(isp16_cdrom_type, "Mitsumi") )
- expected_drive = ISP16_MITSUMI;
- else {
- printk("ISP16: %s not supported by cdrom interface.\n", isp16_cdrom_type);
- return(-EIO);
- }
-
- if ( isp16_cdi_config(isp16_cdrom_base, expected_drive,
- isp16_cdrom_irq, isp16_cdrom_dma ) < 0) {
- printk("ISP16: cdrom interface has not been properly configured.\n");
- return(-EIO);
- }
- printk(KERN_INFO "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
- " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq, isp16_cdrom_dma,
- isp16_cdrom_type);
- return(0);
+ u_char expected_drive;
+
+ printk(KERN_INFO
+ "ISP16: configuration cdrom interface, version %d.%d.\n",
+ ISP16_VERSION_MAJOR, ISP16_VERSION_MINOR);
+
+ if (!strcmp(isp16_cdrom_type, "noisp16")) {
+ printk("ISP16: no cdrom interface configured.\n");
+ return (0);
+ }
+
+ if (check_region(ISP16_IO_BASE, ISP16_IO_SIZE)) {
+ printk("ISP16: i/o ports already in use.\n");
+ return (-EIO);
+ }
+
+ if ((isp16_type = isp16_detect()) < 0) {
+ printk("ISP16: no cdrom interface found.\n");
+ return (-EIO);
+ }
+
+ printk(KERN_INFO
+ "ISP16: cdrom interface (with OPTi 82C92%d chip) detected.\n",
+ (isp16_type == 2) ? 9 : 8);
+
+ if (!strcmp(isp16_cdrom_type, "Sanyo"))
+ expected_drive =
+ (isp16_type ? ISP16_SANYO1 : ISP16_SANYO0);
+ else if (!strcmp(isp16_cdrom_type, "Sony"))
+ expected_drive = ISP16_SONY;
+ else if (!strcmp(isp16_cdrom_type, "Panasonic"))
+ expected_drive =
+ (isp16_type ? ISP16_PANASONIC1 : ISP16_PANASONIC0);
+ else if (!strcmp(isp16_cdrom_type, "Mitsumi"))
+ expected_drive = ISP16_MITSUMI;
+ else {
+ printk("ISP16: %s not supported by cdrom interface.\n",
+ isp16_cdrom_type);
+ return (-EIO);
+ }
+
+ if (isp16_cdi_config(isp16_cdrom_base, expected_drive,
+ isp16_cdrom_irq, isp16_cdrom_dma) < 0) {
+ printk
+ ("ISP16: cdrom interface has not been properly configured.\n");
+ return (-EIO);
+ }
+ printk(KERN_INFO
+ "ISP16: cdrom interface set up with io base 0x%03X, irq %d, dma %d,"
+ " type %s.\n", isp16_cdrom_base, isp16_cdrom_irq,
+ isp16_cdrom_dma, isp16_cdrom_type);
+ return (0);
}
-static short __init
-isp16_detect(void)
+static short __init isp16_detect(void)
{
- if ( isp16_c929__detect() >= 0 )
- return(2);
- else
- return(isp16_c928__detect());
+ if (isp16_c929__detect() >= 0)
+ return (2);
+ else
+ return (isp16_c928__detect());
}
-static short __init
-isp16_c928__detect(void)
+static short __init isp16_c928__detect(void)
{
- u_char ctrl;
- u_char enable_cdrom;
- u_char io;
- short i = -1;
-
- isp16_ctrl = ISP16_C928__CTRL;
- isp16_enable_port = ISP16_C928__ENABLE_PORT;
-
- /* read' and write' are a special read and write, respectively */
-
- /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
- ctrl = ISP16_IN( ISP16_CTRL_PORT ) & 0xFC;
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
- /* read' 3,4 and 5-bit from the cdrom enable port */
- enable_cdrom = ISP16_IN( ISP16_C928__ENABLE_PORT ) & 0x38;
-
- if ( !(enable_cdrom & 0x20) ) { /* 5-bit not set */
- /* read' last 2 bits of ISP16_IO_SET_PORT */
- io = ISP16_IN( ISP16_IO_SET_PORT ) & 0x03;
- if ( ((io&0x01)<<1) == (io&0x02) ) { /* bits are the same */
- if ( io == 0 ) { /* ...the same and 0 */
- i = 0;
- enable_cdrom |= 0x20;
- }
- else { /* ...the same and 1 */ /* my card, first time 'round */
- i = 1;
- enable_cdrom |= 0x28;
- }
- ISP16_OUT( ISP16_C928__ENABLE_PORT, enable_cdrom );
- }
- else { /* bits are not the same */
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
- return(i); /* -> not detected: possibly incorrect conclusion */
- }
- }
- else if ( enable_cdrom == 0x20 )
- i = 0;
- else if ( enable_cdrom == 0x28 ) /* my card, already initialised */
- i = 1;
-
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
- return(i);
+ u_char ctrl;
+ u_char enable_cdrom;
+ u_char io;
+ short i = -1;
+
+ isp16_ctrl = ISP16_C928__CTRL;
+ isp16_enable_port = ISP16_C928__ENABLE_PORT;
+
+ /* read' and write' are a special read and write, respectively */
+
+ /* read' ISP16_CTRL_PORT, clear last two bits and write' back the result */
+ ctrl = ISP16_IN(ISP16_CTRL_PORT) & 0xFC;
+ ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+
+ /* read' 3,4 and 5-bit from the cdrom enable port */
+ enable_cdrom = ISP16_IN(ISP16_C928__ENABLE_PORT) & 0x38;
+
+ if (!(enable_cdrom & 0x20)) { /* 5-bit not set */
+ /* read' last 2 bits of ISP16_IO_SET_PORT */
+ io = ISP16_IN(ISP16_IO_SET_PORT) & 0x03;
+ if (((io & 0x01) << 1) == (io & 0x02)) { /* bits are the same */
+ if (io == 0) { /* ...the same and 0 */
+ i = 0;
+ enable_cdrom |= 0x20;
+ } else { /* ...the same and 1 *//* my card, first time 'round */
+ i = 1;
+ enable_cdrom |= 0x28;
+ }
+ ISP16_OUT(ISP16_C928__ENABLE_PORT, enable_cdrom);
+ } else { /* bits are not the same */
+ ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+ return (i); /* -> not detected: possibly incorrect conclusion */
+ }
+ } else if (enable_cdrom == 0x20)
+ i = 0;
+ else if (enable_cdrom == 0x28) /* my card, already initialised */
+ i = 1;
+
+ ISP16_OUT(ISP16_CTRL_PORT, ctrl);
+
+ return (i);
}
-static short __init
-isp16_c929__detect(void)
+static short __init isp16_c929__detect(void)
{
- u_char ctrl;
- u_char tmp;
+ u_char ctrl;
+ u_char tmp;
+
+ isp16_ctrl = ISP16_C929__CTRL;
+ isp16_enable_port = ISP16_C929__ENABLE_PORT;
- isp16_ctrl = ISP16_C929__CTRL;
- isp16_enable_port = ISP16_C929__ENABLE_PORT;
+ /* read' and write' are a special read and write, respectively */
- /* read' and write' are a special read and write, respectively */
+ /* read' ISP16_CTRL_PORT and save */
+ ctrl = ISP16_IN(ISP16_CTRL_PORT);
- /* read' ISP16_CTRL_PORT and save */
- ctrl = ISP16_IN( ISP16_CTRL_PORT );
+ /* write' zero to the ctrl port and get response */
+ ISP16_OUT(ISP16_CTRL_PORT, 0);
+ tmp = ISP16_IN(ISP16_CTRL_PORT);
- /* write' zero to the ctrl port and get response */
- ISP16_OUT( ISP16_CTRL_PORT, 0 );
- tmp = ISP16_IN( ISP16_CTRL_PORT );
+ if (tmp != 2) /* isp16 with 82C929 not detected */
+ return (-1);
- if ( tmp != 2 ) /* isp16 with 82C929 not detected */
- return(-1);
+ /* restore ctrl port value */
+ ISP16_OUT(ISP16_CTRL_PORT, ctrl);
- /* restore ctrl port value */
- ISP16_OUT( ISP16_CTRL_PORT, ctrl );
-
- return(2);
+ return (2);
}
-static short __init
+static short __init
isp16_cdi_config(int base, u_char drive_type, int irq, int dma)
{
- u_char base_code;
- u_char irq_code;
- u_char dma_code;
- u_char i;
-
- if ( (drive_type == ISP16_MITSUMI) && (dma != 0) )
- printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
-
- switch (base) {
- case 0x340: base_code = ISP16_BASE_340; break;
- case 0x330: base_code = ISP16_BASE_330; break;
- case 0x360: base_code = ISP16_BASE_360; break;
- case 0x320: base_code = ISP16_BASE_320; break;
- default:
- printk("ISP16: base address 0x%03X not supported by cdrom interface.\n",
- base);
- return(-1);
- }
- switch (irq) {
- case 0: irq_code = ISP16_IRQ_X; break; /* disable irq */
- case 5: irq_code = ISP16_IRQ_5;
- printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
- " due to possible conflicts with the sound card.\n");
- break;
- case 7: irq_code = ISP16_IRQ_7;
- printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
- " due to possible conflicts with the sound card.\n");
- break;
- case 3: irq_code = ISP16_IRQ_3; break;
- case 9: irq_code = ISP16_IRQ_9; break;
- case 10: irq_code = ISP16_IRQ_10; break;
- case 11: irq_code = ISP16_IRQ_11; break;
- default:
- printk("ISP16: irq %d not supported by cdrom interface.\n", irq );
- return(-1);
- }
- switch (dma) {
- case 0: dma_code = ISP16_DMA_X; break; /* disable dma */
- case 1: printk("ISP16: dma 1 cannot be used by cdrom interface,"
- " due to conflict with the sound card.\n");
- return(-1); break;
- case 3: dma_code = ISP16_DMA_3; break;
- case 5: dma_code = ISP16_DMA_5; break;
- case 6: dma_code = ISP16_DMA_6; break;
- case 7: dma_code = ISP16_DMA_7; break;
- default:
- printk("ISP16: dma %d not supported by cdrom interface.\n", dma);
- return(-1);
- }
-
- if ( drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
- drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
- drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
- drive_type != ISP16_DRIVE_X ) {
- printk("ISP16: drive type (code 0x%02X) not supported by cdrom"
- " interface.\n", drive_type );
- return(-1);
- }
-
- /* set type of interface */
- i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
- ISP16_OUT( ISP16_DRIVE_SET_PORT, i|drive_type );
-
- /* enable cdrom on interface with 82C929 chip */
- if ( isp16_type > 1 )
- ISP16_OUT( isp16_enable_port, ISP16_ENABLE_CDROM );
-
- /* set base address, irq and dma */
- i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
- ISP16_OUT( ISP16_IO_SET_PORT, i|base_code|irq_code|dma_code );
-
- return(0);
+ u_char base_code;
+ u_char irq_code;
+ u_char dma_code;
+ u_char i;
+
+ if ((drive_type == ISP16_MITSUMI) && (dma != 0))
+ printk("ISP16: Mitsumi cdrom drive has no dma support.\n");
+
+ switch (base) {
+ case 0x340:
+ base_code = ISP16_BASE_340;
+ break;
+ case 0x330:
+ base_code = ISP16_BASE_330;
+ break;
+ case 0x360:
+ base_code = ISP16_BASE_360;
+ break;
+ case 0x320:
+ base_code = ISP16_BASE_320;
+ break;
+ default:
+ printk
+ ("ISP16: base address 0x%03X not supported by cdrom interface.\n",
+ base);
+ return (-1);
+ }
+ switch (irq) {
+ case 0:
+ irq_code = ISP16_IRQ_X;
+ break; /* disable irq */
+ case 5:
+ irq_code = ISP16_IRQ_5;
+ printk("ISP16: irq 5 shouldn't be used by cdrom interface,"
+ " due to possible conflicts with the sound card.\n");
+ break;
+ case 7:
+ irq_code = ISP16_IRQ_7;
+ printk("ISP16: irq 7 shouldn't be used by cdrom interface,"
+ " due to possible conflicts with the sound card.\n");
+ break;
+ case 3:
+ irq_code = ISP16_IRQ_3;
+ break;
+ case 9:
+ irq_code = ISP16_IRQ_9;
+ break;
+ case 10:
+ irq_code = ISP16_IRQ_10;
+ break;
+ case 11:
+ irq_code = ISP16_IRQ_11;
+ break;
+ default:
+ printk("ISP16: irq %d not supported by cdrom interface.\n",
+ irq);
+ return (-1);
+ }
+ switch (dma) {
+ case 0:
+ dma_code = ISP16_DMA_X;
+ break; /* disable dma */
+ case 1:
+ printk("ISP16: dma 1 cannot be used by cdrom interface,"
+ " due to conflict with the sound card.\n");
+ return (-1);
+ break;
+ case 3:
+ dma_code = ISP16_DMA_3;
+ break;
+ case 5:
+ dma_code = ISP16_DMA_5;
+ break;
+ case 6:
+ dma_code = ISP16_DMA_6;
+ break;
+ case 7:
+ dma_code = ISP16_DMA_7;
+ break;
+ default:
+ printk("ISP16: dma %d not supported by cdrom interface.\n",
+ dma);
+ return (-1);
+ }
+
+ if (drive_type != ISP16_SONY && drive_type != ISP16_PANASONIC0 &&
+ drive_type != ISP16_PANASONIC1 && drive_type != ISP16_SANYO0 &&
+ drive_type != ISP16_SANYO1 && drive_type != ISP16_MITSUMI &&
+ drive_type != ISP16_DRIVE_X) {
+ printk
+ ("ISP16: drive type (code 0x%02X) not supported by cdrom"
+ " interface.\n", drive_type);
+ return (-1);
+ }
+
+ /* set type of interface */
+ i = ISP16_IN(ISP16_DRIVE_SET_PORT) & ISP16_DRIVE_SET_MASK; /* clear some bits */
+ ISP16_OUT(ISP16_DRIVE_SET_PORT, i | drive_type);
+
+ /* enable cdrom on interface with 82C929 chip */
+ if (isp16_type > 1)
+ ISP16_OUT(isp16_enable_port, ISP16_ENABLE_CDROM);
+
+ /* set base address, irq and dma */
+ i = ISP16_IN(ISP16_IO_SET_PORT) & ISP16_IO_SET_MASK; /* keep some bits */
+ ISP16_OUT(ISP16_IO_SET_PORT, i | base_code | irq_code | dma_code);
+
+ return (0);
}
void __exit isp16_exit(void)
#endif
module_exit(isp16_exit);
-
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
#define MAJOR_NR MITSUMI_CDROM_MAJOR
#include <linux/blk.h>
-#define mcd_port mcd /* for compatible parameter passing with "insmod" */
+#define mcd_port mcd /* for compatible parameter passing with "insmod" */
#include "mcd.h"
static int mcd_blocksizes[1];
/* I added A flag to drop to 1x speed if too many errors 0 = 1X ; 1 = 2X */
-static int mcdDouble;
+static int mcdDouble;
/* How many sectors to hold at 1x speed counter */
static int mcd1xhold;
static int mcdPresent;
#if 0
-#define TEST1 /* <int-..> */
-#define TEST2 /* do_mcd_req */
-#define TEST3 */ /* MCD_S_state */
-#define TEST4 /* QUICK_LOOP-counter */
-#define TEST5 */ /* port(1) state */
+#define TEST1 /* <int-..> */
+#define TEST2 /* do_mcd_req */
+#define TEST3 */ /* MCD_S_state */
+#define TEST4 /* QUICK_LOOP-counter */
+#define TEST5 */ /* port(1) state */
#endif
#if 1
-#define QUICK_LOOP_DELAY udelay(45) /* use udelay */
+#define QUICK_LOOP_DELAY udelay(45) /* use udelay */
#define QUICK_LOOP_COUNT 20
#else
#define QUICK_LOOP_DELAY
-#define QUICK_LOOP_COUNT 140 /* better wait constant time */
+#define QUICK_LOOP_COUNT 140 /* better wait constant time */
#endif
/* #define DOUBLE_QUICK_ONLY */
#define MFL_STATUSorDATA (MFL_STATUS | MFL_DATA)
#define MCD_BUF_SIZ 16
static volatile int mcd_transfer_is_active;
-static char mcd_buf[2048*MCD_BUF_SIZ]; /* buffer for block size conversion */
+static char mcd_buf[2048 * MCD_BUF_SIZ]; /* buffer for block size conversion */
static volatile int mcd_buf_bn[MCD_BUF_SIZ], mcd_next_bn;
static volatile int mcd_buf_in, mcd_buf_out = -1;
static volatile int mcd_error;
static int mcd_open_count;
enum mcd_state_e {
- MCD_S_IDLE, /* 0 */
- MCD_S_START, /* 1 */
- MCD_S_MODE, /* 2 */
- MCD_S_READ, /* 3 */
- MCD_S_DATA, /* 4 */
- MCD_S_STOP, /* 5 */
- MCD_S_STOPPING /* 6 */
+ MCD_S_IDLE, /* 0 */
+ MCD_S_START, /* 1 */
+ MCD_S_MODE, /* 2 */
+ MCD_S_READ, /* 3 */
+ MCD_S_DATA, /* 4 */
+ MCD_S_STOP, /* 5 */
+ MCD_S_STOPPING /* 6 */
};
static volatile enum mcd_state_e mcd_state = MCD_S_IDLE;
static int mcd_mode = -1;
-static int MCMD_DATA_READ= MCMD_PLAY_READ;
+static int MCMD_DATA_READ = MCMD_PLAY_READ;
#define READ_TIMEOUT 3000
#define WORK_AROUND_MITSUMI_BUG_92
#define WORK_AROUND_MITSUMI_BUG_93
#ifdef WORK_AROUND_MITSUMI_BUG_93
int mitsumi_bug_93_wait;
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+#endif /* WORK_AROUND_MITSUMI_BUG_93 */
-static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */
-static int mcd_irq = CONFIG_MCD_IRQ; /* must directly follow mcd_port */
+static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */
+static int mcd_irq = CONFIG_MCD_IRQ; /* must directly follow mcd_port */
MODULE_PARM(mcd, "1-2i");
static int McdTimeout, McdTries;
static int GetDiskInfo(void);
static int GetToc(void);
static int getValue(unsigned char *result);
-static int mcd_open(struct cdrom_device_info * cdi, int purpose);
-static void mcd_release(struct cdrom_device_info * cdi);
-static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr);
-static int mcd_tray_move(struct cdrom_device_info * cdi, int position);
-int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
- void * arg);
-int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr);
+static int mcd_open(struct cdrom_device_info *cdi, int purpose);
+static void mcd_release(struct cdrom_device_info *cdi);
+static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr);
+static int mcd_tray_move(struct cdrom_device_info *cdi, int position);
+int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+ void *arg);
+int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
static struct timer_list mcd_timer;
static struct cdrom_device_ops mcd_dops = {
- open: mcd_open,
- release: mcd_release,
- drive_status: mcd_drive_status,
- media_changed: mcd_media_changed,
- tray_move: mcd_tray_move,
- audio_ioctl: mcd_audio_ioctl,
- capability: CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
- CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
+ open:mcd_open,
+ release:mcd_release,
+ drive_status:mcd_drive_status,
+ media_changed:mcd_media_changed,
+ tray_move:mcd_tray_move,
+ audio_ioctl:mcd_audio_ioctl,
+ capability:CDC_OPEN_TRAY | CDC_MEDIA_CHANGED |
+ CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
};
static struct cdrom_device_info mcd_info = {
- ops: &mcd_dops,
- speed: 2,
- capacity: 1,
- name: "mcd",
+ ops:&mcd_dops,
+ speed:2,
+ capacity:1,
+ name:"mcd",
};
#ifndef MODULE
static int __init mcd_setup(char *str)
{
- int ints[9];
-
- (void)get_options(str, ARRAY_SIZE(ints), ints);
-
- if (ints[0] > 0)
- mcd_port = ints[1];
- if (ints[0] > 1)
- mcd_irq = ints[2];
+ int ints[9];
+
+ (void) get_options(str, ARRAY_SIZE(ints), ints);
+
+ if (ints[0] > 0)
+ mcd_port = ints[1];
+ if (ints[0] > 1)
+ mcd_irq = ints[2];
#ifdef WORK_AROUND_MITSUMI_BUG_93
- if (ints[0] > 2)
- mitsumi_bug_93_wait = ints[3];
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+ if (ints[0] > 2)
+ mitsumi_bug_93_wait = ints[3];
+#endif /* WORK_AROUND_MITSUMI_BUG_93 */
- return 1;
+ return 1;
}
__setup("mcd=", mcd_setup);
-#endif /* MODULE */
+#endif /* MODULE */
-static int mcd_media_changed(struct cdrom_device_info * cdi, int disc_nr)
+static int mcd_media_changed(struct cdrom_device_info *cdi, int disc_nr)
{
- int retval;
+ int retval;
-#if 1 /* the below is not reliable */
- return 0;
-#endif
+#if 1 /* the below is not reliable */
+ return 0;
+#endif
- if (cdi->dev) {
- printk("mcd: Mitsumi CD-ROM request error: invalid device.\n");
- return 0;
- }
+ if (cdi->dev) {
+ printk
+ ("mcd: Mitsumi CD-ROM request error: invalid device.\n");
+ return 0;
+ }
- retval = mcdDiskChanged;
- mcdDiskChanged = 0;
+ retval = mcdDiskChanged;
+ mcdDiskChanged = 0;
- return retval;
+ return retval;
}
* because it calls 'getMcdStatus' which sleeps.
*/
-static int
-statusCmd(void)
+static int statusCmd(void)
{
int st = -1, retry;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
- outb(MCMD_GET_STATUS, MCDPORT(0)); /* send get-status cmd */
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
+ outb(MCMD_GET_STATUS, MCDPORT(0)); /* send get-status cmd */
st = getMcdStatus(MCD_STATUS_DELAY);
- if (st != -1)
- break;
+ if (st != -1)
+ break;
}
return st;
* Send a 'Play' command and get the status. Use only from the top half.
*/
-static int
-mcdPlay(struct mcd_Play_msf *arg)
+static int mcdPlay(struct mcd_Play_msf *arg)
{
int retry, st = -1;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
sendMcdCmd(MCMD_PLAY_READ, arg);
st = getMcdStatus(2 * MCD_STATUS_DELAY);
if (st != -1)
}
-static int
-mcd_tray_move(struct cdrom_device_info * cdi, int position)
+static int mcd_tray_move(struct cdrom_device_info *cdi, int position)
{
int i;
if (position) {
- /* Eject */
- /* all drives can at least stop! */
+ /* Eject */
+ /* all drives can at least stop! */
if (audioStatus == CDROM_AUDIO_PLAY) {
- outb(MCMD_STOP, MCDPORT(0));
- i = getMcdStatus(MCD_STATUS_DELAY);
+ outb(MCMD_STOP, MCDPORT(0));
+ i = getMcdStatus(MCD_STATUS_DELAY);
}
- audioStatus = CDROM_AUDIO_NO_STATUS;
+ audioStatus = CDROM_AUDIO_NO_STATUS;
- outb(MCMD_EJECT, MCDPORT(0));
- /*
- * the status (i) shows failure on all but the FX drives.
- * But nothing we can do about that in software!
- * So just read the status and forget it. - Jon.
- */
- i = getMcdStatus(MCD_STATUS_DELAY);
- return 0;
- }
- else
+ outb(MCMD_EJECT, MCDPORT(0));
+ /*
+ * the status (i) shows failure on all but the FX drives.
+ * But nothing we can do about that in software!
+ * So just read the status and forget it. - Jon.
+ */
+ i = getMcdStatus(MCD_STATUS_DELAY);
+ return 0;
+ } else
return -EINVAL;
}
-long
-msf2hsg(struct msf *mp)
+long msf2hsg(struct msf *mp)
{
- return bcd2bin(mp -> frame)
- + bcd2bin(mp -> sec) * 75
- + bcd2bin(mp -> min) * 4500
- - 150;
+ return bcd2bin(mp->frame)
+ + bcd2bin(mp->sec) * 75 + bcd2bin(mp->min) * 4500 - 150;
}
-int mcd_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
- void * arg)
+int mcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
+ void *arg)
{
int i, st;
struct mcd_Toc qInfo;
if (st < 0)
return -EIO;
- if (!tocUpToDate)
- {
+ if (!tocUpToDate) {
i = updateToc();
- if (i < 0)
+ if (i < 0)
return i; /* error reading TOC */
}
- switch (cmd)
- {
- case CDROMSTART: /* Spin up the drive */
+ switch (cmd) {
+ case CDROMSTART: /* Spin up the drive */
/* Don't think we can do this. Even if we could,
- * I think the drive times out and stops after a while
+ * I think the drive times out and stops after a while
* anyway. For now, ignore it.
*/
return 0;
- case CDROMSTOP: /* Spin down the drive */
+ case CDROMSTOP: /* Spin down the drive */
outb(MCMD_STOP, MCDPORT(0));
i = getMcdStatus(MCD_STATUS_DELAY);
audioStatus = CDROM_AUDIO_NO_STATUS;
return 0;
- case CDROMPAUSE: /* Pause the drive */
+ case CDROMPAUSE: /* Pause the drive */
if (audioStatus != CDROM_AUDIO_PLAY)
return -EINVAL;
outb(MCMD_STOP, MCDPORT(0));
i = getMcdStatus(MCD_STATUS_DELAY);
- if (GetQChannelInfo(&qInfo) < 0)
- {
+ if (GetQChannelInfo(&qInfo) < 0) {
/* didn't get q channel info */
audioStatus = CDROM_AUDIO_NO_STATUS;
audioStatus = CDROM_AUDIO_PAUSED;
return 0;
- case CDROMRESUME: /* Play it again, Sam */
+ case CDROMRESUME: /* Play it again, Sam */
if (audioStatus != CDROM_AUDIO_PAUSED)
return -EINVAL;
/* restart the drive at the saved position. */
i = mcdPlay(&mcd_Play);
- if (i < 0)
- {
+ if (i < 0) {
audioStatus = CDROM_AUDIO_ERROR;
return -EIO;
}
audioStatus = CDROM_AUDIO_PLAY;
return 0;
- case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
+ case CDROMPLAYTRKIND: /* Play a track. This currently ignores index. */
- ti=(struct cdrom_ti *) arg;
+ ti = (struct cdrom_ti *) arg;
if (ti->cdti_trk0 < DiskInfo.first
- || ti->cdti_trk0 > DiskInfo.last
- || ti->cdti_trk1 < ti->cdti_trk0)
- {
+ || ti->cdti_trk0 > DiskInfo.last
+ || ti->cdti_trk1 < ti->cdti_trk0) {
return -EINVAL;
}
mcd_Play.end = Toc[ti->cdti_trk1 + 1].diskTime;
#ifdef MCD_DEBUG
-printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
- mcd_Play.start.min, mcd_Play.start.sec, mcd_Play.start.frame,
- mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
+ printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+ mcd_Play.start.min, mcd_Play.start.sec,
+ mcd_Play.start.frame, mcd_Play.end.min,
+ mcd_Play.end.sec, mcd_Play.end.frame);
#endif
i = mcdPlay(&mcd_Play);
- if (i < 0)
- {
+ if (i < 0) {
audioStatus = CDROM_AUDIO_ERROR;
return -EIO;
}
audioStatus = CDROM_AUDIO_PLAY;
return 0;
- case CDROMPLAYMSF: /* Play starting at the given MSF address. */
+ case CDROMPLAYMSF: /* Play starting at the given MSF address. */
if (audioStatus == CDROM_AUDIO_PLAY) {
- outb(MCMD_STOP, MCDPORT(0));
- i = getMcdStatus(MCD_STATUS_DELAY);
- audioStatus = CDROM_AUDIO_NO_STATUS;
+ outb(MCMD_STOP, MCDPORT(0));
+ i = getMcdStatus(MCD_STATUS_DELAY);
+ audioStatus = CDROM_AUDIO_NO_STATUS;
}
- msf=(struct cdrom_msf *) arg;
+ msf = (struct cdrom_msf *) arg;
/* convert to bcd */
mcd_Play.end.frame = msf->cdmsf_frame1;
#ifdef MCD_DEBUG
-printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
-mcd_Play.start.min, mcd_Play.start.sec, mcd_Play.start.frame,
-mcd_Play.end.min, mcd_Play.end.sec, mcd_Play.end.frame);
+ printk("play: %02x:%02x.%02x to %02x:%02x.%02x\n",
+ mcd_Play.start.min, mcd_Play.start.sec,
+ mcd_Play.start.frame, mcd_Play.end.min,
+ mcd_Play.end.sec, mcd_Play.end.frame);
#endif
i = mcdPlay(&mcd_Play);
- if (i < 0)
- {
+ if (i < 0) {
audioStatus = CDROM_AUDIO_ERROR;
return -EIO;
}
audioStatus = CDROM_AUDIO_PLAY;
return 0;
- case CDROMREADTOCHDR: /* Read the table of contents header */
- tocHdr=(struct cdrom_tochdr *) arg;
+ case CDROMREADTOCHDR: /* Read the table of contents header */
+ tocHdr = (struct cdrom_tochdr *) arg;
tocHdr->cdth_trk0 = DiskInfo.first;
tocHdr->cdth_trk1 = DiskInfo.last;
return 0;
- case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
- entry=(struct cdrom_tocentry *) arg;
+ case CDROMREADTOCENTRY: /* Read an entry in the table of contents */
+ entry = (struct cdrom_tocentry *) arg;
if (entry->cdte_track == CDROM_LEADOUT)
tocPtr = &Toc[DiskInfo.last - DiskInfo.first + 1];
else if (entry->cdte_track > DiskInfo.last
- || entry->cdte_track < DiskInfo.first)
+ || entry->cdte_track < DiskInfo.first)
return -EINVAL;
else
tocPtr = &Toc[entry->cdte_track];
- entry->cdte_adr = tocPtr -> ctrl_addr;
- entry->cdte_ctrl = tocPtr -> ctrl_addr >> 4;
+ entry->cdte_adr = tocPtr->ctrl_addr;
+ entry->cdte_ctrl = tocPtr->ctrl_addr >> 4;
if (entry->cdte_format == CDROM_LBA)
- entry->cdte_addr.lba = msf2hsg(&tocPtr -> diskTime);
-
- else if (entry->cdte_format == CDROM_MSF)
- {
- entry->cdte_addr.msf.minute = bcd2bin(tocPtr -> diskTime.min);
- entry->cdte_addr.msf.second = bcd2bin(tocPtr -> diskTime.sec);
- entry->cdte_addr.msf.frame = bcd2bin(tocPtr -> diskTime.frame);
+ entry->cdte_addr.lba = msf2hsg(&tocPtr->diskTime);
+
+ else if (entry->cdte_format == CDROM_MSF) {
+ entry->cdte_addr.msf.minute =
+ bcd2bin(tocPtr->diskTime.min);
+ entry->cdte_addr.msf.second =
+ bcd2bin(tocPtr->diskTime.sec);
+ entry->cdte_addr.msf.frame =
+ bcd2bin(tocPtr->diskTime.frame);
}
else
return 0;
- case CDROMSUBCHNL: /* Get subchannel info */
+ case CDROMSUBCHNL: /* Get subchannel info */
- subchnl=(struct cdrom_subchnl *) arg;
+ subchnl = (struct cdrom_subchnl *) arg;
if (GetQChannelInfo(&qInfo) < 0)
return -EIO;
subchnl->cdsc_ctrl = qInfo.ctrl_addr >> 4;
subchnl->cdsc_trk = bcd2bin(qInfo.track);
subchnl->cdsc_ind = bcd2bin(qInfo.pointIndex);
- subchnl->cdsc_absaddr.msf.minute = bcd2bin(qInfo.diskTime.min);
- subchnl->cdsc_absaddr.msf.second = bcd2bin(qInfo.diskTime.sec);
- subchnl->cdsc_absaddr.msf.frame = bcd2bin(qInfo.diskTime.frame);
- subchnl->cdsc_reladdr.msf.minute = bcd2bin(qInfo.trackTime.min);
- subchnl->cdsc_reladdr.msf.second = bcd2bin(qInfo.trackTime.sec);
- subchnl->cdsc_reladdr.msf.frame = bcd2bin(qInfo.trackTime.frame);
- return(0);
-
- case CDROMVOLCTRL: /* Volume control */
- volctrl=(struct cdrom_volctrl *) arg;
+ subchnl->cdsc_absaddr.msf.minute =
+ bcd2bin(qInfo.diskTime.min);
+ subchnl->cdsc_absaddr.msf.second =
+ bcd2bin(qInfo.diskTime.sec);
+ subchnl->cdsc_absaddr.msf.frame =
+ bcd2bin(qInfo.diskTime.frame);
+ subchnl->cdsc_reladdr.msf.minute =
+ bcd2bin(qInfo.trackTime.min);
+ subchnl->cdsc_reladdr.msf.second =
+ bcd2bin(qInfo.trackTime.sec);
+ subchnl->cdsc_reladdr.msf.frame =
+ bcd2bin(qInfo.trackTime.frame);
+ return (0);
+
+ case CDROMVOLCTRL: /* Volume control */
+ volctrl = (struct cdrom_volctrl *) arg;
outb(MCMD_SET_VOLUME, MCDPORT(0));
outb(volctrl->channel0, MCDPORT(0));
outb(255, MCDPORT(0));
* When Linux gets variable block sizes this will probably go away.
*/
-static void
-mcd_transfer(void)
+static void mcd_transfer(void)
{
- if (CURRENT_VALID) {
- while (CURRENT -> nr_sectors) {
- int bn = CURRENT -> sector / 4;
- int i;
- for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn; ++i)
- ;
- if (i < MCD_BUF_SIZ) {
- int offs = (i * 4 + (CURRENT -> sector & 3)) * 512;
- int nr_sectors = 4 - (CURRENT -> sector & 3);
- if (mcd_buf_out != i) {
- mcd_buf_out = i;
- if (mcd_buf_bn[i] != bn) {
- mcd_buf_out = -1;
- continue;
- }
+ if (CURRENT_VALID) {
+ while (CURRENT->nr_sectors) {
+ int bn = CURRENT->sector / 4;
+ int i;
+ for (i = 0; i < MCD_BUF_SIZ && mcd_buf_bn[i] != bn;
+ ++i);
+ if (i < MCD_BUF_SIZ) {
+ int offs =
+ (i * 4 + (CURRENT->sector & 3)) * 512;
+ int nr_sectors = 4 - (CURRENT->sector & 3);
+ if (mcd_buf_out != i) {
+ mcd_buf_out = i;
+ if (mcd_buf_bn[i] != bn) {
+ mcd_buf_out = -1;
+ continue;
+ }
+ }
+ if (nr_sectors > CURRENT->nr_sectors)
+ nr_sectors = CURRENT->nr_sectors;
+ memcpy(CURRENT->buffer, mcd_buf + offs,
+ nr_sectors * 512);
+ CURRENT->nr_sectors -= nr_sectors;
+ CURRENT->sector += nr_sectors;
+ CURRENT->buffer += nr_sectors * 512;
+ } else {
+ mcd_buf_out = -1;
+ break;
+ }
+ }
}
- if (nr_sectors > CURRENT -> nr_sectors)
- nr_sectors = CURRENT -> nr_sectors;
- memcpy(CURRENT -> buffer, mcd_buf + offs, nr_sectors * 512);
- CURRENT -> nr_sectors -= nr_sectors;
- CURRENT -> sector += nr_sectors;
- CURRENT -> buffer += nr_sectors * 512;
- } else {
- mcd_buf_out = -1;
- break;
- }
- }
- }
}
* Just take the interrupt and clear out the status reg.
*/
-static void
-mcd_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static void mcd_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int st;
st = inb(MCDPORT(1)) & 0xFF;
#ifdef TEST1
- printk("<int1-%02X>", st);
+ printk("<int1-%02X>", st);
#endif
- if (!(st & MFL_STATUS))
- {
+ if (!(st & MFL_STATUS)) {
st = inb(MCDPORT(0)) & 0xFF;
#ifdef TEST1
printk("<int0-%02X>", st);
#endif
if ((st & 0xFF) != 0xFF)
- mcd_error = st ? st & 0xFF : -1;
+ mcd_error = st ? st & 0xFF : -1;
}
}
-static void
-do_mcd_request(request_queue_t * q)
+static void do_mcd_request(request_queue_t * q)
{
#ifdef TEST2
- printk(" do_mcd_request(%ld+%ld)\n", CURRENT -> sector, CURRENT -> nr_sectors);
+ printk(" do_mcd_request(%ld+%ld)\n", CURRENT->sector,
+ CURRENT->nr_sectors);
#endif
- mcd_transfer_is_active = 1;
- while (CURRENT_VALID) {
- if (CURRENT->bh) {
- if (!buffer_locked(CURRENT->bh))
- panic(DEVICE_NAME ": block not locked");
- }
- mcd_transfer();
- if (CURRENT -> nr_sectors == 0) {
- end_request(1);
- } else {
- mcd_buf_out = -1; /* Want to read a block not in buffer */
- if (mcd_state == MCD_S_IDLE) {
- if (!tocUpToDate) {
- if (updateToc() < 0) {
- while (CURRENT_VALID)
- end_request(0);
- break;
- }
+ mcd_transfer_is_active = 1;
+ while (CURRENT_VALID) {
+ if (CURRENT->bh) {
+ if (!buffer_locked(CURRENT->bh))
+ panic(DEVICE_NAME ": block not locked");
+ }
+ mcd_transfer();
+ if (CURRENT->nr_sectors == 0) {
+ end_request(1);
+ } else {
+ mcd_buf_out = -1; /* Want to read a block not in buffer */
+ if (mcd_state == MCD_S_IDLE) {
+ if (!tocUpToDate) {
+ if (updateToc() < 0) {
+ while (CURRENT_VALID)
+ end_request(0);
+ break;
+ }
+ }
+ mcd_state = MCD_S_START;
+ McdTries = 5;
+ SET_TIMER(mcd_poll, 1);
+ }
+ break;
+ }
}
- mcd_state = MCD_S_START;
- McdTries = 5;
- SET_TIMER(mcd_poll, 1);
- }
- break;
- }
- }
- mcd_transfer_is_active = 0;
+ mcd_transfer_is_active = 0;
#ifdef TEST2
- printk(" do_mcd_request ends\n");
+ printk(" do_mcd_request ends\n");
#endif
}
-static void
-mcd_poll(unsigned long dummy)
+static void mcd_poll(unsigned long dummy)
{
- int st;
-
-
- if (mcd_error)
- {
- if (mcd_error & 0xA5)
- {
- printk("mcd: I/O error 0x%02x", mcd_error);
- if (mcd_error & 0x80)
- printk(" (Door open)");
- if (mcd_error & 0x20)
- printk(" (Disk changed)");
- if (mcd_error & 0x04)
- {
- printk(" (Read error)"); /* Bitch about the problem. */
-
- /* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
- /* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
- /* But I find that rather HANDY!!! */
- /* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
- /* AJK [06/17/95] */
-
- /* Slap the CD down to single speed! */
- if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_2X_READ)
- {
- MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */
- mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Beavis! */
- printk(" Speed now 1x"); /* Pull my finger! */
- }
- }
- printk("\n");
- mcd_invalidate_buffers();
+ int st;
+
+
+ if (mcd_error) {
+ if (mcd_error & 0xA5) {
+ printk("mcd: I/O error 0x%02x", mcd_error);
+ if (mcd_error & 0x80)
+ printk(" (Door open)");
+ if (mcd_error & 0x20)
+ printk(" (Disk changed)");
+ if (mcd_error & 0x04) {
+ printk(" (Read error)"); /* Bitch about the problem. */
+
+ /* Time to get fancy! If at 2x speed and 1 error, drop to 1x speed! */
+ /* Interesting how it STAYS at MCD_RETRY_ATTEMPTS on first error! */
+ /* But I find that rather HANDY!!! */
+ /* Neat! it REALLY WORKS on those LOW QUALITY CD's!!! Smile! :) */
+ /* AJK [06/17/95] */
+
+ /* Slap the CD down to single speed! */
+ if (mcdDouble == 1
+ && McdTries == MCD_RETRY_ATTEMPTS
+ && MCMD_DATA_READ == MCMD_2X_READ) {
+ MCMD_DATA_READ = MCMD_PLAY_READ; /* Uhhh, Ummmm, muhuh-huh! */
+ mcd1xhold = SINGLE_HOLD_SECTORS; /* Hey Beavis! */
+ printk(" Speed now 1x"); /* Pull my finger! */
+ }
+ }
+ printk("\n");
+ mcd_invalidate_buffers();
#ifdef WARN_IF_READ_FAILURE
- if (McdTries == MCD_RETRY_ATTEMPTS)
- printk("mcd: read of block %d failed\n", mcd_next_bn);
+ if (McdTries == MCD_RETRY_ATTEMPTS)
+ printk("mcd: read of block %d failed\n",
+ mcd_next_bn);
#endif
- if (!McdTries--)
- {
- /* Nuts! This cd is ready for recycling! */
- /* When WAS the last time YOU cleaned it CORRECTLY?! */
- printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
- if (mcd_transfer_is_active)
- {
- McdTries = 0;
- goto ret;
+ if (!McdTries--) {
+ /* Nuts! This cd is ready for recycling! */
+ /* When WAS the last time YOU cleaned it CORRECTLY?! */
+ printk
+ ("mcd: read of block %d failed, giving up\n",
+ mcd_next_bn);
+ if (mcd_transfer_is_active) {
+ McdTries = 0;
+ goto ret;
+ }
+ if (CURRENT_VALID)
+ end_request(0);
+ McdTries = MCD_RETRY_ATTEMPTS;
+ }
+ }
+ mcd_error = 0;
+ mcd_state = MCD_S_STOP;
}
- if (CURRENT_VALID)
- end_request(0);
- McdTries = MCD_RETRY_ATTEMPTS;
- }
- }
- mcd_error = 0;
- mcd_state = MCD_S_STOP;
- }
/* Switch back to Double speed if enough GOOD sectors were read! */
-
+
/* Are we a double speed with a crappy CD?! */
- if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS && MCMD_DATA_READ == MCMD_PLAY_READ)
- {
- /* We ARE a double speed and we ARE bitching! */
- if (mcd1xhold == 0) /* Okay, Like are we STILL at single speed? */
- { /* We need to switch back to double speed now... */
- MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */
- printk("mcd: Switching back to 2X speed!\n"); /* Tell 'em! */
- }
- else mcd1xhold--; /* No?! Count down the good reads some more... */
- /* and try, try again! */
- }
+ if (mcdDouble == 1 && McdTries == MCD_RETRY_ATTEMPTS
+ && MCMD_DATA_READ == MCMD_PLAY_READ) {
+ /* We ARE a double speed and we ARE bitching! */
+ if (mcd1xhold == 0) { /* Okay, Like are we STILL at single speed? *//* We need to switch back to double speed now... */
+ MCMD_DATA_READ = MCMD_2X_READ; /* Uhhh... BACK You GO! */
+ printk("mcd: Switching back to 2X speed!\n"); /* Tell 'em! */
+ } else
+ mcd1xhold--; /* No?! Count down the good reads some more... */
+ /* and try, try again! */
+ }
- immediately:
- switch (mcd_state) {
+ immediately:
+ switch (mcd_state) {
- case MCD_S_IDLE:
+ case MCD_S_IDLE:
#ifdef TEST3
- printk("MCD_S_IDLE\n");
+ printk("MCD_S_IDLE\n");
#endif
- goto out;
+ goto out;
- case MCD_S_START:
+ case MCD_S_START:
#ifdef TEST3
- printk("MCD_S_START\n");
+ printk("MCD_S_START\n");
#endif
- outb(MCMD_GET_STATUS, MCDPORT(0));
- mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
- McdTimeout = 3000;
- break;
+ outb(MCMD_GET_STATUS, MCDPORT(0));
+ mcd_state = mcd_mode == 1 ? MCD_S_READ : MCD_S_MODE;
+ McdTimeout = 3000;
+ break;
- case MCD_S_MODE:
+ case MCD_S_MODE:
#ifdef TEST3
- printk("MCD_S_MODE\n");
+ printk("MCD_S_MODE\n");
#endif
- if ((st = mcdStatus()) != -1) {
+ if ((st = mcdStatus()) != -1) {
- if (st & MST_DSK_CHG) {
- mcdDiskChanged = 1;
- tocUpToDate = 0;
- mcd_invalidate_buffers();
- }
-
- set_mode_immediately:
+ if (st & MST_DSK_CHG) {
+ mcdDiskChanged = 1;
+ tocUpToDate = 0;
+ mcd_invalidate_buffers();
+ }
- if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
- mcdDiskChanged = 1;
- tocUpToDate = 0;
- if (mcd_transfer_is_active) {
- mcd_state = MCD_S_START;
- goto immediately;
- }
- printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n");
- mcd_state = MCD_S_IDLE;
- while (CURRENT_VALID)
- end_request(0);
- goto out;
- }
+ set_mode_immediately:
+
+ if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
+ mcdDiskChanged = 1;
+ tocUpToDate = 0;
+ if (mcd_transfer_is_active) {
+ mcd_state = MCD_S_START;
+ goto immediately;
+ }
+ printk((st & MST_DOOR_OPEN) ?
+ "mcd: door open\n" :
+ "mcd: disk removed\n");
+ mcd_state = MCD_S_IDLE;
+ while (CURRENT_VALID)
+ end_request(0);
+ goto out;
+ }
- outb(MCMD_SET_MODE, MCDPORT(0));
- outb(1, MCDPORT(0));
- mcd_mode = 1;
- mcd_state = MCD_S_READ;
- McdTimeout = 3000;
+ outb(MCMD_SET_MODE, MCDPORT(0));
+ outb(1, MCDPORT(0));
+ mcd_mode = 1;
+ mcd_state = MCD_S_READ;
+ McdTimeout = 3000;
- }
- break;
+ }
+ break;
- case MCD_S_READ:
+ case MCD_S_READ:
#ifdef TEST3
- printk("MCD_S_READ\n");
+ printk("MCD_S_READ\n");
#endif
- if ((st = mcdStatus()) != -1) {
+ if ((st = mcdStatus()) != -1) {
- if (st & MST_DSK_CHG) {
- mcdDiskChanged = 1;
- tocUpToDate = 0;
- mcd_invalidate_buffers();
- }
+ if (st & MST_DSK_CHG) {
+ mcdDiskChanged = 1;
+ tocUpToDate = 0;
+ mcd_invalidate_buffers();
+ }
- read_immediately:
+ read_immediately:
+
+ if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
+ mcdDiskChanged = 1;
+ tocUpToDate = 0;
+ if (mcd_transfer_is_active) {
+ mcd_state = MCD_S_START;
+ goto immediately;
+ }
+ printk((st & MST_DOOR_OPEN) ?
+ "mcd: door open\n" :
+ "mcd: disk removed\n");
+ mcd_state = MCD_S_IDLE;
+ while (CURRENT_VALID)
+ end_request(0);
+ goto out;
+ }
- if ((st & MST_DOOR_OPEN) || !(st & MST_READY)) {
- mcdDiskChanged = 1;
- tocUpToDate = 0;
- if (mcd_transfer_is_active) {
- mcd_state = MCD_S_START;
- goto immediately;
- }
- printk((st & MST_DOOR_OPEN) ? "mcd: door open\n" : "mcd: disk removed\n");
- mcd_state = MCD_S_IDLE;
- while (CURRENT_VALID)
- end_request(0);
- goto out;
- }
-
- if (CURRENT_VALID) {
- struct mcd_Play_msf msf;
- mcd_next_bn = CURRENT -> sector / 4;
- hsg2msf(mcd_next_bn, &msf.start);
- msf.end.min = ~0;
- msf.end.sec = ~0;
- msf.end.frame = ~0;
- sendMcdCmd(MCMD_DATA_READ, &msf);
- mcd_state = MCD_S_DATA;
- McdTimeout = READ_TIMEOUT;
- } else {
- mcd_state = MCD_S_STOP;
- goto immediately;
- }
-
- }
- break;
-
-
- case MCD_S_DATA:
+ if (CURRENT_VALID) {
+ struct mcd_Play_msf msf;
+ mcd_next_bn = CURRENT->sector / 4;
+ hsg2msf(mcd_next_bn, &msf.start);
+ msf.end.min = ~0;
+ msf.end.sec = ~0;
+ msf.end.frame = ~0;
+ sendMcdCmd(MCMD_DATA_READ, &msf);
+ mcd_state = MCD_S_DATA;
+ McdTimeout = READ_TIMEOUT;
+ } else {
+ mcd_state = MCD_S_STOP;
+ goto immediately;
+ }
+
+ }
+ break;
+
+
+ case MCD_S_DATA:
#ifdef TEST3
- printk("MCD_S_DATA\n");
+ printk("MCD_S_DATA\n");
#endif
- st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
- data_immediately:
+ st = inb(MCDPORT(1)) & (MFL_STATUSorDATA);
+ data_immediately:
#ifdef TEST5
- printk("Status %02x\n",st);
+ printk("Status %02x\n", st);
#endif
- switch (st) {
+ switch (st) {
- case MFL_DATA:
+ case MFL_DATA:
#ifdef WARN_IF_READ_FAILURE
- if (McdTries == 5)
- printk("mcd: read of block %d failed\n", mcd_next_bn);
+ if (McdTries == 5)
+ printk("mcd: read of block %d failed\n",
+ mcd_next_bn);
#endif
- if (!McdTries--) {
- printk("mcd: read of block %d failed, giving up\n", mcd_next_bn);
- if (mcd_transfer_is_active) {
- McdTries = 0;
- break;
- }
- if (CURRENT_VALID)
- end_request(0);
- McdTries = 5;
- }
- mcd_state = MCD_S_START;
- McdTimeout = READ_TIMEOUT;
- goto immediately;
-
- case MFL_STATUSorDATA:
- break;
-
- default:
- McdTries = 5;
- if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) {
- mcd_state = MCD_S_STOP;
- goto immediately;
- }
- mcd_buf_bn[mcd_buf_in] = -1;
- READ_DATA(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in, 2048);
- mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
- if (mcd_buf_out == -1)
- mcd_buf_out = mcd_buf_in;
- mcd_buf_in = mcd_buf_in + 1 == MCD_BUF_SIZ ? 0 : mcd_buf_in + 1;
- if (!mcd_transfer_is_active) {
- while (CURRENT_VALID) {
- mcd_transfer();
- if (CURRENT -> nr_sectors == 0)
- end_request(1);
- else
- break;
- }
- }
-
- if (CURRENT_VALID
- && (CURRENT -> sector / 4 < mcd_next_bn ||
- CURRENT -> sector / 4 > mcd_next_bn + 16)) {
- mcd_state = MCD_S_STOP;
- goto immediately;
- }
- McdTimeout = READ_TIMEOUT;
+ if (!McdTries--) {
+ printk
+ ("mcd: read of block %d failed, giving up\n",
+ mcd_next_bn);
+ if (mcd_transfer_is_active) {
+ McdTries = 0;
+ break;
+ }
+ if (CURRENT_VALID)
+ end_request(0);
+ McdTries = 5;
+ }
+ mcd_state = MCD_S_START;
+ McdTimeout = READ_TIMEOUT;
+ goto immediately;
+
+ case MFL_STATUSorDATA:
+ break;
+
+ default:
+ McdTries = 5;
+ if (!CURRENT_VALID && mcd_buf_in == mcd_buf_out) {
+ mcd_state = MCD_S_STOP;
+ goto immediately;
+ }
+ mcd_buf_bn[mcd_buf_in] = -1;
+ READ_DATA(MCDPORT(0), mcd_buf + 2048 * mcd_buf_in,
+ 2048);
+ mcd_buf_bn[mcd_buf_in] = mcd_next_bn++;
+ if (mcd_buf_out == -1)
+ mcd_buf_out = mcd_buf_in;
+ mcd_buf_in =
+ mcd_buf_in + 1 ==
+ MCD_BUF_SIZ ? 0 : mcd_buf_in + 1;
+ if (!mcd_transfer_is_active) {
+ while (CURRENT_VALID) {
+ mcd_transfer();
+ if (CURRENT->nr_sectors == 0)
+ end_request(1);
+ else
+ break;
+ }
+ }
+
+ if (CURRENT_VALID
+ && (CURRENT->sector / 4 < mcd_next_bn ||
+ CURRENT->sector / 4 > mcd_next_bn + 16)) {
+ mcd_state = MCD_S_STOP;
+ goto immediately;
+ }
+ McdTimeout = READ_TIMEOUT;
#ifdef DOUBLE_QUICK_ONLY
- if (MCMD_DATA_READ != MCMD_PLAY_READ)
+ if (MCMD_DATA_READ != MCMD_PLAY_READ)
#endif
- {
- int count= QUICK_LOOP_COUNT;
- while (count--) {
- QUICK_LOOP_DELAY;
- if ((st = (inb(MCDPORT(1))) & (MFL_STATUSorDATA)) != (MFL_STATUSorDATA)) {
+ {
+ int count = QUICK_LOOP_COUNT;
+ while (count--) {
+ QUICK_LOOP_DELAY;
+ if ((st =
+ (inb(MCDPORT(1))) &
+ (MFL_STATUSorDATA)) !=
+ (MFL_STATUSorDATA)) {
# ifdef TEST4
/* printk("Quickloop success at %d\n",QUICK_LOOP_COUNT-count); */
- printk(" %d ",QUICK_LOOP_COUNT-count);
+ printk(" %d ",
+ QUICK_LOOP_COUNT -
+ count);
# endif
- goto data_immediately;
- }
- }
+ goto data_immediately;
+ }
+ }
# ifdef TEST4
/* printk("Quickloop ended at %d\n",QUICK_LOOP_COUNT); */
- printk("ended ");
+ printk("ended ");
# endif
- }
- break;
- }
- break;
+ }
+ break;
+ }
+ break;
- case MCD_S_STOP:
+ case MCD_S_STOP:
#ifdef TEST3
- printk("MCD_S_STOP\n");
+ printk("MCD_S_STOP\n");
#endif
#ifdef WORK_AROUND_MITSUMI_BUG_93
- if (!mitsumi_bug_93_wait)
- goto do_not_work_around_mitsumi_bug_93_1;
+ if (!mitsumi_bug_93_wait)
+ goto do_not_work_around_mitsumi_bug_93_1;
- McdTimeout = mitsumi_bug_93_wait;
- mcd_state = 9+3+1;
- break;
+ McdTimeout = mitsumi_bug_93_wait;
+ mcd_state = 9 + 3 + 1;
+ break;
- case 9+3+1:
- if (McdTimeout)
- break;
+ case 9 + 3 + 1:
+ if (McdTimeout)
+ break;
- do_not_work_around_mitsumi_bug_93_1:
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+ do_not_work_around_mitsumi_bug_93_1:
+#endif /* WORK_AROUND_MITSUMI_BUG_93 */
- outb(MCMD_STOP, MCDPORT(0));
+ outb(MCMD_STOP, MCDPORT(0));
#ifdef WORK_AROUND_MITSUMI_BUG_92
- if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
- int i = 4096;
- do {
- inb(MCDPORT(0));
- } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
- outb(MCMD_STOP, MCDPORT(0));
- if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
- i = 4096;
- do {
- inb(MCDPORT(0));
- } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS && --i);
- outb(MCMD_STOP, MCDPORT(0));
- }
- }
-#endif /* WORK_AROUND_MITSUMI_BUG_92 */
-
- mcd_state = MCD_S_STOPPING;
- McdTimeout = 1000;
- break;
-
- case MCD_S_STOPPING:
+ if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) == MFL_STATUS) {
+ int i = 4096;
+ do {
+ inb(MCDPORT(0));
+ } while ((inb(MCDPORT(1)) & MFL_STATUSorDATA) ==
+ MFL_STATUS && --i);
+ outb(MCMD_STOP, MCDPORT(0));
+ if ((inb(MCDPORT(1)) & MFL_STATUSorDATA) ==
+ MFL_STATUS) {
+ i = 4096;
+ do {
+ inb(MCDPORT(0));
+ } while ((inb(MCDPORT(1)) &
+ MFL_STATUSorDATA) == MFL_STATUS
+ && --i);
+ outb(MCMD_STOP, MCDPORT(0));
+ }
+ }
+#endif /* WORK_AROUND_MITSUMI_BUG_92 */
+
+ mcd_state = MCD_S_STOPPING;
+ McdTimeout = 1000;
+ break;
+
+ case MCD_S_STOPPING:
#ifdef TEST3
- printk("MCD_S_STOPPING\n");
+ printk("MCD_S_STOPPING\n");
#endif
- if ((st = mcdStatus()) == -1 && McdTimeout)
- break;
-
- if ((st != -1) && (st & MST_DSK_CHG)) {
- mcdDiskChanged = 1;
- tocUpToDate = 0;
- mcd_invalidate_buffers();
- }
+ if ((st = mcdStatus()) == -1 && McdTimeout)
+ break;
+ if ((st != -1) && (st & MST_DSK_CHG)) {
+ mcdDiskChanged = 1;
+ tocUpToDate = 0;
+ mcd_invalidate_buffers();
+ }
#ifdef WORK_AROUND_MITSUMI_BUG_93
- if (!mitsumi_bug_93_wait)
- goto do_not_work_around_mitsumi_bug_93_2;
+ if (!mitsumi_bug_93_wait)
+ goto do_not_work_around_mitsumi_bug_93_2;
- McdTimeout = mitsumi_bug_93_wait;
- mcd_state = 9+3+2;
- break;
+ McdTimeout = mitsumi_bug_93_wait;
+ mcd_state = 9 + 3 + 2;
+ break;
- case 9+3+2:
- if (McdTimeout)
- break;
+ case 9 + 3 + 2:
+ if (McdTimeout)
+ break;
- st = -1;
+ st = -1;
- do_not_work_around_mitsumi_bug_93_2:
-#endif /* WORK_AROUND_MITSUMI_BUG_93 */
+ do_not_work_around_mitsumi_bug_93_2:
+#endif /* WORK_AROUND_MITSUMI_BUG_93 */
#ifdef TEST3
- printk("CURRENT_VALID %d mcd_mode %d\n",
- CURRENT_VALID, mcd_mode);
+ printk("CURRENT_VALID %d mcd_mode %d\n",
+ CURRENT_VALID, mcd_mode);
#endif
- if (CURRENT_VALID) {
- if (st != -1) {
- if (mcd_mode == 1)
- goto read_immediately;
- else
- goto set_mode_immediately;
- } else {
- mcd_state = MCD_S_START;
- McdTimeout = 1;
- }
- } else {
- mcd_state = MCD_S_IDLE;
- goto out;
- }
- break;
-
- default:
- printk("mcd: invalid state %d\n", mcd_state);
- goto out;
- }
-
- ret:
- if (!McdTimeout--) {
- printk("mcd: timeout in state %d\n", mcd_state);
- mcd_state = MCD_S_STOP;
- }
-
- SET_TIMER(mcd_poll, 1);
-out:
- return;
+ if (CURRENT_VALID) {
+ if (st != -1) {
+ if (mcd_mode == 1)
+ goto read_immediately;
+ else
+ goto set_mode_immediately;
+ } else {
+ mcd_state = MCD_S_START;
+ McdTimeout = 1;
+ }
+ } else {
+ mcd_state = MCD_S_IDLE;
+ goto out;
+ }
+ break;
+
+ default:
+ printk("mcd: invalid state %d\n", mcd_state);
+ goto out;
+ }
+
+ ret:
+ if (!McdTimeout--) {
+ printk("mcd: timeout in state %d\n", mcd_state);
+ mcd_state = MCD_S_STOP;
+ }
+
+ SET_TIMER(mcd_poll, 1);
+ out:
+ return;
}
-static void
-mcd_invalidate_buffers(void)
+static void mcd_invalidate_buffers(void)
{
- int i;
- for (i = 0; i < MCD_BUF_SIZ; ++i)
- mcd_buf_bn[i] = -1;
- mcd_buf_out = -1;
+ int i;
+ for (i = 0; i < MCD_BUF_SIZ; ++i)
+ mcd_buf_bn[i] = -1;
+ mcd_buf_out = -1;
}
/*
* Open the device special file. Check that a disk is in.
*/
-static int mcd_open(struct cdrom_device_info * cdi, int purpose)
+static int mcd_open(struct cdrom_device_info *cdi, int purpose)
{
- int st, count=0;
+ int st, count = 0;
if (mcdPresent == 0)
- return -ENXIO; /* no hardware */
+ return -ENXIO; /* no hardware */
- MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT;
- if (mcd_open_count || mcd_state != MCD_S_IDLE)
+ if (mcd_open_count || mcd_state != MCD_S_IDLE)
goto bump_count;
- mcd_invalidate_buffers();
- do {
- st = statusCmd(); /* check drive status */
- if (st == -1)
- goto err_out; /* drive doesn't respond */
- if ((st & MST_READY) == 0) { /* no disk? wait a sec... */
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ);
- }
- } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
-
- if (updateToc() < 0)
- goto err_out;
-
-bump_count:
+ mcd_invalidate_buffers();
+ do {
+ st = statusCmd(); /* check drive status */
+ if (st == -1)
+ goto err_out; /* drive doesn't respond */
+ if ((st & MST_READY) == 0) { /* no disk? wait a sec... */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ);
+ }
+ } while (((st & MST_READY) == 0) && count++ < MCD_RETRY_ATTEMPTS);
+
+ if (updateToc() < 0)
+ goto err_out;
+
+ bump_count:
++mcd_open_count;
return 0;
-err_out:
- MOD_DEC_USE_COUNT;
+ err_out:
+ MOD_DEC_USE_COUNT;
return -EIO;
}
/*
* On close, we flush all mcd blocks from the buffer cache.
*/
-static void mcd_release(struct cdrom_device_info * cdi)
-{ MOD_DEC_USE_COUNT;
- if (!--mcd_open_count) {
- mcd_invalidate_buffers();
- }
+static void mcd_release(struct cdrom_device_info *cdi)
+{
+ MOD_DEC_USE_COUNT;
+ if (!--mcd_open_count) {
+ mcd_invalidate_buffers();
+ }
}
* and is used in mcd_exit as well. */
static void cleanup(int level)
{
- switch (level) {
- case 3:
- if (unregister_cdrom(&mcd_info)) {
- printk(KERN_WARNING "Can't unregister cdrom mcd\n");
- return;
- }
- free_irq(mcd_irq, NULL);
- case 2:
- release_region(mcd_port,4);
- case 1:
- if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
- printk(KERN_WARNING "Can't unregister major mcd\n");
- return;
- }
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- default:;
- }
+ switch (level) {
+ case 3:
+ if (unregister_cdrom(&mcd_info)) {
+ printk(KERN_WARNING
+ "Can't unregister cdrom mcd\n");
+ return;
+ }
+ free_irq(mcd_irq, NULL);
+ case 2:
+ release_region(mcd_port, 4);
+ case 1:
+ if (devfs_unregister_blkdev(MAJOR_NR, "mcd")) {
+ printk(KERN_WARNING
+ "Can't unregister major mcd\n");
+ return;
+ }
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ default:;
+ }
}
char msg[80];
if (mcd_port <= 0 || mcd_irq <= 0) {
- printk("skip mcd_init\n");
- return -EIO;
+ printk("skip mcd_init\n");
+ return -EIO;
}
- if (devfs_register_blkdev(MAJOR_NR, "mcd", &cdrom_fops) != 0)
- {
+ if (devfs_register_blkdev(MAJOR_NR, "mcd", &cdrom_fops) != 0) {
printk("Unable to get major %d for Mitsumi CD-ROM\n",
MAJOR_NR);
- return -EIO;
+ return -EIO;
}
- if (check_region(mcd_port, 4)) {
- cleanup(1);
- printk("Init failed, I/O port (%X) already in use\n",
- mcd_port);
- return -EIO;
+ if (check_region(mcd_port, 4)) {
+ cleanup(1);
+ printk("Init failed, I/O port (%X) already in use\n",
+ mcd_port);
+ return -EIO;
}
blksize_size[MAJOR_NR] = mcd_blocksizes;
/* check for card */
- outb(0, MCDPORT(1)); /* send reset */
+ outb(0, MCDPORT(1)); /* send reset */
for (count = 0; count < 2000000; count++)
- (void) inb(MCDPORT(1)); /* delay a bit */
+ (void) inb(MCDPORT(1)); /* delay a bit */
- outb(0x40, MCDPORT(0)); /* send get-stat cmd */
+ outb(0x40, MCDPORT(0)); /* send get-stat cmd */
for (count = 0; count < 2000000; count++)
if (!(inb(MCDPORT(1)) & MFL_STATUS))
break;
if (count >= 2000000) {
printk("Init failed. No mcd device at 0x%x irq %d\n",
- mcd_port, mcd_irq);
+ mcd_port, mcd_irq);
cleanup(1);
- return -EIO;
+ return -EIO;
}
- count = inb(MCDPORT(0)); /* pick up the status */
-
- outb(MCMD_GET_VERSION,MCDPORT(0));
- for(count=0;count<3;count++)
- if(getValue(result+count)) {
+ count = inb(MCDPORT(0)); /* pick up the status */
+
+ outb(MCMD_GET_VERSION, MCDPORT(0));
+ for (count = 0; count < 3; count++)
+ if (getValue(result + count)) {
printk("mitsumi get version failed at 0x%x\n",
mcd_port);
- cleanup(1);
- return -EIO;
- }
+ cleanup(1);
+ return -EIO;
+ }
if (result[0] == result[1] && result[1] == result[2]) {
cleanup(1);
- return -EIO;
+ return -EIO;
}
- mcdVersion=result[2];
+ mcdVersion = result[2];
- if (mcdVersion >=4)
- outb(4,MCDPORT(2)); /* magic happens */
+ if (mcdVersion >= 4)
+ outb(4, MCDPORT(2)); /* magic happens */
/* don't get the IRQ until we know for sure the drive is there */
- if (request_irq(mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL))
- {
- printk("Unable to get IRQ%d for Mitsumi CD-ROM\n", mcd_irq);
+ if (request_irq
+ (mcd_irq, mcd_interrupt, SA_INTERRUPT, "Mitsumi CD", NULL)) {
+ printk("Unable to get IRQ%d for Mitsumi CD-ROM\n",
+ mcd_irq);
cleanup(1);
- return -EIO;
+ return -EIO;
}
- if (result[1] == 'D')
- {
+ if (result[1] == 'D') {
MCMD_DATA_READ = MCMD_2X_READ;
/* Added flag to drop to 1x speed if too many errors */
mcdDouble = 1;
- } else
+ } else
mcd_info.speed = 1;
sprintf(msg, " mcd: Mitsumi %s Speed CD-ROM at port=0x%x,"
- " irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double", mcd_port, mcd_irq);
+ " irq=%d\n", mcd_info.speed == 1 ? "Single" : "Double",
+ mcd_port, mcd_irq);
request_region(mcd_port, 4, "mcd");
outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
- outb(0x02,MCDPORT(0));
- outb(0x00,MCDPORT(0));
+ outb(0x02, MCDPORT(0));
+ outb(0x00, MCDPORT(0));
getValue(result);
outb(MCMD_CONFIG_DRIVE, MCDPORT(0));
- outb(0x10,MCDPORT(0));
- outb(0x04,MCDPORT(0));
+ outb(0x10, MCDPORT(0));
+ outb(0x04, MCDPORT(0));
getValue(result);
mcd_invalidate_buffers();
mcdPresent = 1;
- mcd_info.dev = MKDEV(MAJOR_NR,0);
+ mcd_info.dev = MKDEV(MAJOR_NR, 0);
- if (register_cdrom(&mcd_info) != 0) {
- printk("Cannot register Mitsumi CD-ROM!\n");
- cleanup(3);
- return -EIO;
- }
- printk(msg);
+ if (register_cdrom(&mcd_info) != 0) {
+ printk("Cannot register Mitsumi CD-ROM!\n");
+ cleanup(3);
+ return -EIO;
+ }
+ printk(msg);
return 0;
}
-static void
-hsg2msf(long hsg, struct msf *msf)
+static void hsg2msf(long hsg, struct msf *msf)
{
hsg += 150;
- msf -> min = hsg / 4500;
+ msf->min = hsg / 4500;
hsg %= 4500;
- msf -> sec = hsg / 75;
- msf -> frame = hsg % 75;
+ msf->sec = hsg / 75;
+ msf->frame = hsg % 75;
- bin2bcd(&msf -> min); /* convert to BCD */
- bin2bcd(&msf -> sec);
- bin2bcd(&msf -> frame);
+ bin2bcd(&msf->min); /* convert to BCD */
+ bin2bcd(&msf->sec);
+ bin2bcd(&msf->frame);
}
-static void
-bin2bcd(unsigned char *p)
+static void bin2bcd(unsigned char *p)
{
int u, t;
*p = u | (t << 4);
}
-static int
-bcd2bin(unsigned char bcd)
+static int bcd2bin(unsigned char bcd)
{
return (bcd >> 4) * 10 + (bcd & 0xF);
}
* if it is ready.
*/
-static int
-mcdStatus(void)
+static int mcdStatus(void)
{
int i;
int st;
st = inb(MCDPORT(1)) & MFL_STATUS;
- if (!st)
- {
+ if (!st) {
i = inb(MCDPORT(0)) & 0xFF;
return i;
- }
- else
+ } else
return -1;
}
* Send a play or read command to the drive
*/
-static void
-sendMcdCmd(int cmd, struct mcd_Play_msf *params)
+static void sendMcdCmd(int cmd, struct mcd_Play_msf *params)
{
outb(cmd, MCDPORT(0));
- outb(params -> start.min, MCDPORT(0));
- outb(params -> start.sec, MCDPORT(0));
- outb(params -> start.frame, MCDPORT(0));
- outb(params -> end.min, MCDPORT(0));
- outb(params -> end.sec, MCDPORT(0));
- outb(params -> end.frame, MCDPORT(0));
+ outb(params->start.min, MCDPORT(0));
+ outb(params->start.sec, MCDPORT(0));
+ outb(params->start.frame, MCDPORT(0));
+ outb(params->end.min, MCDPORT(0));
+ outb(params->end.sec, MCDPORT(0));
+ outb(params->end.frame, MCDPORT(0));
}
* (see the next routine)
*/
-static void
-mcdStatTimer(unsigned long dummy)
+static void mcdStatTimer(unsigned long dummy)
{
- if (!(inb(MCDPORT(1)) & MFL_STATUS))
- {
+ if (!(inb(MCDPORT(1)) & MFL_STATUS)) {
wake_up(&mcd_waitq);
return;
}
McdTimeout--;
- if (McdTimeout <= 0)
- {
+ if (McdTimeout <= 0) {
wake_up(&mcd_waitq);
return;
}
* excessive rescheduling.
*/
-static int
-getMcdStatus(int timeout)
+static int getMcdStatus(int timeout)
{
int st;
/* XXX might be an error? look at q-channel? */
audioStatus = CDROM_AUDIO_COMPLETED;
- if (st & MST_DSK_CHG)
- {
+ if (st & MST_DSK_CHG) {
mcdDiskChanged = 1;
tocUpToDate = 0;
audioStatus = CDROM_AUDIO_NO_STATUS;
/* gives current state of the drive This function is quite unreliable,
and should probably be rewritten by someone, eventually... */
-int mcd_drive_status(struct cdrom_device_info * cdi, int slot_nr)
+int mcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
{
- int st;
-
- st = statusCmd(); /* check drive status */
- if (st == -1)
- return -EIO; /* drive doesn't respond */
- if ((st & MST_READY)) return CDS_DISC_OK;
- if ((st & MST_DOOR_OPEN)) return CDS_TRAY_OPEN;
- if ((st & MST_DSK_CHG)) return CDS_NO_DISC;
- if ((st & MST_BUSY)) return CDS_DRIVE_NOT_READY;
- return -EIO;
+ int st;
+
+ st = statusCmd(); /* check drive status */
+ if (st == -1)
+ return -EIO; /* drive doesn't respond */
+ if ((st & MST_READY))
+ return CDS_DISC_OK;
+ if ((st & MST_DOOR_OPEN))
+ return CDS_TRAY_OPEN;
+ if ((st & MST_DSK_CHG))
+ return CDS_NO_DISC;
+ if ((st & MST_BUSY))
+ return CDS_DRIVE_NOT_READY;
+ return -EIO;
}
* Read a value from the drive.
*/
-static int
-getValue(unsigned char *result)
+static int getValue(unsigned char *result)
{
- int count;
+ int count;
int s;
for (count = 0; count < 2000; count++)
if (!(inb(MCDPORT(1)) & MFL_STATUS))
break;
- if (count >= 2000)
- {
+ if (count >= 2000) {
printk("mcd: getValue timeout\n");
return -1;
}
* table of contents.
*/
-int
-GetQChannelInfo(struct mcd_Toc *qp)
+int GetQChannelInfo(struct mcd_Toc *qp)
{
unsigned char notUsed;
int retry;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
outb(MCMD_GET_Q_CHANNEL, MCDPORT(0));
if (getMcdStatus(MCD_STATUS_DELAY) != -1)
break;
if (retry >= MCD_RETRY_ATTEMPTS)
return -1;
- if (getValue(&qp -> ctrl_addr) < 0) return -1;
- if (getValue(&qp -> track) < 0) return -1;
- if (getValue(&qp -> pointIndex) < 0) return -1;
- if (getValue(&qp -> trackTime.min) < 0) return -1;
- if (getValue(&qp -> trackTime.sec) < 0) return -1;
- if (getValue(&qp -> trackTime.frame) < 0) return -1;
- if (getValue(¬Used) < 0) return -1;
- if (getValue(&qp -> diskTime.min) < 0) return -1;
- if (getValue(&qp -> diskTime.sec) < 0) return -1;
- if (getValue(&qp -> diskTime.frame) < 0) return -1;
+ if (getValue(&qp->ctrl_addr) < 0)
+ return -1;
+ if (getValue(&qp->track) < 0)
+ return -1;
+ if (getValue(&qp->pointIndex) < 0)
+ return -1;
+ if (getValue(&qp->trackTime.min) < 0)
+ return -1;
+ if (getValue(&qp->trackTime.sec) < 0)
+ return -1;
+ if (getValue(&qp->trackTime.frame) < 0)
+ return -1;
+ if (getValue(¬Used) < 0)
+ return -1;
+ if (getValue(&qp->diskTime.min) < 0)
+ return -1;
+ if (getValue(&qp->diskTime.sec) < 0)
+ return -1;
+ if (getValue(&qp->diskTime.frame) < 0)
+ return -1;
return 0;
}
* Read the table of contents (TOC) and TOC header if necessary
*/
-static int
-updateToc()
+static int updateToc()
{
if (tocUpToDate)
return 0;
* Read the table of contents header
*/
-static int
-GetDiskInfo()
+static int GetDiskInfo()
{
int retry;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
outb(MCMD_GET_DISK_INFO, MCDPORT(0));
if (getMcdStatus(MCD_STATUS_DELAY) != -1)
break;
if (retry >= MCD_RETRY_ATTEMPTS)
return -1;
- if (getValue(&DiskInfo.first) < 0) return -1;
- if (getValue(&DiskInfo.last) < 0) return -1;
+ if (getValue(&DiskInfo.first) < 0)
+ return -1;
+ if (getValue(&DiskInfo.last) < 0)
+ return -1;
DiskInfo.first = bcd2bin(DiskInfo.first);
DiskInfo.last = bcd2bin(DiskInfo.last);
#ifdef MCD_DEBUG
-printk("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
- DiskInfo.first,
- DiskInfo.last,
- DiskInfo.diskLength.min,
- DiskInfo.diskLength.sec,
- DiskInfo.diskLength.frame,
- DiskInfo.firstTrack.min,
- DiskInfo.firstTrack.sec,
- DiskInfo.firstTrack.frame);
+ printk
+ ("Disk Info: first %d last %d length %02x:%02x.%02x first %02x:%02x.%02x\n",
+ DiskInfo.first, DiskInfo.last, DiskInfo.diskLength.min,
+ DiskInfo.diskLength.sec, DiskInfo.diskLength.frame,
+ DiskInfo.firstTrack.min, DiskInfo.firstTrack.sec,
+ DiskInfo.firstTrack.frame);
#endif
- if (getValue(&DiskInfo.diskLength.min) < 0) return -1;
- if (getValue(&DiskInfo.diskLength.sec) < 0) return -1;
- if (getValue(&DiskInfo.diskLength.frame) < 0) return -1;
- if (getValue(&DiskInfo.firstTrack.min) < 0) return -1;
- if (getValue(&DiskInfo.firstTrack.sec) < 0) return -1;
- if (getValue(&DiskInfo.firstTrack.frame) < 0) return -1;
+ if (getValue(&DiskInfo.diskLength.min) < 0)
+ return -1;
+ if (getValue(&DiskInfo.diskLength.sec) < 0)
+ return -1;
+ if (getValue(&DiskInfo.diskLength.frame) < 0)
+ return -1;
+ if (getValue(&DiskInfo.firstTrack.min) < 0)
+ return -1;
+ if (getValue(&DiskInfo.firstTrack.sec) < 0)
+ return -1;
+ if (getValue(&DiskInfo.firstTrack.frame) < 0)
+ return -1;
return 0;
}
* Read the table of contents (TOC)
*/
-static int
-GetToc()
+static int GetToc()
{
int i, px;
int limit;
i = DiskInfo.last + 3;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
outb(MCMD_STOP, MCDPORT(0));
if (getMcdStatus(MCD_STATUS_DELAY) != -1)
break;
if (retry >= MCD_RETRY_ATTEMPTS)
return -1;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
outb(MCMD_SET_MODE, MCDPORT(0));
- outb(0x05, MCDPORT(0)); /* mode: toc */
+ outb(0x05, MCDPORT(0)); /* mode: toc */
mcd_mode = 0x05;
if (getMcdStatus(MCD_STATUS_DELAY) != -1)
break;
if (retry >= MCD_RETRY_ATTEMPTS)
return -1;
- for (limit = 300; limit > 0; limit--)
- {
+ for (limit = 300; limit > 0; limit--) {
if (GetQChannelInfo(&qInfo) < 0)
break;
px = bcd2bin(qInfo.pointIndex);
if (px > 0 && px < MAX_TRACKS && qInfo.track == 0)
- if (Toc[px].pointIndex == 0)
- {
+ if (Toc[px].pointIndex == 0) {
Toc[px] = qInfo;
i--;
}
Toc[DiskInfo.last + 1].diskTime = DiskInfo.diskLength;
- for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++)
- {
- outb(MCMD_SET_MODE, MCDPORT(0));
- outb(0x01, MCDPORT(0));
+ for (retry = 0; retry < MCD_RETRY_ATTEMPTS; retry++) {
+ outb(MCMD_SET_MODE, MCDPORT(0));
+ outb(0x01, MCDPORT(0));
mcd_mode = 1;
- if (getMcdStatus(MCD_STATUS_DELAY) != -1)
- break;
+ if (getMcdStatus(MCD_STATUS_DELAY) != -1)
+ break;
}
#ifdef MCD_DEBUG
-for (i = 1; i <= DiskInfo.last; i++)
-printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X %02X:%02X.%02X\n",
-i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
-for (i = 100; i < 103; i++)
-printk("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X %02X:%02X.%02X\n",
-i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
-Toc[i].trackTime.min, Toc[i].trackTime.sec, Toc[i].trackTime.frame,
-Toc[i].diskTime.min, Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+ for (i = 1; i <= DiskInfo.last; i++)
+ printk
+ ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X %02X:%02X.%02X\n",
+ i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+ Toc[i].trackTime.min, Toc[i].trackTime.sec,
+ Toc[i].trackTime.frame, Toc[i].diskTime.min,
+ Toc[i].diskTime.sec, Toc[i].diskTime.frame);
+ for (i = 100; i < 103; i++)
+ printk
+ ("i = %2d ctl-adr = %02X track %2d px %02X %02X:%02X.%02X %02X:%02X.%02X\n",
+ i, Toc[i].ctrl_addr, Toc[i].track, Toc[i].pointIndex,
+ Toc[i].trackTime.min, Toc[i].trackTime.sec,
+ Toc[i].trackTime.frame, Toc[i].diskTime.min,
+ Toc[i].diskTime.sec, Toc[i].diskTime.frame);
#endif
return limit > 0 ? 0 : -1;
void __exit mcd_exit(void)
{
- cleanup(3);
- del_timer_sync(&mcd_timer);
+ cleanup(3);
+ del_timer_sync(&mcd_timer);
}
#ifdef MODULE
module_init(mcd_init);
-#endif
+#endif
module_exit(mcd_exit);
-
+MODULE_AUTHOR("Martin Harriss");
+MODULE_LICENSE("GPL");
#if RCS
static const char *mcdx_c_version
- = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
+ = "$Id: mcdx.c,v 1.21 1997/01/26 07:12:59 davem Exp $";
#endif
#include <linux/version.h>
enum datamodes { MODE0, MODE1, MODE2 };
enum resetmodes { SOFT, HARD };
-const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
-const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
-const int DOOR = 0x04; /* door locking capability */
-const int MULTI = 0x08; /* multi session capability */
+const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */
+const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */
+const int DOOR = 0x04; /* door locking capability */
+const int MULTI = 0x08; /* multi session capability */
const unsigned char READ1X = 0xc0;
const unsigned char READ2X = 0xc1;
struct s_drive_stuff {
/* waitqueues */
- wait_queue_head_t busyq;
- wait_queue_head_t lockq;
- wait_queue_head_t sleepq;
+ wait_queue_head_t busyq;
+ wait_queue_head_t lockq;
+ wait_queue_head_t sleepq;
- /* flags */
- volatile int introk; /* status of last irq operation */
- volatile int busy; /* drive performs an operation */
- volatile int lock; /* exclusive usage */
+ /* flags */
+ volatile int introk; /* status of last irq operation */
+ volatile int busy; /* drive performs an operation */
+ volatile int lock; /* exclusive usage */
/* cd infos */
struct s_diskinfo di;
struct s_multi multi;
- struct s_subqcode* toc; /* first entry of the toc array */
+ struct s_subqcode *toc; /* first entry of the toc array */
struct s_subqcode start;
- struct s_subqcode stop;
- int xa; /* 1 if xa disk */
- int audio; /* 1 if audio disk */
+ struct s_subqcode stop;
+ int xa; /* 1 if xa disk */
+ int audio; /* 1 if audio disk */
int audiostatus;
/* `buffer' control */
- volatile int valid; /* pending, ..., values are valid */
- volatile int pending; /* next sector to be read */
- volatile int low_border; /* first sector not to be skipped direct */
- volatile int high_border; /* first sector `out of area' */
+ volatile int valid; /* pending, ..., values are valid */
+ volatile int pending; /* next sector to be read */
+ volatile int low_border; /* first sector not to be skipped direct */
+ volatile int high_border; /* first sector `out of area' */
#ifdef AK2
- volatile int int_err;
-#endif /* AK2 */
+ volatile int int_err;
+#endif /* AK2 */
/* adds and odds */
- void* wreg_data; /* w data */
- void* wreg_reset; /* w hardware reset */
- void* wreg_hcon; /* w hardware conf */
- void* wreg_chn; /* w channel */
- void* rreg_data; /* r data */
- void* rreg_status; /* r status */
-
- int irq; /* irq used by this drive */
- int minor; /* minor number of this drive */
- int present; /* drive present and its capabilities */
- unsigned char readcmd; /* read cmd depends on single/double speed */
- unsigned char playcmd; /* play should always be single speed */
- unsigned int xxx; /* set if changed, reset while open */
- unsigned int yyy; /* set if changed, reset by media_changed */
- int users; /* keeps track of open/close */
- int lastsector; /* last block accessible */
- int status; /* last operation's error / status */
- int readerrs; /* # of blocks read w/o error */
+ void *wreg_data; /* w data */
+ void *wreg_reset; /* w hardware reset */
+ void *wreg_hcon; /* w hardware conf */
+ void *wreg_chn; /* w channel */
+ void *rreg_data; /* r data */
+ void *rreg_status; /* r status */
+
+ int irq; /* irq used by this drive */
+ int minor; /* minor number of this drive */
+ int present; /* drive present and its capabilities */
+ unsigned char readcmd; /* read cmd depends on single/double speed */
+ unsigned char playcmd; /* play should always be single speed */
+ unsigned int xxx; /* set if changed, reset while open */
+ unsigned int yyy; /* set if changed, reset by media_changed */
+ int users; /* keeps track of open/close */
+ int lastsector; /* last block accessible */
+ int status; /* last operation's error / status */
+ int readerrs; /* # of blocks read w/o error */
};
structure mcdx_dops. */
/* ??? exported by the mcdx_sigaction struct */
-static void mcdx_intr(int, void *, struct pt_regs*);
+static void mcdx_intr(int, void *, struct pt_regs *);
/* exported by file_ops */
-static int mcdx_open(struct cdrom_device_info * cdi, int purpose);
-static void mcdx_close(struct cdrom_device_info * cdi);
-static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr);
-static int mcdx_tray_move(struct cdrom_device_info * cdi, int position);
-static int mcdx_lockdoor(struct cdrom_device_info * cdi, int lock);
-static int mcdx_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
- void * arg);
+static int mcdx_open(struct cdrom_device_info *cdi, int purpose);
+static void mcdx_close(struct cdrom_device_info *cdi);
+static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr);
+static int mcdx_tray_move(struct cdrom_device_info *cdi, int position);
+static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock);
+static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
+ unsigned int cmd, void *arg);
/* misc internal support functions */
-static void log2msf(unsigned int, struct cdrom_msf0*);
-static unsigned int msf2log(const struct cdrom_msf0*);
+static void log2msf(unsigned int, struct cdrom_msf0 *);
+static unsigned int msf2log(const struct cdrom_msf0 *);
static unsigned int uint2bcd(unsigned int);
static unsigned int bcd2uint(unsigned char);
-static char *port(int*);
-static int irq(int*);
-static void mcdx_delay(struct s_drive_stuff*, long jifs);
-static int mcdx_transfer(struct s_drive_stuff*, char* buf, int sector, int nr_sectors);
-static int mcdx_xfer(struct s_drive_stuff*, char* buf, int sector, int nr_sectors);
-
-static int mcdx_config(struct s_drive_stuff*, int);
-static int mcdx_requestversion(struct s_drive_stuff*, struct s_version*, int);
-static int mcdx_stop(struct s_drive_stuff*, int);
-static int mcdx_hold(struct s_drive_stuff*, int);
-static int mcdx_reset(struct s_drive_stuff*, enum resetmodes, int);
-static int mcdx_setdrivemode(struct s_drive_stuff*, enum drivemodes, int);
-static int mcdx_setdatamode(struct s_drive_stuff*, enum datamodes, int);
-static int mcdx_requestsubqcode(struct s_drive_stuff*, struct s_subqcode*, int);
-static int mcdx_requestmultidiskinfo(struct s_drive_stuff*, struct s_multi*, int);
-static int mcdx_requesttocdata(struct s_drive_stuff*, struct s_diskinfo*, int);
-static int mcdx_getstatus(struct s_drive_stuff*, int);
-static int mcdx_getval(struct s_drive_stuff*, int to, int delay, char*);
-static int mcdx_talk(struct s_drive_stuff*,
- const unsigned char* cmd, size_t,
- void *buffer, size_t size,
- unsigned int timeout, int);
-static int mcdx_readtoc(struct s_drive_stuff*);
-static int mcdx_playtrk(struct s_drive_stuff*, const struct cdrom_ti*);
-static int mcdx_playmsf(struct s_drive_stuff*, const struct cdrom_msf*);
-static int mcdx_setattentuator(struct s_drive_stuff*, struct cdrom_volctrl*, int);
+static char *port(int *);
+static int irq(int *);
+static void mcdx_delay(struct s_drive_stuff *, long jifs);
+static int mcdx_transfer(struct s_drive_stuff *, char *buf, int sector,
+ int nr_sectors);
+static int mcdx_xfer(struct s_drive_stuff *, char *buf, int sector,
+ int nr_sectors);
+
+static int mcdx_config(struct s_drive_stuff *, int);
+static int mcdx_requestversion(struct s_drive_stuff *, struct s_version *,
+ int);
+static int mcdx_stop(struct s_drive_stuff *, int);
+static int mcdx_hold(struct s_drive_stuff *, int);
+static int mcdx_reset(struct s_drive_stuff *, enum resetmodes, int);
+static int mcdx_setdrivemode(struct s_drive_stuff *, enum drivemodes, int);
+static int mcdx_setdatamode(struct s_drive_stuff *, enum datamodes, int);
+static int mcdx_requestsubqcode(struct s_drive_stuff *,
+ struct s_subqcode *, int);
+static int mcdx_requestmultidiskinfo(struct s_drive_stuff *,
+ struct s_multi *, int);
+static int mcdx_requesttocdata(struct s_drive_stuff *, struct s_diskinfo *,
+ int);
+static int mcdx_getstatus(struct s_drive_stuff *, int);
+static int mcdx_getval(struct s_drive_stuff *, int to, int delay, char *);
+static int mcdx_talk(struct s_drive_stuff *,
+ const unsigned char *cmd, size_t,
+ void *buffer, size_t size, unsigned int timeout, int);
+static int mcdx_readtoc(struct s_drive_stuff *);
+static int mcdx_playtrk(struct s_drive_stuff *, const struct cdrom_ti *);
+static int mcdx_playmsf(struct s_drive_stuff *, const struct cdrom_msf *);
+static int mcdx_setattentuator(struct s_drive_stuff *,
+ struct cdrom_volctrl *, int);
/* static variables ************************************************/
static int mcdx_blocksizes[MCDX_NDRIVES];
static int mcdx_drive_map[][2] = MCDX_DRIVEMAP;
-static struct s_drive_stuff* mcdx_stuffp[MCDX_NDRIVES];
-static struct s_drive_stuff* mcdx_irq_map[16] =
- {0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0};
+static struct s_drive_stuff *mcdx_stuffp[MCDX_NDRIVES];
+static struct s_drive_stuff *mcdx_irq_map[16] = { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
MODULE_PARM(mcdx, "1-4i");
static struct cdrom_device_ops mcdx_dops = {
- open: mcdx_open,
- release: mcdx_close,
- media_changed: mcdx_media_changed,
- tray_move: mcdx_tray_move,
- lock_door: mcdx_lockdoor,
- audio_ioctl: mcdx_audio_ioctl,
- capability: CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
- CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
+ open:mcdx_open,
+ release:mcdx_close,
+ media_changed:mcdx_media_changed,
+ tray_move:mcdx_tray_move,
+ lock_door:mcdx_lockdoor,
+ audio_ioctl:mcdx_audio_ioctl,
+ capability:CDC_OPEN_TRAY | CDC_LOCK | CDC_MEDIA_CHANGED |
+ CDC_PLAY_AUDIO | CDC_DRIVE_STATUS,
};
static struct cdrom_device_info mcdx_info = {
- ops: &mcdx_dops,
- speed: 2,
- capacity: 1,
- name: "mcdx",
+ ops:&mcdx_dops,
+ speed:2,
+ capacity:1,
+ name:"mcdx",
};
/* KERNEL INTERFACE FUNCTIONS **************************************/
-static int mcdx_audio_ioctl(struct cdrom_device_info * cdi, unsigned int cmd,
- void * arg)
+static int mcdx_audio_ioctl(struct cdrom_device_info *cdi,
+ unsigned int cmd, void *arg)
{
struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
- if (!stuffp->present) return -ENXIO;
+ if (!stuffp->present)
+ return -ENXIO;
- if (stuffp->xxx)
- {
- if(-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1))
- {
+ if (stuffp->xxx) {
+ if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
stuffp->lastsector = -1;
- }
- else
- {
+ } else {
stuffp->lastsector = (CD_FRAMESIZE / 512)
- * msf2log(&stuffp->di.msf_leadout) - 1;
+ * msf2log(&stuffp->di.msf_leadout) - 1;
}
- if (stuffp->toc)
- {
+ if (stuffp->toc) {
kfree(stuffp->toc);
stuffp->toc = NULL;
- if (-1 == mcdx_readtoc(stuffp)) return -1;
+ if (-1 == mcdx_readtoc(stuffp))
+ return -1;
}
- stuffp->xxx=0;
+ stuffp->xxx = 0;
}
switch (cmd) {
- case CDROMSTART: {
- xtrace(IOCTL, "ioctl() START\n");
- /* Spin up the drive. Don't think we can do this.
- * For now, ignore it.
- */
+ case CDROMSTART:{
+ xtrace(IOCTL, "ioctl() START\n");
+ /* Spin up the drive. Don't think we can do this.
+ * For now, ignore it.
+ */
return 0;
}
- case CDROMSTOP: {
+ case CDROMSTOP:{
xtrace(IOCTL, "ioctl() STOP\n");
- stuffp->audiostatus = CDROM_AUDIO_INVALID;
+ stuffp->audiostatus = CDROM_AUDIO_INVALID;
if (-1 == mcdx_stop(stuffp, 1))
return -EIO;
return 0;
}
- case CDROMPLAYTRKIND: {
- struct cdrom_ti *ti=(struct cdrom_ti *) arg;
+ case CDROMPLAYTRKIND:{
+ struct cdrom_ti *ti = (struct cdrom_ti *) arg;
xtrace(IOCTL, "ioctl() PLAYTRKIND\n");
if ((ti->cdti_trk0 < stuffp->di.n_first)
- || (ti->cdti_trk0 > stuffp->di.n_last)
- || (ti->cdti_trk1 < stuffp->di.n_first))
- return -EINVAL;
+ || (ti->cdti_trk0 > stuffp->di.n_last)
+ || (ti->cdti_trk1 < stuffp->di.n_first))
+ return -EINVAL;
if (ti->cdti_trk1 > stuffp->di.n_last)
- ti->cdti_trk1 = stuffp->di.n_last;
- xtrace(PLAYTRK, "ioctl() track %d to %d\n", ti->cdti_trk0, ti->cdti_trk1);
- return mcdx_playtrk(stuffp, ti);
- }
+ ti->cdti_trk1 = stuffp->di.n_last;
+ xtrace(PLAYTRK, "ioctl() track %d to %d\n",
+ ti->cdti_trk0, ti->cdti_trk1);
+ return mcdx_playtrk(stuffp, ti);
+ }
- case CDROMPLAYMSF: {
- struct cdrom_msf *msf=(struct cdrom_msf *) arg;
+ case CDROMPLAYMSF:{
+ struct cdrom_msf *msf = (struct cdrom_msf *) arg;
- xtrace(IOCTL, "ioctl() PLAYMSF\n");
+ xtrace(IOCTL, "ioctl() PLAYMSF\n");
- if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
- && (-1 == mcdx_hold(stuffp, 1))) return -EIO;
+ if ((stuffp->audiostatus == CDROM_AUDIO_PLAY)
+ && (-1 == mcdx_hold(stuffp, 1)))
+ return -EIO;
- msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
- msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
- msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
+ msf->cdmsf_min0 = uint2bcd(msf->cdmsf_min0);
+ msf->cdmsf_sec0 = uint2bcd(msf->cdmsf_sec0);
+ msf->cdmsf_frame0 = uint2bcd(msf->cdmsf_frame0);
- msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
- msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
- msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
+ msf->cdmsf_min1 = uint2bcd(msf->cdmsf_min1);
+ msf->cdmsf_sec1 = uint2bcd(msf->cdmsf_sec1);
+ msf->cdmsf_frame1 = uint2bcd(msf->cdmsf_frame1);
- stuffp->stop.dt.minute = msf->cdmsf_min1;
- stuffp->stop.dt.second = msf->cdmsf_sec1;
- stuffp->stop.dt.frame = msf->cdmsf_frame1;
+ stuffp->stop.dt.minute = msf->cdmsf_min1;
+ stuffp->stop.dt.second = msf->cdmsf_sec1;
+ stuffp->stop.dt.frame = msf->cdmsf_frame1;
- return mcdx_playmsf(stuffp, msf);
- }
+ return mcdx_playmsf(stuffp, msf);
+ }
- case CDROMRESUME: {
- xtrace(IOCTL, "ioctl() RESUME\n");
- return mcdx_playtrk(stuffp, NULL);
- }
+ case CDROMRESUME:{
+ xtrace(IOCTL, "ioctl() RESUME\n");
+ return mcdx_playtrk(stuffp, NULL);
+ }
- case CDROMREADTOCENTRY: {
- struct cdrom_tocentry *entry=(struct cdrom_tocentry *) arg;
+ case CDROMREADTOCENTRY:{
+ struct cdrom_tocentry *entry =
+ (struct cdrom_tocentry *) arg;
struct s_subqcode *tp = NULL;
xtrace(IOCTL, "ioctl() READTOCENTRY\n");
- if (-1 == mcdx_readtoc(stuffp)) return -1;
+ if (-1 == mcdx_readtoc(stuffp))
+ return -1;
if (entry->cdte_track == CDROM_LEADOUT)
- tp = &stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1];
+ tp = &stuffp->toc[stuffp->di.n_last -
+ stuffp->di.n_first + 1];
else if (entry->cdte_track > stuffp->di.n_last
- || entry->cdte_track < stuffp->di.n_first) return -EINVAL;
- else tp = &stuffp->toc[entry->cdte_track - stuffp->di.n_first];
+ || entry->cdte_track < stuffp->di.n_first)
+ return -EINVAL;
+ else
+ tp = &stuffp->toc[entry->cdte_track -
+ stuffp->di.n_first];
- if (NULL == tp)
+ if (NULL == tp)
return -EIO;
entry->cdte_adr = tp->control;
entry->cdte_ctrl = tp->control >> 4;
- /* Always return stuff in MSF, and let the Uniform cdrom driver
- worry about what the user actually wants */
- entry->cdte_addr.msf.minute = bcd2uint(tp->dt.minute);
- entry->cdte_addr.msf.second = bcd2uint(tp->dt.second);
- entry->cdte_addr.msf.frame = bcd2uint(tp->dt.frame);
+ /* Always return stuff in MSF, and let the Uniform cdrom driver
+ worry about what the user actually wants */
+ entry->cdte_addr.msf.minute =
+ bcd2uint(tp->dt.minute);
+ entry->cdte_addr.msf.second =
+ bcd2uint(tp->dt.second);
+ entry->cdte_addr.msf.frame =
+ bcd2uint(tp->dt.frame);
return 0;
}
- case CDROMSUBCHNL: {
- struct cdrom_subchnl *sub= (struct cdrom_subchnl *)arg;
+ case CDROMSUBCHNL:{
+ struct cdrom_subchnl *sub =
+ (struct cdrom_subchnl *) arg;
struct s_subqcode q;
xtrace(IOCTL, "ioctl() SUBCHNL\n");
- if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
+ if (-1 == mcdx_requestsubqcode(stuffp, &q, 2))
return -EIO;
- xtrace(SUBCHNL, "audiostatus: %x\n", stuffp->audiostatus);
+ xtrace(SUBCHNL, "audiostatus: %x\n",
+ stuffp->audiostatus);
sub->cdsc_audiostatus = stuffp->audiostatus;
sub->cdsc_adr = q.control;
sub->cdsc_ctrl = q.control >> 4;
sub->cdsc_trk = bcd2uint(q.tno);
sub->cdsc_ind = bcd2uint(q.index);
- xtrace(SUBCHNL, "trk %d, ind %d\n",
- sub->cdsc_trk, sub->cdsc_ind);
- /* Always return stuff in MSF, and let the Uniform cdrom driver
- worry about what the user actually wants */
- sub->cdsc_absaddr.msf.minute = bcd2uint(q.dt.minute);
- sub->cdsc_absaddr.msf.second = bcd2uint(q.dt.second);
+ xtrace(SUBCHNL, "trk %d, ind %d\n",
+ sub->cdsc_trk, sub->cdsc_ind);
+ /* Always return stuff in MSF, and let the Uniform cdrom driver
+ worry about what the user actually wants */
+ sub->cdsc_absaddr.msf.minute =
+ bcd2uint(q.dt.minute);
+ sub->cdsc_absaddr.msf.second =
+ bcd2uint(q.dt.second);
sub->cdsc_absaddr.msf.frame = bcd2uint(q.dt.frame);
- sub->cdsc_reladdr.msf.minute = bcd2uint(q.tt.minute);
- sub->cdsc_reladdr.msf.second = bcd2uint(q.tt.second);
+ sub->cdsc_reladdr.msf.minute =
+ bcd2uint(q.tt.minute);
+ sub->cdsc_reladdr.msf.second =
+ bcd2uint(q.tt.second);
sub->cdsc_reladdr.msf.frame = bcd2uint(q.tt.frame);
xtrace(SUBCHNL,
- "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
- sub->cdsc_absaddr.msf.minute, sub->cdsc_absaddr.msf.second,
- sub->cdsc_absaddr.msf.frame, sub->cdsc_reladdr.msf.minute,
- sub->cdsc_reladdr.msf.second, sub->cdsc_reladdr.msf.frame);
+ "msf: abs %02d:%02d:%02d, rel %02d:%02d:%02d\n",
+ sub->cdsc_absaddr.msf.minute,
+ sub->cdsc_absaddr.msf.second,
+ sub->cdsc_absaddr.msf.frame,
+ sub->cdsc_reladdr.msf.minute,
+ sub->cdsc_reladdr.msf.second,
+ sub->cdsc_reladdr.msf.frame);
return 0;
}
- case CDROMREADTOCHDR: {
- struct cdrom_tochdr *toc=(struct cdrom_tochdr *) arg;
+ case CDROMREADTOCHDR:{
+ struct cdrom_tochdr *toc =
+ (struct cdrom_tochdr *) arg;
xtrace(IOCTL, "ioctl() READTOCHDR\n");
toc->cdth_trk0 = stuffp->di.n_first;
toc->cdth_trk1 = stuffp->di.n_last;
- xtrace(TOCHDR, "ioctl() track0 = %d, track1 = %d\n",
- stuffp->di.n_first, stuffp->di.n_last);
+ xtrace(TOCHDR,
+ "ioctl() track0 = %d, track1 = %d\n",
+ stuffp->di.n_first, stuffp->di.n_last);
return 0;
}
- case CDROMPAUSE: {
+ case CDROMPAUSE:{
xtrace(IOCTL, "ioctl() PAUSE\n");
- if (stuffp->audiostatus != CDROM_AUDIO_PLAY) return -EINVAL;
- if (-1 == mcdx_stop(stuffp, 1)) return -EIO;
- stuffp->audiostatus = CDROM_AUDIO_PAUSED;
- if (-1 == mcdx_requestsubqcode(stuffp, &stuffp->start, 1))
+ if (stuffp->audiostatus != CDROM_AUDIO_PLAY)
+ return -EINVAL;
+ if (-1 == mcdx_stop(stuffp, 1))
+ return -EIO;
+ stuffp->audiostatus = CDROM_AUDIO_PAUSED;
+ if (-1 ==
+ mcdx_requestsubqcode(stuffp, &stuffp->start,
+ 1))
return -EIO;
return 0;
}
- case CDROMMULTISESSION: {
- struct cdrom_multisession *ms=(struct cdrom_multisession *) arg;
+ case CDROMMULTISESSION:{
+ struct cdrom_multisession *ms =
+ (struct cdrom_multisession *) arg;
xtrace(IOCTL, "ioctl() MULTISESSION\n");
/* Always return stuff in LBA, and let the Uniform cdrom driver
- worry about what the user actually wants */
+ worry about what the user actually wants */
ms->addr.lba = msf2log(&stuffp->multi.msf_last);
ms->xa_flag = !!stuffp->multi.multi;
- xtrace(MS, "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
- ms->xa_flag, ms->addr.lba, stuffp->multi.msf_last.minute,
- stuffp->multi.msf_last.second,stuffp->multi.msf_last.frame);
-
+ xtrace(MS,
+ "ioctl() (%d, 0x%08x [%02x:%02x.%02x])\n",
+ ms->xa_flag, ms->addr.lba,
+ stuffp->multi.msf_last.minute,
+ stuffp->multi.msf_last.second,
+ stuffp->multi.msf_last.frame);
+
return 0;
}
- case CDROMEJECT: {
+ case CDROMEJECT:{
xtrace(IOCTL, "ioctl() EJECT\n");
- if (stuffp->users > 1) return -EBUSY;
- return(mcdx_tray_move(cdi, 1));
+ if (stuffp->users > 1)
+ return -EBUSY;
+ return (mcdx_tray_move(cdi, 1));
}
- case CDROMCLOSETRAY: {
- xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
- return(mcdx_tray_move(cdi, 0));
- }
+ case CDROMCLOSETRAY:{
+ xtrace(IOCTL, "ioctl() CDROMCLOSETRAY\n");
+ return (mcdx_tray_move(cdi, 0));
+ }
- case CDROMVOLCTRL: {
- struct cdrom_volctrl *volctrl=(struct cdrom_volctrl *)arg;
- xtrace(IOCTL, "ioctl() VOLCTRL\n");
+ case CDROMVOLCTRL:{
+ struct cdrom_volctrl *volctrl =
+ (struct cdrom_volctrl *) arg;
+ xtrace(IOCTL, "ioctl() VOLCTRL\n");
-#if 0 /* not tested! */
+#if 0 /* not tested! */
/* adjust for the weirdness of workman (md) */
/* can't test it (hs) */
volctrl.channel2 = volctrl.channel1;
volctrl.channel1 = volctrl.channel3 = 0x00;
#endif
- return mcdx_setattentuator(stuffp, volctrl, 2);
- }
+ return mcdx_setattentuator(stuffp, volctrl, 2);
+ }
- default:
- xwarn("ioctl(): unknown request 0x%04x\n", cmd);
- return -EINVAL;
+ default:
+ return -EINVAL;
}
}
void do_mcdx_request(request_queue_t * q)
{
- int dev;
- struct s_drive_stuff *stuffp;
+ int dev;
+ struct s_drive_stuff *stuffp;
- again:
+ again:
if (QUEUE_EMPTY) {
xtrace(REQUEST, "end_request(0): CURRENT == NULL\n");
}
if (CURRENT->rq_status == RQ_INACTIVE) {
- xtrace(REQUEST, "end_request(0): rq_status == RQ_INACTIVE\n");
+ xtrace(REQUEST,
+ "end_request(0): rq_status == RQ_INACTIVE\n");
return;
}
- INIT_REQUEST;
+ INIT_REQUEST;
- dev = MINOR(CURRENT->rq_dev);
- stuffp = mcdx_stuffp[dev];
+ dev = MINOR(CURRENT->rq_dev);
+ stuffp = mcdx_stuffp[dev];
if ((dev < 0)
- || (dev >= MCDX_NDRIVES)
- || !stuffp
- || (!stuffp->present)) {
+ || (dev >= MCDX_NDRIVES)
+ || !stuffp || (!stuffp->present)) {
xwarn("do_request(): bad device: %s\n",
- kdevname(CURRENT->rq_dev));
+ kdevname(CURRENT->rq_dev));
xtrace(REQUEST, "end_request(0): bad device\n");
- end_request(0); return;
- }
+ end_request(0);
+ return;
+ }
if (stuffp->audio) {
xwarn("do_request() attempt to read from audio cd\n");
xtrace(REQUEST, "end_request(0): read from audio\n");
- end_request(0); return;
+ end_request(0);
+ return;
}
xtrace(REQUEST, "do_request() (%lu + %lu)\n",
- CURRENT->sector, CURRENT->nr_sectors);
-
- switch (CURRENT->cmd) {
- case WRITE:
- xwarn("do_request(): attempt to write to cd!!\n");
- xtrace(REQUEST, "end_request(0): write\n");
- end_request(0); return;
-
- case READ:
- stuffp->status = 0;
- while (CURRENT->nr_sectors) {
- int i;
-
- i = mcdx_transfer(stuffp,
- CURRENT->buffer,
- CURRENT->sector,
- CURRENT->nr_sectors);
-
- if (i == -1) {
- end_request(0);
- goto again;
- }
- CURRENT->sector += i;
- CURRENT->nr_sectors -= i;
- CURRENT->buffer += (i * 512);
- }
- end_request(1);
- goto again;
-
- xtrace(REQUEST, "end_request(1)\n");
- end_request(1);
- break;
-
- default:
- panic(MCDX "do_request: unknown command.\n");
- break;
- }
-
- goto again;
+ CURRENT->sector, CURRENT->nr_sectors);
+
+ switch (CURRENT->cmd) {
+ case WRITE:
+ xwarn("do_request(): attempt to write to cd!!\n");
+ xtrace(REQUEST, "end_request(0): write\n");
+ end_request(0);
+ return;
+
+ case READ:
+ stuffp->status = 0;
+ while (CURRENT->nr_sectors) {
+ int i;
+
+ i = mcdx_transfer(stuffp,
+ CURRENT->buffer,
+ CURRENT->sector,
+ CURRENT->nr_sectors);
+
+ if (i == -1) {
+ end_request(0);
+ goto again;
+ }
+ CURRENT->sector += i;
+ CURRENT->nr_sectors -= i;
+ CURRENT->buffer += (i * 512);
+ }
+ end_request(1);
+ goto again;
+
+ xtrace(REQUEST, "end_request(1)\n");
+ end_request(1);
+ break;
+
+ default:
+ panic(MCDX "do_request: unknown command.\n");
+ break;
+ }
+
+ goto again;
}
-static int
-mcdx_open(struct cdrom_device_info * cdi, int purpose)
+static int mcdx_open(struct cdrom_device_info *cdi, int purpose)
{
- struct s_drive_stuff *stuffp;
+ struct s_drive_stuff *stuffp;
xtrace(OPENCLOSE, "open()\n");
- stuffp = mcdx_stuffp[MINOR(cdi->dev)];
- if (!stuffp->present) return -ENXIO;
+ stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+ if (!stuffp->present)
+ return -ENXIO;
/* Make the modules looking used ... (thanx bjorn).
* But we shouldn't forget to decrement the module counter
* on error return */
MOD_INC_USE_COUNT;
- /* this is only done to test if the drive talks with us */
- if (-1 == mcdx_getstatus(stuffp, 1)) {
+ /* this is only done to test if the drive talks with us */
+ if (-1 == mcdx_getstatus(stuffp, 1)) {
MOD_DEC_USE_COUNT;
return -EIO;
}
- if (stuffp->xxx) {
+ if (stuffp->xxx) {
+
+ xtrace(OPENCLOSE, "open() media changed\n");
+ stuffp->audiostatus = CDROM_AUDIO_INVALID;
+ stuffp->readcmd = 0;
+ xtrace(OPENCLOSE, "open() Request multisession info\n");
+ if (-1 ==
+ mcdx_requestmultidiskinfo(stuffp, &stuffp->multi, 6))
+ xinfo("No multidiskinfo\n");
+ } else {
+ /* multisession ? */
+ if (!stuffp->multi.multi)
+ stuffp->multi.msf_last.second = 2;
+
+ xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
+ stuffp->multi.multi,
+ stuffp->multi.msf_last.minute,
+ stuffp->multi.msf_last.second,
+ stuffp->multi.msf_last.frame);
+
+ {;
+ } /* got multisession information */
+ /* request the disks table of contents (aka diskinfo) */
+ if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
+
+ stuffp->lastsector = -1;
- xtrace(OPENCLOSE, "open() media changed\n");
- stuffp->audiostatus = CDROM_AUDIO_INVALID;
- stuffp->readcmd = 0;
- xtrace(OPENCLOSE, "open() Request multisession info\n");
- if (-1 == mcdx_requestmultidiskinfo( stuffp, &stuffp->multi, 6))
- xinfo("No multidiskinfo\n");
} else {
- /* multisession ? */
- if (!stuffp->multi.multi)
- stuffp->multi.msf_last.second = 2;
-
- xtrace(OPENCLOSE, "open() MS: %d, last @ %02x:%02x.%02x\n",
- stuffp->multi.multi,
- stuffp->multi.msf_last.minute,
- stuffp->multi.msf_last.second,
- stuffp->multi.msf_last.frame);
-
- { ; } /* got multisession information */
- /* request the disks table of contents (aka diskinfo) */
- if (-1 == mcdx_requesttocdata(stuffp, &stuffp->di, 1)) {
-
- stuffp->lastsector = -1;
-
- } else {
-
- stuffp->lastsector = (CD_FRAMESIZE / 512)
- * msf2log(&stuffp->di.msf_leadout) - 1;
-
- xtrace(OPENCLOSE, "open() start %d (%02x:%02x.%02x) %d\n",
- stuffp->di.n_first,
- stuffp->di.msf_first.minute,
- stuffp->di.msf_first.second,
- stuffp->di.msf_first.frame,
- msf2log(&stuffp->di.msf_first));
- xtrace(OPENCLOSE, "open() last %d (%02x:%02x.%02x) %d\n",
- stuffp->di.n_last,
- stuffp->di.msf_leadout.minute,
- stuffp->di.msf_leadout.second,
- stuffp->di.msf_leadout.frame,
- msf2log(&stuffp->di.msf_leadout));
- }
-
- if (stuffp->toc) {
- xtrace(MALLOC, "open() free old toc @ %p\n", stuffp->toc);
- kfree(stuffp->toc);
-
- stuffp->toc = NULL;
- }
-
- xtrace(OPENCLOSE, "open() init irq generation\n");
- if (-1 == mcdx_config(stuffp, 1)) {
- MOD_DEC_USE_COUNT;
- return -EIO;
- }
+ stuffp->lastsector = (CD_FRAMESIZE / 512)
+ * msf2log(&stuffp->di.msf_leadout) - 1;
+
+ xtrace(OPENCLOSE,
+ "open() start %d (%02x:%02x.%02x) %d\n",
+ stuffp->di.n_first,
+ stuffp->di.msf_first.minute,
+ stuffp->di.msf_first.second,
+ stuffp->di.msf_first.frame,
+ msf2log(&stuffp->di.msf_first));
+ xtrace(OPENCLOSE,
+ "open() last %d (%02x:%02x.%02x) %d\n",
+ stuffp->di.n_last,
+ stuffp->di.msf_leadout.minute,
+ stuffp->di.msf_leadout.second,
+ stuffp->di.msf_leadout.frame,
+ msf2log(&stuffp->di.msf_leadout));
+ }
+
+ if (stuffp->toc) {
+ xtrace(MALLOC, "open() free old toc @ %p\n",
+ stuffp->toc);
+ kfree(stuffp->toc);
+
+ stuffp->toc = NULL;
+ }
+
+ xtrace(OPENCLOSE, "open() init irq generation\n");
+ if (-1 == mcdx_config(stuffp, 1)) {
+ MOD_DEC_USE_COUNT;
+ return -EIO;
+ }
#if FALLBACK
- /* Set the read speed */
- xwarn("AAA %x AAA\n", stuffp->readcmd);
- if (stuffp->readerrs) stuffp->readcmd = READ1X;
- else stuffp->readcmd =
- stuffp->present | SINGLE ? READ1X : READ2X;
- xwarn("XXX %x XXX\n", stuffp->readcmd);
+ /* Set the read speed */
+ xwarn("AAA %x AAA\n", stuffp->readcmd);
+ if (stuffp->readerrs)
+ stuffp->readcmd = READ1X;
+ else
+ stuffp->readcmd =
+ stuffp->present | SINGLE ? READ1X : READ2X;
+ xwarn("XXX %x XXX\n", stuffp->readcmd);
#else
- stuffp->readcmd = stuffp->present | SINGLE ? READ1X : READ2X;
+ stuffp->readcmd =
+ stuffp->present | SINGLE ? READ1X : READ2X;
#endif
- /* try to get the first sector, iff any ... */
- if (stuffp->lastsector >= 0) {
- char buf[512];
- int ans;
- int tries;
-
- stuffp->xa = 0;
- stuffp->audio = 0;
-
- for (tries = 6; tries; tries--) {
-
- stuffp->introk = 1;
-
- xtrace(OPENCLOSE, "open() try as %s\n",
- stuffp->xa ? "XA" : "normal");
- /* set data mode */
- if (-1 == (ans = mcdx_setdatamode(stuffp,
- stuffp->xa ? MODE2 : MODE1, 1))) {
- /* MOD_DEC_USE_COUNT, return -EIO; */
- stuffp->xa = 0;
- break;
- }
-
- if ((stuffp->audio = e_audio(ans))) break;
-
- while (0 == (ans = mcdx_transfer(stuffp, buf, 0, 1)))
- ;
-
- if (ans == 1) break;
- stuffp->xa = !stuffp->xa;
- }
- }
- /* xa disks will be read in raw mode, others not */
- if (-1 == mcdx_setdrivemode(stuffp,
- stuffp->xa ? RAW : COOKED, 1)) {
- MOD_DEC_USE_COUNT;
- return -EIO;
- }
- if (stuffp->audio) {
- xinfo("open() audio disk found\n");
- } else if (stuffp->lastsector >= 0) {
- xinfo("open() %s%s disk found\n",
- stuffp->xa ? "XA / " : "",
- stuffp->multi.multi ? "Multi Session" : "Single Session");
- }
- }
+ /* try to get the first sector, iff any ... */
+ if (stuffp->lastsector >= 0) {
+ char buf[512];
+ int ans;
+ int tries;
+
+ stuffp->xa = 0;
+ stuffp->audio = 0;
+
+ for (tries = 6; tries; tries--) {
+
+ stuffp->introk = 1;
+
+ xtrace(OPENCLOSE, "open() try as %s\n",
+ stuffp->xa ? "XA" : "normal");
+ /* set data mode */
+ if (-1 == (ans = mcdx_setdatamode(stuffp,
+ stuffp->
+ xa ?
+ MODE2 :
+ MODE1,
+ 1))) {
+ /* MOD_DEC_USE_COUNT, return -EIO; */
+ stuffp->xa = 0;
+ break;
+ }
+
+ if ((stuffp->audio = e_audio(ans)))
+ break;
+
+ while (0 ==
+ (ans =
+ mcdx_transfer(stuffp, buf, 0, 1)));
+
+ if (ans == 1)
+ break;
+ stuffp->xa = !stuffp->xa;
+ }
+ }
+ /* xa disks will be read in raw mode, others not */
+ if (-1 == mcdx_setdrivemode(stuffp,
+ stuffp->xa ? RAW : COOKED,
+ 1)) {
+ MOD_DEC_USE_COUNT;
+ return -EIO;
+ }
+ if (stuffp->audio) {
+ xinfo("open() audio disk found\n");
+ } else if (stuffp->lastsector >= 0) {
+ xinfo("open() %s%s disk found\n",
+ stuffp->xa ? "XA / " : "",
+ stuffp->multi.
+ multi ? "Multi Session" : "Single Session");
+ }
+ }
stuffp->xxx = 0;
- stuffp->users++;
- return 0;
+ stuffp->users++;
+ return 0;
}
-static void mcdx_close(struct cdrom_device_info * cdi)
+static void mcdx_close(struct cdrom_device_info *cdi)
{
- struct s_drive_stuff *stuffp;
+ struct s_drive_stuff *stuffp;
- xtrace(OPENCLOSE, "close()\n");
+ xtrace(OPENCLOSE, "close()\n");
- stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+ stuffp = mcdx_stuffp[MINOR(cdi->dev)];
- --stuffp->users;
+ --stuffp->users;
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
}
-static int mcdx_media_changed(struct cdrom_device_info * cdi, int disc_nr)
+static int mcdx_media_changed(struct cdrom_device_info *cdi, int disc_nr)
/* Return: 1 if media changed since last call to this function
0 otherwise */
{
- struct s_drive_stuff *stuffp;
+ struct s_drive_stuff *stuffp;
- xinfo("mcdx_media_changed called for device %s\n",
- kdevname(cdi->dev));
+ xinfo("mcdx_media_changed called for device %s\n",
+ kdevname(cdi->dev));
stuffp = mcdx_stuffp[MINOR(cdi->dev)];
mcdx_getstatus(stuffp, 1);
- if (stuffp->yyy == 0) return 0;
+ if (stuffp->yyy == 0)
+ return 0;
stuffp->yyy = 0;
return 1;
static int __init mcdx_setup(char *str)
{
int pi[4];
- (void)get_options(str, ARRAY_SIZE(pi), pi);
-
- if (pi[0] > 0) mcdx_drive_map[0][0] = pi[1];
- if (pi[0] > 1) mcdx_drive_map[0][1] = pi[2];
+ (void) get_options(str, ARRAY_SIZE(pi), pi);
+
+ if (pi[0] > 0)
+ mcdx_drive_map[0][0] = pi[1];
+ if (pi[0] > 1)
+ mcdx_drive_map[0][1] = pi[2];
return 1;
}
* May be we could use a simple count loop w/ jumps to itself, but
* I wanna make this independent of cpu speed. [1 jiffy is 1/HZ] sec */
{
- if (jifs < 0) return;
+ if (jifs < 0)
+ return;
xtrace(SLEEP, "*** delay: sleepq\n");
interruptible_sleep_on_timeout(&stuff->sleepq, jifs);
}
}
-static void
-mcdx_intr(int irq, void *dev_id, struct pt_regs* regs)
+static void mcdx_intr(int irq, void *dev_id, struct pt_regs *regs)
{
- struct s_drive_stuff *stuffp;
+ struct s_drive_stuff *stuffp;
unsigned char b;
- stuffp = mcdx_irq_map[irq];
+ stuffp = mcdx_irq_map[irq];
- if (stuffp == NULL ) {
+ if (stuffp == NULL) {
xwarn("mcdx: no device for intr %d\n", irq);
return;
- }
-
+ }
#ifdef AK2
- if ( !stuffp->busy && stuffp->pending )
+ if (!stuffp->busy && stuffp->pending)
stuffp->int_err = 1;
-#endif /* AK2 */
+#endif /* AK2 */
/* get the interrupt status */
b = inb((unsigned int) stuffp->rreg_status);
stuffp->introk = ~b & MCDX_RBIT_DTEN;
if (!stuffp->introk) {
xtrace(IRQ, "intr() irq %d hw status 0x%02x\n", irq, b);
if (~b & MCDX_RBIT_STEN) {
- xinfo( "intr() irq %d status 0x%02x\n",
- irq, inb((unsigned int) stuffp->rreg_data));
+ xinfo("intr() irq %d status 0x%02x\n",
+ irq, inb((unsigned int) stuffp->rreg_data));
} else {
- xinfo( "intr() irq %d ambiguous hw status\n", irq);
+ xinfo("intr() irq %d ambiguous hw status\n", irq);
}
} else {
xtrace(IRQ, "irq() irq %d ok, status %02x\n", irq, b);
- }
+ }
- stuffp->busy = 0;
- wake_up_interruptible(&stuffp->busyq);
+ stuffp->busy = 0;
+ wake_up_interruptible(&stuffp->busyq);
}
-static int
-mcdx_talk (
- struct s_drive_stuff *stuffp,
- const unsigned char *cmd, size_t cmdlen,
- void *buffer, size_t size,
- unsigned int timeout, int tries)
+static int mcdx_talk(struct s_drive_stuff *stuffp,
+ const unsigned char *cmd, size_t cmdlen,
+ void *buffer, size_t size, unsigned int timeout, int tries)
/* Send a command to the drive, wait for the result.
* returns -1 on timeout, drive status otherwise
* If buffer is not zero, the result (length size) is stored there.
*/
{
int st;
- char c;
- int discard;
+ char c;
+ int discard;
/* Somebody wants the data read? */
- if ((discard = (buffer == NULL))) buffer = &c;
+ if ((discard = (buffer == NULL)))
+ buffer = &c;
- while (stuffp->lock) {
+ while (stuffp->lock) {
xtrace(SLEEP, "*** talk: lockq\n");
interruptible_sleep_on(&stuffp->lockq);
xtrace(SLEEP, "talk: awoken\n");
}
- stuffp->lock = 1;
+ stuffp->lock = 1;
/* An operation other then reading data destroys the
- * data already requested and remembered in stuffp->request, ... */
- stuffp->valid = 0;
+ * data already requested and remembered in stuffp->request, ... */
+ stuffp->valid = 0;
#if MCDX_DEBUG & TALK
{
unsigned char i;
- xtrace(TALK, "talk() %d / %d tries, res.size %d, command 0x%02x",
- tries, timeout, size, (unsigned char) cmd[0]);
- for (i = 1; i < cmdlen; i++) xtrace(TALK, " 0x%02x", cmd[i]);
+ xtrace(TALK,
+ "talk() %d / %d tries, res.size %d, command 0x%02x",
+ tries, timeout, size, (unsigned char) cmd[0]);
+ for (i = 1; i < cmdlen; i++)
+ xtrace(TALK, " 0x%02x", cmd[i]);
xtrace(TALK, "\n");
}
#endif
- /* give up if all tries are done (bad) or if the status
- * st != -1 (good) */
+ /* give up if all tries are done (bad) or if the status
+ * st != -1 (good) */
for (st = -1; st == -1 && tries; tries--) {
- char *bp = (char*) buffer;
+ char *bp = (char *) buffer;
size_t sz = size;
outsb((unsigned int) stuffp->wreg_data, cmd, cmdlen);
- xtrace(TALK, "talk() command sent\n");
-
- /* get the status byte */
- if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
- xinfo("talk() %02x timed out (status), %d tr%s left\n",
- cmd[0], tries - 1, tries == 2 ? "y" : "ies");
- continue;
- }
- st = *bp;
- sz--;
- if (!discard) bp++;
-
- xtrace(TALK, "talk() got status 0x%02x\n", st);
-
- /* command error? */
- if (e_cmderr(st)) {
- xwarn("command error cmd = %02x %s \n",
- cmd[0], cmdlen > 1 ? "..." : "");
- st = -1;
- continue;
+ xtrace(TALK, "talk() command sent\n");
+
+ /* get the status byte */
+ if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
+ xinfo("talk() %02x timed out (status), %d tr%s left\n",
+ cmd[0], tries - 1, tries == 2 ? "y" : "ies");
+ continue;
+ }
+ st = *bp;
+ sz--;
+ if (!discard)
+ bp++;
+
+ xtrace(TALK, "talk() got status 0x%02x\n", st);
+
+ /* command error? */
+ if (e_cmderr(st)) {
+ xwarn("command error cmd = %02x %s \n",
+ cmd[0], cmdlen > 1 ? "..." : "");
+ st = -1;
+ continue;
}
- /* audio status? */
- if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
- stuffp->audiostatus =
- e_audiobusy(st) ? CDROM_AUDIO_PLAY : CDROM_AUDIO_NO_STATUS;
- else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
- && e_audiobusy(st) == 0)
- stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
-
- /* media change? */
- if (e_changed(st)) {
- xinfo("talk() media changed\n");
- stuffp->xxx = stuffp->yyy = 1;
- }
-
- /* now actually get the data */
- while (sz--) {
- if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
- xinfo("talk() %02x timed out (data), %d tr%s left\n",
- cmd[0], tries - 1, tries == 2 ? "y" : "ies");
- st = -1; break;
- }
- if (!discard) bp++;
- xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
- }
- }
+ /* audio status? */
+ if (stuffp->audiostatus == CDROM_AUDIO_INVALID)
+ stuffp->audiostatus =
+ e_audiobusy(st) ? CDROM_AUDIO_PLAY :
+ CDROM_AUDIO_NO_STATUS;
+ else if (stuffp->audiostatus == CDROM_AUDIO_PLAY
+ && e_audiobusy(st) == 0)
+ stuffp->audiostatus = CDROM_AUDIO_COMPLETED;
+
+ /* media change? */
+ if (e_changed(st)) {
+ xinfo("talk() media changed\n");
+ stuffp->xxx = stuffp->yyy = 1;
+ }
+
+ /* now actually get the data */
+ while (sz--) {
+ if (-1 == mcdx_getval(stuffp, timeout, 0, bp)) {
+ xinfo("talk() %02x timed out (data), %d tr%s left\n",
+ cmd[0], tries - 1,
+ tries == 2 ? "y" : "ies");
+ st = -1;
+ break;
+ }
+ if (!discard)
+ bp++;
+ xtrace(TALK, "talk() got 0x%02x\n", *(bp - 1));
+ }
+ }
#if !MCDX_QUIET
- if (!tries && st == -1) xinfo("talk() giving up\n");
+ if (!tries && st == -1)
+ xinfo("talk() giving up\n");
#endif
- stuffp->lock = 0;
- wake_up_interruptible(&stuffp->lockq);
+ stuffp->lock = 0;
+ wake_up_interruptible(&stuffp->lockq);
xtrace(TALK, "talk() done with 0x%02x\n", st);
- return st;
+ return st;
}
/* MODULE STUFF ***********************************************************/
int drives = 0;
mcdx_init();
- for (i = 0; i < MCDX_NDRIVES; i++) {
+ for (i = 0; i < MCDX_NDRIVES; i++) {
if (mcdx_stuffp[i]) {
- xtrace(INIT, "init_module() drive %d stuff @ %p\n",
- i, mcdx_stuffp[i]);
+ xtrace(INIT, "init_module() drive %d stuff @ %p\n",
+ i, mcdx_stuffp[i]);
drives++;
}
}
- if (!drives)
+ if (!drives)
return -EIO;
- return 0;
+ return 0;
}
void __exit mcdx_exit(void)
{
- int i;
+ int i;
xinfo("cleanup_module called\n");
- for (i = 0; i < MCDX_NDRIVES; i++) {
+ for (i = 0; i < MCDX_NDRIVES; i++) {
struct s_drive_stuff *stuffp;
- if (unregister_cdrom(&mcdx_info)) {
+ if (unregister_cdrom(&mcdx_info)) {
printk(KERN_WARNING "Can't unregister cdrom mcdx\n");
return;
}
stuffp = mcdx_stuffp[i];
- if (!stuffp) continue;
- release_region((unsigned long) stuffp->wreg_data, MCDX_IO_SIZE);
+ if (!stuffp)
+ continue;
+ release_region((unsigned long) stuffp->wreg_data,
+ MCDX_IO_SIZE);
free_irq(stuffp->irq, NULL);
if (stuffp->toc) {
- xtrace(MALLOC, "cleanup_module() free toc @ %p\n", stuffp->toc);
+ xtrace(MALLOC, "cleanup_module() free toc @ %p\n",
+ stuffp->toc);
kfree(stuffp->toc);
}
- xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n", stuffp);
+ xtrace(MALLOC, "cleanup_module() free stuffp @ %p\n",
+ stuffp);
mcdx_stuffp[i] = NULL;
kfree(stuffp);
- }
+ }
- if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
- xwarn("cleanup() unregister_blkdev() failed\n");
- }
+ if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0) {
+ xwarn("cleanup() unregister_blkdev() failed\n");
+ }
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
#if !MCDX_QUIET
- else xinfo("cleanup() succeeded\n");
+ else
+ xinfo("cleanup() succeeded\n");
#endif
}
int __init mcdx_init_drive(int drive)
{
struct s_version version;
- struct s_drive_stuff* stuffp;
+ struct s_drive_stuff *stuffp;
int size = sizeof(*stuffp);
char msg[80];
/* setup our irq and i/o addresses */
stuffp->irq = irq(mcdx_drive_map[drive]);
- stuffp->wreg_data = stuffp->rreg_data = port(mcdx_drive_map[drive]);
+ stuffp->wreg_data = stuffp->rreg_data =
+ port(mcdx_drive_map[drive]);
stuffp->wreg_reset = stuffp->rreg_status = stuffp->wreg_data + 1;
stuffp->wreg_hcon = stuffp->wreg_reset + 1;
stuffp->wreg_chn = stuffp->wreg_hcon + 1;
-
+
init_waitqueue_head(&stuffp->busyq);
init_waitqueue_head(&stuffp->lockq);
init_waitqueue_head(&stuffp->sleepq);
xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
kfree(stuffp);
xtrace(INIT, "init() continue at next drive\n");
- return 0; /* next drive */
+ return 0; /* next drive */
}
xtrace(INIT, "init() i/o port is available at 0x%3p\n",
if (-1 == mcdx_requestversion(stuffp, &version, 4)) {
/* failed, next drive */
xwarn("%s=0x%3p,%d: Init failed. Can't get version.\n",
- MCDX,
- stuffp->wreg_data, stuffp->irq);
+ MCDX, stuffp->wreg_data, stuffp->irq);
xtrace(MALLOC, "init() free stuffp @ %p\n", stuffp);
kfree(stuffp);
xtrace(INIT, "init() continue at next drive\n");
switch (version.code) {
case 'D':
- stuffp->readcmd = READ2X;
- stuffp->present = DOUBLE | DOOR | MULTI;
- break;
+ stuffp->readcmd = READ2X;
+ stuffp->present = DOUBLE | DOOR | MULTI;
+ break;
case 'F':
- stuffp->readcmd = READ1X;
- stuffp->present = SINGLE | DOOR | MULTI;
- break;
+ stuffp->readcmd = READ1X;
+ stuffp->present = SINGLE | DOOR | MULTI;
+ break;
case 'M':
- stuffp->readcmd = READ1X;
- stuffp->present = SINGLE;
- break;
+ stuffp->readcmd = READ1X;
+ stuffp->present = SINGLE;
+ break;
default:
- stuffp->present = 0; break;
+ stuffp->present = 0;
+ break;
}
- stuffp->playcmd = READ1X;
+ stuffp->playcmd = READ1X;
if (!stuffp->present) {
xwarn("%s=0x%3p,%d: Init failed. No Mitsumi CD-ROM?.\n",
MCDX, stuffp->wreg_data, stuffp->irq);
kfree(stuffp);
- return 0; /* next drive */
+ return 0; /* next drive */
}
xtrace(INIT, "init() register blkdev\n");
if (devfs_register_blkdev(MAJOR_NR, "mcdx", &cdrom_fops) != 0) {
xwarn("%s=0x%3p,%d: Init failed. Can't get major %d.\n",
- MCDX,
- stuffp->wreg_data, stuffp->irq, MAJOR_NR);
+ MCDX, stuffp->wreg_data, stuffp->irq, MAJOR_NR);
kfree(stuffp);
return 1;
}
mcdx_irq_map[stuffp->irq] = stuffp;
if (request_irq(stuffp->irq, mcdx_intr, SA_INTERRUPT, "mcdx", NULL)) {
xwarn("%s=0x%3p,%d: Init failed. Can't get irq (%d).\n",
- MCDX,
- stuffp->wreg_data, stuffp->irq, stuffp->irq);
+ MCDX, stuffp->wreg_data, stuffp->irq, stuffp->irq);
stuffp->irq = 0;
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
kfree(stuffp);
return 0;
}
request_region((unsigned int) stuffp->wreg_data,
- MCDX_IO_SIZE,
- "mcdx");
+ MCDX_IO_SIZE, "mcdx");
xtrace(INIT, "init() get garbage\n");
{
int i;
- mcdx_delay(stuffp, HZ/2);
+ mcdx_delay(stuffp, HZ / 2);
for (i = 100; i; i--)
(void) inb((unsigned int) stuffp->rreg_status);
}
stuffp->minor = drive;
sprintf(msg, " mcdx: Mitsumi CD-ROM installed at 0x%3p, irq %d."
- " (Firmware version %c %x)\n",
- stuffp->wreg_data, stuffp->irq, version.code,
- version.ver);
+ " (Firmware version %c %x)\n",
+ stuffp->wreg_data, stuffp->irq, version.code, version.ver);
mcdx_stuffp[drive] = stuffp;
xtrace(INIT, "init() mcdx_stuffp[%d] = %p\n", drive, stuffp);
- mcdx_info.dev = MKDEV(MAJOR_NR,0);
- if (register_cdrom(&mcdx_info) != 0) {
+ mcdx_info.dev = MKDEV(MAJOR_NR, 0);
+ if (register_cdrom(&mcdx_info) != 0) {
printk("Cannot register Mitsumi CD-ROM!\n");
release_region((unsigned long) stuffp->wreg_data,
MCDX_IO_SIZE);
free_irq(stuffp->irq, NULL);
kfree(stuffp);
if (devfs_unregister_blkdev(MAJOR_NR, "mcdx") != 0)
- xwarn("cleanup() unregister_blkdev() failed\n");
+ xwarn("cleanup() unregister_blkdev() failed\n");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
return 2;
- }
- printk(msg);
+ }
+ printk(msg);
return 0;
}
/* do the initialisation */
for (drive = 0; drive < MCDX_NDRIVES; drive++) {
- switch(mcdx_init_drive(drive)) {
+ switch (mcdx_init_drive(drive)) {
case 2:
return -EIO;
case 1:
return 0;
}
-static int
-mcdx_transfer(struct s_drive_stuff *stuffp,
- char *p, int sector, int nr_sectors)
+static int mcdx_transfer(struct s_drive_stuff *stuffp,
+ char *p, int sector, int nr_sectors)
/* This seems to do the actually transfer. But it does more. It
keeps track of errors occurred and will (if possible) fall back
to single speed on error.
ans = mcdx_xfer(stuffp, p, sector, nr_sectors);
return ans;
#if FALLBACK
- if (-1 == ans) stuffp->readerrs++;
- else return ans;
+ if (-1 == ans)
+ stuffp->readerrs++;
+ else
+ return ans;
if (stuffp->readerrs && stuffp->readcmd == READ1X) {
xwarn("XXX Already reading 1x -- no chance\n");
static int mcdx_xfer(struct s_drive_stuff *stuffp,
- char *p, int sector, int nr_sectors)
+ char *p, int sector, int nr_sectors)
/* This does actually the transfer from the drive.
Return: -1 on timeout or other error
else status byte (as in stuff->st) */
{
- int border;
- int done = 0;
+ int border;
+ int done = 0;
long timeout;
if (stuffp->audio) {
- xwarn("Attempt to read from audio CD.\n");
- return -1;
+ xwarn("Attempt to read from audio CD.\n");
+ return -1;
}
if (!stuffp->readcmd) {
- xinfo("Can't transfer from missing disk.\n");
- return -1;
+ xinfo("Can't transfer from missing disk.\n");
+ return -1;
}
- while (stuffp->lock) {
+ while (stuffp->lock) {
interruptible_sleep_on(&stuffp->lockq);
}
- if (stuffp->valid
- && (sector >= stuffp->pending)
- && (sector < stuffp->low_border)) {
+ if (stuffp->valid && (sector >= stuffp->pending)
+ && (sector < stuffp->low_border)) {
/* All (or at least a part of the sectors requested) seems
- * to be already requested, so we don't need to bother the
- * drive with new requests ...
- * Wait for the drive become idle, but first
- * check for possible occurred errors --- the drive
- * seems to report them asynchronously */
+ * to be already requested, so we don't need to bother the
+ * drive with new requests ...
+ * Wait for the drive become idle, but first
+ * check for possible occurred errors --- the drive
+ * seems to report them asynchronously */
- border = stuffp->high_border < (border = sector + nr_sectors)
- ? stuffp->high_border : border;
+ border = stuffp->high_border < (border =
+ sector + nr_sectors)
+ ? stuffp->high_border : border;
- stuffp->lock = current->pid;
+ stuffp->lock = current->pid;
- do {
+ do {
- while (stuffp->busy) {
+ while (stuffp->busy) {
- timeout = interruptible_sleep_on_timeout(&stuffp->busyq, 5*HZ);
+ timeout =
+ interruptible_sleep_on_timeout
+ (&stuffp->busyq, 5 * HZ);
- if (!stuffp->introk) { xtrace(XFER, "error via interrupt\n"); }
- else if (!timeout) { xtrace(XFER, "timeout\n"); }
- else if (signal_pending(current)) {
- xtrace(XFER, "signal\n");
- } else continue;
+ if (!stuffp->introk) {
+ xtrace(XFER,
+ "error via interrupt\n");
+ } else if (!timeout) {
+ xtrace(XFER, "timeout\n");
+ } else if (signal_pending(current)) {
+ xtrace(XFER, "signal\n");
+ } else
+ continue;
- stuffp->lock = 0;
- stuffp->busy = 0;
- stuffp->valid = 0;
-
- wake_up_interruptible(&stuffp->lockq);
- xtrace(XFER, "transfer() done (-1)\n");
- return -1;
- }
+ stuffp->lock = 0;
+ stuffp->busy = 0;
+ stuffp->valid = 0;
- /* check if we need to set the busy flag (as we
- * expect an interrupt */
- stuffp->busy = (3 == (stuffp->pending & 3));
+ wake_up_interruptible(&stuffp->lockq);
+ xtrace(XFER, "transfer() done (-1)\n");
+ return -1;
+ }
- /* Test if it's the first sector of a block,
- * there we have to skip some bytes as we read raw data */
- if (stuffp->xa && (0 == (stuffp->pending & 3))) {
- const int HEAD = CD_FRAMESIZE_RAW - CD_XA_TAIL - CD_FRAMESIZE;
- insb((unsigned int) stuffp->rreg_data, p, HEAD);
- }
+ /* check if we need to set the busy flag (as we
+ * expect an interrupt */
+ stuffp->busy = (3 == (stuffp->pending & 3));
+
+ /* Test if it's the first sector of a block,
+ * there we have to skip some bytes as we read raw data */
+ if (stuffp->xa && (0 == (stuffp->pending & 3))) {
+ const int HEAD =
+ CD_FRAMESIZE_RAW - CD_XA_TAIL -
+ CD_FRAMESIZE;
+ insb((unsigned int) stuffp->rreg_data, p,
+ HEAD);
+ }
- /* now actually read the data */
- insb((unsigned int) stuffp->rreg_data, p, 512);
+ /* now actually read the data */
+ insb((unsigned int) stuffp->rreg_data, p, 512);
- /* test if it's the last sector of a block,
- * if so, we have to handle XA special */
- if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
- char dummy[CD_XA_TAIL];
- insb((unsigned int) stuffp->rreg_data, &dummy[0], CD_XA_TAIL);
- }
+ /* test if it's the last sector of a block,
+ * if so, we have to handle XA special */
+ if ((3 == (stuffp->pending & 3)) && stuffp->xa) {
+ char dummy[CD_XA_TAIL];
+ insb((unsigned int) stuffp->rreg_data,
+ &dummy[0], CD_XA_TAIL);
+ }
- if (stuffp->pending == sector) {
- p += 512;
- done++;
- sector++;
- }
- } while (++(stuffp->pending) < border);
+ if (stuffp->pending == sector) {
+ p += 512;
+ done++;
+ sector++;
+ }
+ } while (++(stuffp->pending) < border);
- stuffp->lock = 0;
- wake_up_interruptible(&stuffp->lockq);
+ stuffp->lock = 0;
+ wake_up_interruptible(&stuffp->lockq);
- } else {
+ } else {
/* The requested sector(s) is/are out of the
* already requested range, so we have to bother the drive
/* do some sanity checks */
if (stuffp->pending > stuffp->lastsector) {
- xwarn("transfer() sector %d from nirvana requested.\n",
- stuffp->pending);
+ xwarn
+ ("transfer() sector %d from nirvana requested.\n",
+ stuffp->pending);
stuffp->status = MCDX_ST_EOM;
stuffp->valid = 0;
xtrace(XFER, "transfer() done (-1)\n");
}
if ((stuffp->low_border = stuffp->pending + DIRECT_SIZE)
- > stuffp->lastsector + 1) {
+ > stuffp->lastsector + 1) {
xtrace(XFER, "cut low_border\n");
stuffp->low_border = stuffp->lastsector + 1;
}
if ((stuffp->high_border = stuffp->pending + REQUEST_SIZE)
- > stuffp->lastsector + 1) {
- xtrace(XFER, "cut high_border\n");
+ > stuffp->lastsector + 1) {
+ xtrace(XFER, "cut high_border\n");
stuffp->high_border = stuffp->lastsector + 1;
}
- { /* Convert the sector to be requested to MSF format */
+ { /* Convert the sector to be requested to MSF format */
struct cdrom_msf0 pending;
log2msf(stuffp->pending / 4, &pending);
cmd[1] = pending.minute;
cmd[3] = pending.frame;
}
- cmd[6] = (unsigned char) ((stuffp->high_border - stuffp->pending) / 4);
+ cmd[6] =
+ (unsigned
+ char) ((stuffp->high_border - stuffp->pending) / 4);
xtrace(XFER, "[%2d]\n", cmd[6]);
stuffp->busy = 1;
/* Now really issue the request command */
outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
- }
+ }
#ifdef AK2
- if ( stuffp->int_err ) {
+ if (stuffp->int_err) {
stuffp->valid = 0;
stuffp->int_err = 0;
return -1;
}
-#endif /* AK2 */
+#endif /* AK2 */
- stuffp->low_border = (stuffp->low_border += done) < stuffp->high_border
- ? stuffp->low_border : stuffp->high_border;
+ stuffp->low_border = (stuffp->low_border +=
+ done) <
+ stuffp->high_border ? stuffp->low_border : stuffp->high_border;
- return done;
+ return done;
}
/* Access to elements of the mcdx_drive_map members */
-static char* port(int *ip) { return (char*) ip[0]; }
-static int irq(int *ip) { return ip[1]; }
+static char *port(int *ip)
+{
+ return (char *) ip[0];
+}
+static int irq(int *ip)
+{
+ return ip[1];
+}
/* Misc number converters */
static unsigned int bcd2uint(unsigned char c)
-{ return (c >> 4) * 10 + (c & 0x0f); }
+{
+ return (c >> 4) * 10 + (c & 0x0f);
+}
static unsigned int uint2bcd(unsigned int ival)
-{ return ((ival / 10) << 4) | (ival % 10); }
+{
+ return ((ival / 10) << 4) | (ival % 10);
+}
-static void log2msf(unsigned int l, struct cdrom_msf0* pmsf)
+static void log2msf(unsigned int l, struct cdrom_msf0 *pmsf)
{
- l += CD_MSF_OFFSET;
- pmsf->minute = uint2bcd(l / 4500), l %= 4500;
- pmsf->second = uint2bcd(l / 75);
- pmsf->frame = uint2bcd(l % 75);
+ l += CD_MSF_OFFSET;
+ pmsf->minute = uint2bcd(l / 4500), l %= 4500;
+ pmsf->second = uint2bcd(l / 75);
+ pmsf->frame = uint2bcd(l % 75);
}
-static unsigned int msf2log(const struct cdrom_msf0* pmsf)
+static unsigned int msf2log(const struct cdrom_msf0 *pmsf)
{
- return bcd2uint(pmsf->frame)
- + bcd2uint(pmsf->second) * 75
- + bcd2uint(pmsf->minute) * 4500
- - CD_MSF_OFFSET;
+ return bcd2uint(pmsf->frame)
+ + bcd2uint(pmsf->second) * 75
+ + bcd2uint(pmsf->minute) * 4500 - CD_MSF_OFFSET;
}
-int mcdx_readtoc(struct s_drive_stuff* stuffp)
+int mcdx_readtoc(struct s_drive_stuff *stuffp)
/* Read the toc entries from the CD,
* Return: -1 on failure, else 0 */
{
}
xtrace(READTOC, "ioctl() readtoc for %d tracks\n",
- stuffp->di.n_last - stuffp->di.n_first + 1);
+ stuffp->di.n_last - stuffp->di.n_first + 1);
- if (-1 == mcdx_hold(stuffp, 1)) return -1;
+ if (-1 == mcdx_hold(stuffp, 1))
+ return -1;
xtrace(READTOC, "ioctl() tocmode\n");
- if (-1 == mcdx_setdrivemode(stuffp, TOC, 1)) return -EIO;
+ if (-1 == mcdx_setdrivemode(stuffp, TOC, 1))
+ return -EIO;
/* all seems to be ok so far ... malloc */
{
int size;
- size = sizeof(struct s_subqcode) * (stuffp->di.n_last - stuffp->di.n_first + 2);
+ size =
+ sizeof(struct s_subqcode) * (stuffp->di.n_last -
+ stuffp->di.n_first + 2);
xtrace(MALLOC, "ioctl() malloc %d bytes\n", size);
stuffp->toc = kmalloc(size, GFP_KERNEL);
int retries;
for (trk = 0;
- trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
- trk++)
+ trk < (stuffp->di.n_last - stuffp->di.n_first + 1);
+ trk++)
stuffp->toc[trk].index = 0;
- for (retries = 300; retries; retries--) { /* why 300? */
+ for (retries = 300; retries; retries--) { /* why 300? */
struct s_subqcode q;
unsigned int idx;
idx = bcd2uint(q.index);
if ((idx > 0)
- && (idx <= stuffp->di.n_last)
- && (q.tno == 0)
- && (stuffp->toc[idx - stuffp->di.n_first].index == 0)) {
+ && (idx <= stuffp->di.n_last)
+ && (q.tno == 0)
+ && (stuffp->toc[idx - stuffp->di.n_first].
+ index == 0)) {
stuffp->toc[idx - stuffp->di.n_first] = q;
- xtrace(READTOC, "ioctl() toc idx %d (trk %d)\n", idx, trk);
+ xtrace(READTOC,
+ "ioctl() toc idx %d (trk %d)\n",
+ idx, trk);
trk--;
}
- if (trk == 0) break;
+ if (trk == 0)
+ break;
}
- memset(&stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1],
- 0, sizeof(stuffp->toc[0]));
- stuffp->toc[stuffp->di.n_last - stuffp->di.n_first + 1].dt
- = stuffp->di.msf_leadout;
+ memset(&stuffp->
+ toc[stuffp->di.n_last - stuffp->di.n_first + 1], 0,
+ sizeof(stuffp->toc[0]));
+ stuffp->toc[stuffp->di.n_last - stuffp->di.n_first +
+ 1].dt = stuffp->di.msf_leadout;
}
/* unset toc mode */
return -EIO;
#if MCDX_DEBUG && READTOC
- { int trk;
- for (trk = 0;
- trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
- trk++)
- xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
- " %02x:%02x.%02x %02x:%02x.%02x\n",
- trk + stuffp->di.n_first,
- stuffp->toc[trk].control, stuffp->toc[trk].tno, stuffp->toc[trk].index,
- stuffp->toc[trk].tt.minute, stuffp->toc[trk].tt.second, stuffp->toc[trk].tt.frame,
- stuffp->toc[trk].dt.minute, stuffp->toc[trk].dt.second, stuffp->toc[trk].dt.frame);
+ {
+ int trk;
+ for (trk = 0;
+ trk < (stuffp->di.n_last - stuffp->di.n_first + 2);
+ trk++)
+ xtrace(READTOC, "ioctl() %d readtoc %02x %02x %02x"
+ " %02x:%02x.%02x %02x:%02x.%02x\n",
+ trk + stuffp->di.n_first,
+ stuffp->toc[trk].control,
+ stuffp->toc[trk].tno,
+ stuffp->toc[trk].index,
+ stuffp->toc[trk].tt.minute,
+ stuffp->toc[trk].tt.second,
+ stuffp->toc[trk].tt.frame,
+ stuffp->toc[trk].dt.minute,
+ stuffp->toc[trk].dt.second,
+ stuffp->toc[trk].dt.frame);
}
#endif
}
static int
-mcdx_playmsf(struct s_drive_stuff* stuffp, const struct cdrom_msf* msf)
+mcdx_playmsf(struct s_drive_stuff *stuffp, const struct cdrom_msf *msf)
{
- unsigned char cmd[7] = {
- 0, 0, 0, 0, 0, 0, 0
- };
+ unsigned char cmd[7] = {
+ 0, 0, 0, 0, 0, 0, 0
+ };
if (!stuffp->readcmd) {
xinfo("Can't play from missing disk.\n");
return -1;
}
- cmd[0] = stuffp->playcmd;
+ cmd[0] = stuffp->playcmd;
- cmd[1] = msf->cdmsf_min0;
- cmd[2] = msf->cdmsf_sec0;
- cmd[3] = msf->cdmsf_frame0;
- cmd[4] = msf->cdmsf_min1;
- cmd[5] = msf->cdmsf_sec1;
- cmd[6] = msf->cdmsf_frame1;
+ cmd[1] = msf->cdmsf_min0;
+ cmd[2] = msf->cdmsf_sec0;
+ cmd[3] = msf->cdmsf_frame0;
+ cmd[4] = msf->cdmsf_min1;
+ cmd[5] = msf->cdmsf_sec1;
+ cmd[6] = msf->cdmsf_frame1;
- xtrace(PLAYMSF, "ioctl(): play %x "
- "%02x:%02x:%02x -- %02x:%02x:%02x\n",
- cmd[0], cmd[1], cmd[2], cmd[3],
- cmd[4], cmd[5], cmd[6]);
+ xtrace(PLAYMSF, "ioctl(): play %x "
+ "%02x:%02x:%02x -- %02x:%02x:%02x\n",
+ cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
- outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
+ outsb((unsigned int) stuffp->wreg_data, cmd, sizeof cmd);
- if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
- xwarn("playmsf() timeout\n");
- return -1;
- }
+ if (-1 == mcdx_getval(stuffp, 3 * HZ, 0, NULL)) {
+ xwarn("playmsf() timeout\n");
+ return -1;
+ }
- stuffp->audiostatus = CDROM_AUDIO_PLAY;
- return 0;
+ stuffp->audiostatus = CDROM_AUDIO_PLAY;
+ return 0;
}
static int
-mcdx_playtrk(struct s_drive_stuff* stuffp, const struct cdrom_ti* ti)
+mcdx_playtrk(struct s_drive_stuff *stuffp, const struct cdrom_ti *ti)
{
- struct s_subqcode* p;
- struct cdrom_msf msf;
+ struct s_subqcode *p;
+ struct cdrom_msf msf;
- if (-1 == mcdx_readtoc(stuffp)) return -1;
+ if (-1 == mcdx_readtoc(stuffp))
+ return -1;
- if (ti) p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
- else p = &stuffp->start;
+ if (ti)
+ p = &stuffp->toc[ti->cdti_trk0 - stuffp->di.n_first];
+ else
+ p = &stuffp->start;
- msf.cdmsf_min0 = p->dt.minute;
- msf.cdmsf_sec0 = p->dt.second;
- msf.cdmsf_frame0 = p->dt.frame;
+ msf.cdmsf_min0 = p->dt.minute;
+ msf.cdmsf_sec0 = p->dt.second;
+ msf.cdmsf_frame0 = p->dt.frame;
- if (ti) {
- p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
- stuffp->stop = *p;
- } else p = &stuffp->stop;
+ if (ti) {
+ p = &stuffp->toc[ti->cdti_trk1 - stuffp->di.n_first + 1];
+ stuffp->stop = *p;
+ } else
+ p = &stuffp->stop;
- msf.cdmsf_min1 = p->dt.minute;
- msf.cdmsf_sec1 = p->dt.second;
- msf.cdmsf_frame1 = p->dt.frame;
+ msf.cdmsf_min1 = p->dt.minute;
+ msf.cdmsf_sec1 = p->dt.second;
+ msf.cdmsf_frame1 = p->dt.frame;
- return mcdx_playmsf(stuffp, &msf);
+ return mcdx_playmsf(stuffp, &msf);
}
/* Drive functions ************************************************/
-static int
-mcdx_tray_move(struct cdrom_device_info * cdi, int position)
+static int mcdx_tray_move(struct cdrom_device_info *cdi, int position)
{
- struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+ struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
- if (!stuffp->present)
+ if (!stuffp->present)
return -ENXIO;
if (!(stuffp->present & DOOR))
- return -ENOSYS;
+ return -ENOSYS;
- if (position) /* 1: eject */
- return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
- else /* 0: close */
- return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
- return 1;
+ if (position) /* 1: eject */
+ return mcdx_talk(stuffp, "\xf6", 1, NULL, 1, 5 * HZ, 3);
+ else /* 0: close */
+ return mcdx_talk(stuffp, "\xf8", 1, NULL, 1, 5 * HZ, 3);
+ return 1;
}
-static int
-mcdx_stop(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries); }
+static int mcdx_stop(struct s_drive_stuff *stuffp, int tries)
+{
+ return mcdx_talk(stuffp, "\xf0", 1, NULL, 1, 2 * HZ, tries);
+}
-static int
-mcdx_hold(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries); }
+static int mcdx_hold(struct s_drive_stuff *stuffp, int tries)
+{
+ return mcdx_talk(stuffp, "\x70", 1, NULL, 1, 2 * HZ, tries);
+}
-static int
-mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
- struct s_subqcode *sub,
- int tries)
+static int mcdx_requestsubqcode(struct s_drive_stuff *stuffp,
+ struct s_subqcode *sub, int tries)
{
char buf[11];
int ans;
- if (-1 == (ans = mcdx_talk(
- stuffp, "\x20", 1, buf, sizeof(buf),
- 2 * HZ, tries)))
- return -1;
+ if (-1 == (ans = mcdx_talk(stuffp, "\x20", 1, buf, sizeof(buf),
+ 2 * HZ, tries)))
+ return -1;
sub->control = buf[1];
sub->tno = buf[2];
sub->index = buf[3];
return ans;
}
-static int
-mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp, struct s_multi *multi, int tries)
+static int mcdx_requestmultidiskinfo(struct s_drive_stuff *stuffp,
+ struct s_multi *multi, int tries)
{
char buf[5];
int ans;
- if (stuffp->present & MULTI) {
- ans = mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ, tries);
+ if (stuffp->present & MULTI) {
+ ans =
+ mcdx_talk(stuffp, "\x11", 1, buf, sizeof(buf), 2 * HZ,
+ tries);
multi->multi = buf[1];
- multi->msf_last.minute = buf[2];
- multi->msf_last.second = buf[3];
- multi->msf_last.frame = buf[4];
- return ans;
- } else {
- multi->multi = 0;
- return 0;
- }
+ multi->msf_last.minute = buf[2];
+ multi->msf_last.second = buf[3];
+ multi->msf_last.frame = buf[4];
+ return ans;
+ } else {
+ multi->multi = 0;
+ return 0;
+ }
}
-static int
-mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info, int tries)
+static int mcdx_requesttocdata(struct s_drive_stuff *stuffp, struct s_diskinfo *info,
+ int tries)
{
char buf[9];
int ans;
- ans = mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
+ ans =
+ mcdx_talk(stuffp, "\x10", 1, buf, sizeof(buf), 2 * HZ, tries);
if (ans == -1) {
info->n_first = 0;
info->n_last = 0;
return ans;
}
-static int
-mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode, int tries)
+static int mcdx_setdrivemode(struct s_drive_stuff *stuffp, enum drivemodes mode,
+ int tries)
{
char cmd[2];
int ans;
return -1;
switch (mode) {
- case TOC: cmd[1] |= 0x04; break;
- case DATA: cmd[1] &= ~0x04; break;
- case RAW: cmd[1] |= 0x40; break;
- case COOKED: cmd[1] &= ~0x40; break;
- default: break;
+ case TOC:
+ cmd[1] |= 0x04;
+ break;
+ case DATA:
+ cmd[1] &= ~0x04;
+ break;
+ case RAW:
+ cmd[1] |= 0x40;
+ break;
+ case COOKED:
+ cmd[1] &= ~0x40;
+ break;
+ default:
+ break;
}
cmd[0] = 0x50;
return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
}
-static int
-mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode, int tries)
+static int mcdx_setdatamode(struct s_drive_stuff *stuffp, enum datamodes mode,
+ int tries)
{
unsigned char cmd[2] = { 0xa0 };
xtrace(HW, "setdatamode() %d\n", mode);
switch (mode) {
- case MODE0: cmd[1] = 0x00; break;
- case MODE1: cmd[1] = 0x01; break;
- case MODE2: cmd[1] = 0x02; break;
- default: return -EINVAL;
+ case MODE0:
+ cmd[1] = 0x00;
+ break;
+ case MODE1:
+ cmd[1] = 0x01;
+ break;
+ case MODE2:
+ cmd[1] = 0x02;
+ break;
+ default:
+ return -EINVAL;
}
return mcdx_talk(stuffp, cmd, 2, NULL, 1, 5 * HZ, tries);
}
-static int
-mcdx_config(struct s_drive_stuff *stuffp, int tries)
+static int mcdx_config(struct s_drive_stuff *stuffp, int tries)
{
char cmd[4];
return mcdx_talk(stuffp, cmd, 3, NULL, 1, 1 * HZ, tries);
}
-static int
-mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver, int tries)
+static int mcdx_requestversion(struct s_drive_stuff *stuffp, struct s_version *ver,
+ int tries)
{
char buf[3];
int ans;
if (-1 == (ans = mcdx_talk(stuffp, "\xdc",
- 1, buf, sizeof(buf), 2 * HZ, tries)))
+ 1, buf, sizeof(buf), 2 * HZ, tries)))
return ans;
ver->code = buf[1];
return ans;
}
-static int
-mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
+static int mcdx_reset(struct s_drive_stuff *stuffp, enum resetmodes mode, int tries)
{
if (mode == HARD) {
- outb(0, (unsigned int) stuffp->wreg_chn); /* no dma, no irq -> hardware */
- outb(0, (unsigned int) stuffp->wreg_reset); /* hw reset */
+ outb(0, (unsigned int) stuffp->wreg_chn); /* no dma, no irq -> hardware */
+ outb(0, (unsigned int) stuffp->wreg_reset); /* hw reset */
return 0;
- } else return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
+ } else
+ return mcdx_talk(stuffp, "\x60", 1, NULL, 1, 5 * HZ, tries);
}
-static int mcdx_lockdoor(struct cdrom_device_info * cdi, int lock)
+static int mcdx_lockdoor(struct cdrom_device_info *cdi, int lock)
{
- struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
+ struct s_drive_stuff *stuffp = mcdx_stuffp[MINOR(cdi->dev)];
char cmd[2] = { 0xfe };
- if (!(stuffp->present & DOOR))
+ if (!(stuffp->present & DOOR))
return -ENOSYS;
- if (stuffp->present & DOOR) {
- cmd[1] = lock ? 0x01 : 0x00;
- return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
- } else return 0;
+ if (stuffp->present & DOOR) {
+ cmd[1] = lock ? 0x01 : 0x00;
+ return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 1, 5 * HZ, 3);
+ } else
+ return 0;
}
-static int
-mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
-{ return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries); }
+static int mcdx_getstatus(struct s_drive_stuff *stuffp, int tries)
+{
+ return mcdx_talk(stuffp, "\x40", 1, NULL, 1, 5 * HZ, tries);
+}
static int
-mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char* buf)
+mcdx_getval(struct s_drive_stuff *stuffp, int to, int delay, char *buf)
{
- unsigned long timeout = to + jiffies;
- char c;
+ unsigned long timeout = to + jiffies;
+ char c;
- if (!buf) buf = &c;
+ if (!buf)
+ buf = &c;
- while (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_STEN) {
- if (time_after(jiffies, timeout)) return -1;
- mcdx_delay(stuffp, delay);
- }
+ while (inb((unsigned int) stuffp->rreg_status) & MCDX_RBIT_STEN) {
+ if (time_after(jiffies, timeout))
+ return -1;
+ mcdx_delay(stuffp, delay);
+ }
- *buf = (unsigned char) inb((unsigned int) stuffp->rreg_data) & 0xff;
+ *buf = (unsigned char) inb((unsigned int) stuffp->rreg_data) & 0xff;
- return 0;
+ return 0;
}
-static int
-mcdx_setattentuator(
- struct s_drive_stuff* stuffp,
- struct cdrom_volctrl* vol,
- int tries)
+static int mcdx_setattentuator(struct s_drive_stuff *stuffp,
+ struct cdrom_volctrl *vol, int tries)
{
- char cmd[5];
- cmd[0] = 0xae;
- cmd[1] = vol->channel0;
- cmd[2] = 0;
- cmd[3] = vol->channel1;
- cmd[4] = 0;
-
- return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
+ char cmd[5];
+ cmd[0] = 0xae;
+ cmd[1] = vol->channel0;
+ cmd[2] = 0;
+ cmd[3] = vol->channel1;
+ cmd[4] = 0;
+
+ return mcdx_talk(stuffp, cmd, sizeof(cmd), NULL, 5, 200, tries);
}
-/* ex:set ts=4 sw=4 ai si: */
+MODULE_LICENSE("GPL");
static int sjcd_present = 0;
-#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
+#define SJCD_BUF_SIZ 32 /* cdr-h94a has internal 64K buffer */
/*
* buffer for block size conversion
*/
-static char sjcd_buf[ 2048 * SJCD_BUF_SIZ ];
-static volatile int sjcd_buf_bn[ SJCD_BUF_SIZ ], sjcd_next_bn;
+static char sjcd_buf[2048 * SJCD_BUF_SIZ];
+static volatile int sjcd_buf_bn[SJCD_BUF_SIZ], sjcd_next_bn;
static volatile int sjcd_buf_in, sjcd_buf_out = -1;
/*
static int sjcd_base = SJCD_BASE_ADDR;
-#ifdef MODULE
MODULE_PARM(sjcd_base, "i");
-#endif
static DECLARE_WAIT_QUEUE_HEAD(sjcd_waitq);
static volatile unsigned short sjcd_transfer_is_active = 0;
enum sjcd_transfer_state {
- SJCD_S_IDLE = 0,
- SJCD_S_START = 1,
- SJCD_S_MODE = 2,
- SJCD_S_READ = 3,
- SJCD_S_DATA = 4,
- SJCD_S_STOP = 5,
- SJCD_S_STOPPING = 6
+ SJCD_S_IDLE = 0,
+ SJCD_S_START = 1,
+ SJCD_S_MODE = 2,
+ SJCD_S_READ = 3,
+ SJCD_S_DATA = 4,
+ SJCD_S_STOP = 5,
+ SJCD_S_STOPPING = 6
};
static enum sjcd_transfer_state sjcd_transfer_state = SJCD_S_IDLE;
static long sjcd_transfer_timeout = 0;
* base address.
*/
#ifndef MODULE
-static int __init sjcd_setup( char *str)
+static int __init sjcd_setup(char *str)
{
- int ints[2];
- (void)get_options(str, ARRAY_SIZE(ints), ints);
- if (ints[0] > 0)
- sjcd_base = ints[1];
+ int ints[2];
+ (void) get_options(str, ARRAY_SIZE(ints), ints);
+ if (ints[0] > 0)
+ sjcd_base = ints[1];
- return 1;
+ return 1;
}
__setup("sjcd=", sjcd_setup);
/*
* Special converters.
*/
-static unsigned char bin2bcd( int bin ){
- int u, v;
+static unsigned char bin2bcd(int bin)
+{
+ int u, v;
- u = bin % 10; v = bin / 10;
- return( u | ( v << 4 ) );
+ u = bin % 10;
+ v = bin / 10;
+ return (u | (v << 4));
}
-static int bcd2bin( unsigned char bcd ){
- return( ( bcd >> 4 ) * 10 + ( bcd & 0x0F ) );
+static int bcd2bin(unsigned char bcd)
+{
+ return ((bcd >> 4) * 10 + (bcd & 0x0F));
}
-static long msf2hsg( struct msf *mp ){
- return( bcd2bin( mp->frame ) + bcd2bin( mp->sec ) * 75
- + bcd2bin( mp->min ) * 4500 - 150 );
+static long msf2hsg(struct msf *mp)
+{
+ return (bcd2bin(mp->frame) + bcd2bin(mp->sec) * 75
+ + bcd2bin(mp->min) * 4500 - 150);
}
-static void hsg2msf( long hsg, struct msf *msf ){
- hsg += 150; msf->min = hsg / 4500;
- hsg %= 4500; msf->sec = hsg / 75; msf->frame = hsg % 75;
- msf->min = bin2bcd( msf->min ); /* convert to BCD */
- msf->sec = bin2bcd( msf->sec );
- msf->frame = bin2bcd( msf->frame );
+static void hsg2msf(long hsg, struct msf *msf)
+{
+ hsg += 150;
+ msf->min = hsg / 4500;
+ hsg %= 4500;
+ msf->sec = hsg / 75;
+ msf->frame = hsg % 75;
+ msf->min = bin2bcd(msf->min); /* convert to BCD */
+ msf->sec = bin2bcd(msf->sec);
+ msf->frame = bin2bcd(msf->frame);
}
/*
* Send a command to cdrom. Invalidate status.
*/
-static void sjcd_send_cmd( unsigned char cmd ){
+static void sjcd_send_cmd(unsigned char cmd)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: send_cmd( 0x%x )\n", cmd );
+ printk("SJCD: send_cmd( 0x%x )\n", cmd);
#endif
- outb( cmd, SJCDPORT( 0 ) );
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
+ outb(cmd, SJCDPORT(0));
+ sjcd_command_is_in_progress = 1;
+ sjcd_status_valid = 0;
+ sjcd_command_failed = 0;
}
/*
* Send a command with one arg to cdrom. Invalidate status.
*/
-static void sjcd_send_1_cmd( unsigned char cmd, unsigned char a ){
+static void sjcd_send_1_cmd(unsigned char cmd, unsigned char a)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a );
+ printk("SJCD: send_1_cmd( 0x%x, 0x%x )\n", cmd, a);
#endif
- outb( cmd, SJCDPORT( 0 ) );
- outb( a, SJCDPORT( 0 ) );
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
+ outb(cmd, SJCDPORT(0));
+ outb(a, SJCDPORT(0));
+ sjcd_command_is_in_progress = 1;
+ sjcd_status_valid = 0;
+ sjcd_command_failed = 0;
}
/*
* Send a command with four args to cdrom. Invalidate status.
*/
-static void sjcd_send_4_cmd( unsigned char cmd, unsigned char a,
- unsigned char b, unsigned char c, unsigned char d ){
+static void sjcd_send_4_cmd(unsigned char cmd, unsigned char a,
+ unsigned char b, unsigned char c,
+ unsigned char d)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: send_4_cmd( 0x%x )\n", cmd );
-#endif
- outb( cmd, SJCDPORT( 0 ) );
- outb( a, SJCDPORT( 0 ) );
- outb( b, SJCDPORT( 0 ) );
- outb( c, SJCDPORT( 0 ) );
- outb( d, SJCDPORT( 0 ) );
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
+ printk("SJCD: send_4_cmd( 0x%x )\n", cmd);
+#endif
+ outb(cmd, SJCDPORT(0));
+ outb(a, SJCDPORT(0));
+ outb(b, SJCDPORT(0));
+ outb(c, SJCDPORT(0));
+ outb(d, SJCDPORT(0));
+ sjcd_command_is_in_progress = 1;
+ sjcd_status_valid = 0;
+ sjcd_command_failed = 0;
}
/*
* Send a play or read command to cdrom. Invalidate Status.
*/
-static void sjcd_send_6_cmd( unsigned char cmd, struct sjcd_play_msf *pms ){
+static void sjcd_send_6_cmd(unsigned char cmd, struct sjcd_play_msf *pms)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: send_long_cmd( 0x%x )\n", cmd );
-#endif
- outb( cmd, SJCDPORT( 0 ) );
- outb( pms->start.min, SJCDPORT( 0 ) );
- outb( pms->start.sec, SJCDPORT( 0 ) );
- outb( pms->start.frame, SJCDPORT( 0 ) );
- outb( pms->end.min, SJCDPORT( 0 ) );
- outb( pms->end.sec, SJCDPORT( 0 ) );
- outb( pms->end.frame, SJCDPORT( 0 ) );
- sjcd_command_is_in_progress = 1;
- sjcd_status_valid = 0;
- sjcd_command_failed = 0;
+ printk("SJCD: send_long_cmd( 0x%x )\n", cmd);
+#endif
+ outb(cmd, SJCDPORT(0));
+ outb(pms->start.min, SJCDPORT(0));
+ outb(pms->start.sec, SJCDPORT(0));
+ outb(pms->start.frame, SJCDPORT(0));
+ outb(pms->end.min, SJCDPORT(0));
+ outb(pms->end.sec, SJCDPORT(0));
+ outb(pms->end.frame, SJCDPORT(0));
+ sjcd_command_is_in_progress = 1;
+ sjcd_status_valid = 0;
+ sjcd_command_failed = 0;
}
/*
* Get a value from the data port. Should not block, so we use a little
* wait for a while. Returns 0 if OK.
*/
-static int sjcd_load_response( void *buf, int len ){
- unsigned char *resp = ( unsigned char * )buf;
-
- for( ; len; --len ){
- int i;
- for( i = 200; i-- && !SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ); );
- if( i > 0 ) *resp++ = ( unsigned char )inb( SJCDPORT( 0 ) );
- else break;
- }
- return( len );
+static int sjcd_load_response(void *buf, int len)
+{
+ unsigned char *resp = (unsigned char *) buf;
+
+ for (; len; --len) {
+ int i;
+ for (i = 200;
+ i-- && !SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))););
+ if (i > 0)
+ *resp++ = (unsigned char) inb(SJCDPORT(0));
+ else
+ break;
+ }
+ return (len);
}
/*
* Load and parse command completion status (drive info byte and maybe error).
* Sorry, no error classification yet.
*/
-static void sjcd_load_status( void ){
- sjcd_media_is_changed = 0;
- sjcd_completion_error = 0;
- sjcd_completion_status = inb( SJCDPORT( 0 ) );
- if( sjcd_completion_status & SST_DOOR_OPENED ){
- sjcd_door_closed = sjcd_media_is_available = 0;
- } else {
- sjcd_door_closed = 1;
- if( sjcd_completion_status & SST_MEDIA_CHANGED )
- sjcd_media_is_available = sjcd_media_is_changed = 1;
- else if( sjcd_completion_status & 0x0F ){
- /*
- * OK, we seem to catch an error ...
- */
- while( !SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ) );
- sjcd_completion_error = inb( SJCDPORT( 0 ) );
- if( ( sjcd_completion_status & 0x08 ) &&
- ( sjcd_completion_error & 0x40 ) )
- sjcd_media_is_available = 0;
- else sjcd_command_failed = 1;
- } else sjcd_media_is_available = 1;
- }
- /*
- * Ok, status loaded successfully.
- */
- sjcd_status_valid = 1, sjcd_error_reported = 0;
- sjcd_command_is_in_progress = 0;
-
- /*
- * If the disk is changed, the TOC is not valid.
- */
- if( sjcd_media_is_changed ) sjcd_toc_uptodate = 0;
+static void sjcd_load_status(void)
+{
+ sjcd_media_is_changed = 0;
+ sjcd_completion_error = 0;
+ sjcd_completion_status = inb(SJCDPORT(0));
+ if (sjcd_completion_status & SST_DOOR_OPENED) {
+ sjcd_door_closed = sjcd_media_is_available = 0;
+ } else {
+ sjcd_door_closed = 1;
+ if (sjcd_completion_status & SST_MEDIA_CHANGED)
+ sjcd_media_is_available = sjcd_media_is_changed =
+ 1;
+ else if (sjcd_completion_status & 0x0F) {
+ /*
+ * OK, we seem to catch an error ...
+ */
+ while (!SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1))));
+ sjcd_completion_error = inb(SJCDPORT(0));
+ if ((sjcd_completion_status & 0x08) &&
+ (sjcd_completion_error & 0x40))
+ sjcd_media_is_available = 0;
+ else
+ sjcd_command_failed = 1;
+ } else
+ sjcd_media_is_available = 1;
+ }
+ /*
+ * Ok, status loaded successfully.
+ */
+ sjcd_status_valid = 1, sjcd_error_reported = 0;
+ sjcd_command_is_in_progress = 0;
+
+ /*
+ * If the disk is changed, the TOC is not valid.
+ */
+ if (sjcd_media_is_changed)
+ sjcd_toc_uptodate = 0;
#if defined( SJCD_TRACE )
- printk( "SJCD: status %02x.%02x loaded.\n",
- ( int )sjcd_completion_status, ( int )sjcd_completion_error );
+ printk("SJCD: status %02x.%02x loaded.\n",
+ (int) sjcd_completion_status, (int) sjcd_completion_error);
#endif
}
/*
* Read status from cdrom. Check to see if the status is available.
*/
-static int sjcd_check_status( void ){
- /*
- * Try to load the response from cdrom into buffer.
- */
- if( SJCD_STATUS_AVAILABLE( inb( SJCDPORT( 1 ) ) ) ){
- sjcd_load_status();
- return( 1 );
- } else {
- /*
- * No status is available.
- */
- return( 0 );
- }
+static int sjcd_check_status(void)
+{
+ /*
+ * Try to load the response from cdrom into buffer.
+ */
+ if (SJCD_STATUS_AVAILABLE(inb(SJCDPORT(1)))) {
+ sjcd_load_status();
+ return (1);
+ } else {
+ /*
+ * No status is available.
+ */
+ return (0);
+ }
}
/*
*/
#define SJCD_WAIT_FOR_STATUS_TIMEOUT 1000
-static void sjcd_status_timer( void ){
- if( sjcd_check_status() ){
- /*
- * The command completed and status is loaded, stop waiting.
- */
- wake_up( &sjcd_waitq );
- } else if( --sjcd_status_timeout <= 0 ){
- /*
- * We are timed out.
- */
- wake_up( &sjcd_waitq );
- } else {
- /*
- * We have still some time to wait. Try again.
- */
- SJCD_SET_TIMER( sjcd_status_timer, 1 );
- }
+static void sjcd_status_timer(void)
+{
+ if (sjcd_check_status()) {
+ /*
+ * The command completed and status is loaded, stop waiting.
+ */
+ wake_up(&sjcd_waitq);
+ } else if (--sjcd_status_timeout <= 0) {
+ /*
+ * We are timed out.
+ */
+ wake_up(&sjcd_waitq);
+ } else {
+ /*
+ * We have still some time to wait. Try again.
+ */
+ SJCD_SET_TIMER(sjcd_status_timer, 1);
+ }
}
/*
* Wait for status for 10 sec approx. Returns non-positive when timed out.
* Should not be used while reading data CDs.
*/
-static int sjcd_wait_for_status( void ){
- sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
- SJCD_SET_TIMER( sjcd_status_timer, 1 );
- sleep_on( &sjcd_waitq );
+static int sjcd_wait_for_status(void)
+{
+ sjcd_status_timeout = SJCD_WAIT_FOR_STATUS_TIMEOUT;
+ SJCD_SET_TIMER(sjcd_status_timer, 1);
+ sleep_on(&sjcd_waitq);
#if defined( SJCD_DIAGNOSTIC ) || defined ( SJCD_TRACE )
- if( sjcd_status_timeout <= 0 )
- printk( "SJCD: Error Wait For Status.\n" );
+ if (sjcd_status_timeout <= 0)
+ printk("SJCD: Error Wait For Status.\n");
#endif
- return( sjcd_status_timeout );
+ return (sjcd_status_timeout);
}
-static int sjcd_receive_status( void ){
- int i;
+static int sjcd_receive_status(void)
+{
+ int i;
#if defined( SJCD_TRACE )
- printk( "SJCD: receive_status\n" );
+ printk("SJCD: receive_status\n");
#endif
- /*
- * Wait a bit for status available.
- */
- for( i = 200; i-- && ( sjcd_check_status() == 0 ); );
- if( i < 0 ){
+ /*
+ * Wait a bit for status available.
+ */
+ for (i = 200; i-- && (sjcd_check_status() == 0););
+ if (i < 0) {
#if defined( SJCD_TRACE )
- printk( "SJCD: long wait for status\n" );
+ printk("SJCD: long wait for status\n");
#endif
- if( sjcd_wait_for_status() <= 0 )
- printk( "SJCD: Timeout when read status.\n" );
- else i = 0;
- }
- return( i );
+ if (sjcd_wait_for_status() <= 0)
+ printk("SJCD: Timeout when read status.\n");
+ else
+ i = 0;
+ }
+ return (i);
}
/*
* Load the status. Issue get status command and wait for status available.
*/
-static void sjcd_get_status( void ){
+static void sjcd_get_status(void)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: get_status\n" );
+ printk("SJCD: get_status\n");
#endif
- sjcd_send_cmd( SCMD_GET_STATUS );
- sjcd_receive_status();
+ sjcd_send_cmd(SCMD_GET_STATUS);
+ sjcd_receive_status();
}
/*
* Check the drive if the disk is changed. Should be revised.
*/
-static int sjcd_disk_change( kdev_t full_dev ){
+static int sjcd_disk_change(kdev_t full_dev)
+{
#if 0
- printk( "SJCD: sjcd_disk_change( 0x%x )\n", full_dev );
-#endif
- if( MINOR( full_dev ) > 0 ){
- printk( "SJCD: request error: invalid device minor.\n" );
- return 0;
- }
- if( !sjcd_command_is_in_progress )
- sjcd_get_status();
- return( sjcd_status_valid ? sjcd_media_is_changed : 0 );
+ printk("SJCD: sjcd_disk_change( 0x%x )\n", full_dev);
+#endif
+ if (MINOR(full_dev) > 0) {
+ printk("SJCD: request error: invalid device minor.\n");
+ return 0;
+ }
+ if (!sjcd_command_is_in_progress)
+ sjcd_get_status();
+ return (sjcd_status_valid ? sjcd_media_is_changed : 0);
}
/*
* Read the table of contents (TOC) and TOC header if necessary.
* We assume that the drive contains no more than 99 toc entries.
*/
-static struct sjcd_hw_disk_info sjcd_table_of_contents[ SJCD_MAX_TRACKS ];
+static struct sjcd_hw_disk_info sjcd_table_of_contents[SJCD_MAX_TRACKS];
static unsigned char sjcd_first_track_no, sjcd_last_track_no;
#define sjcd_disk_length sjcd_table_of_contents[0].un.track_msf
-static int sjcd_update_toc( void ){
- struct sjcd_hw_disk_info info;
- int i;
+static int sjcd_update_toc(void)
+{
+ struct sjcd_hw_disk_info info;
+ int i;
#if defined( SJCD_TRACE )
- printk( "SJCD: update toc:\n" );
-#endif
- /*
- * check to see if we need to do anything
- */
- if( sjcd_toc_uptodate ) return( 0 );
-
- /*
- * Get the TOC start information.
- */
- sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK );
- sjcd_receive_status();
-
- if( !sjcd_status_valid ){
- printk( "SJCD: cannot load status.\n" );
- return( -1 );
- }
-
- if( !sjcd_media_is_available ){
- printk( "SJCD: no disk in drive\n" );
- return( -1 );
- }
-
- if( !sjcd_command_failed ){
- if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
- printk( "SJCD: cannot load response about TOC start.\n" );
- return( -1 );
- }
- sjcd_first_track_no = bcd2bin( info.un.track_no );
- } else {
- printk( "SJCD: get first failed\n" );
- return( -1 );
- }
+ printk("SJCD: update toc:\n");
+#endif
+ /*
+ * check to see if we need to do anything
+ */
+ if (sjcd_toc_uptodate)
+ return (0);
+
+ /*
+ * Get the TOC start information.
+ */
+ sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_1_TRACK);
+ sjcd_receive_status();
+
+ if (!sjcd_status_valid) {
+ printk("SJCD: cannot load status.\n");
+ return (-1);
+ }
+
+ if (!sjcd_media_is_available) {
+ printk("SJCD: no disk in drive\n");
+ return (-1);
+ }
+
+ if (!sjcd_command_failed) {
+ if (sjcd_load_response(&info, sizeof(info)) != 0) {
+ printk
+ ("SJCD: cannot load response about TOC start.\n");
+ return (-1);
+ }
+ sjcd_first_track_no = bcd2bin(info.un.track_no);
+ } else {
+ printk("SJCD: get first failed\n");
+ return (-1);
+ }
#if defined( SJCD_TRACE )
- printk( "SJCD: TOC start 0x%02x ", sjcd_first_track_no );
-#endif
- /*
- * Get the TOC finish information.
- */
- sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK );
- sjcd_receive_status();
-
- if( !sjcd_status_valid ){
- printk( "SJCD: cannot load status.\n" );
- return( -1 );
- }
-
- if( !sjcd_media_is_available ){
- printk( "SJCD: no disk in drive\n" );
- return( -1 );
- }
-
- if( !sjcd_command_failed ){
- if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
- printk( "SJCD: cannot load response about TOC finish.\n" );
- return( -1 );
- }
- sjcd_last_track_no = bcd2bin( info.un.track_no );
- } else {
- printk( "SJCD: get last failed\n" );
- return( -1 );
- }
+ printk("SJCD: TOC start 0x%02x ", sjcd_first_track_no);
+#endif
+ /*
+ * Get the TOC finish information.
+ */
+ sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_L_TRACK);
+ sjcd_receive_status();
+
+ if (!sjcd_status_valid) {
+ printk("SJCD: cannot load status.\n");
+ return (-1);
+ }
+
+ if (!sjcd_media_is_available) {
+ printk("SJCD: no disk in drive\n");
+ return (-1);
+ }
+
+ if (!sjcd_command_failed) {
+ if (sjcd_load_response(&info, sizeof(info)) != 0) {
+ printk
+ ("SJCD: cannot load response about TOC finish.\n");
+ return (-1);
+ }
+ sjcd_last_track_no = bcd2bin(info.un.track_no);
+ } else {
+ printk("SJCD: get last failed\n");
+ return (-1);
+ }
#if defined( SJCD_TRACE )
- printk( "SJCD: TOC finish 0x%02x ", sjcd_last_track_no );
-#endif
- for( i = sjcd_first_track_no; i <= sjcd_last_track_no; i++ ){
- /*
- * Get the first track information.
- */
- sjcd_send_1_cmd( SCMD_GET_DISK_INFO, bin2bcd( i ) );
- sjcd_receive_status();
-
- if( !sjcd_status_valid ){
- printk( "SJCD: cannot load status.\n" );
- return( -1 );
- }
-
- if( !sjcd_media_is_available ){
- printk( "SJCD: no disk in drive\n" );
- return( -1 );
- }
-
- if( !sjcd_command_failed ){
- if( sjcd_load_response( &sjcd_table_of_contents[ i ],
- sizeof( struct sjcd_hw_disk_info ) ) != 0 ){
- printk( "SJCD: cannot load info for %d track\n", i );
- return( -1 );
- }
- } else {
- printk( "SJCD: get info %d failed\n", i );
- return( -1 );
- }
- }
-
- /*
- * Get the disk length info.
- */
- sjcd_send_1_cmd( SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE );
- sjcd_receive_status();
-
- if( !sjcd_status_valid ){
- printk( "SJCD: cannot load status.\n" );
- return( -1 );
- }
-
- if( !sjcd_media_is_available ){
- printk( "SJCD: no disk in drive\n" );
- return( -1 );
- }
-
- if( !sjcd_command_failed ){
- if( sjcd_load_response( &info, sizeof( info ) ) != 0 ){
- printk( "SJCD: cannot load response about disk size.\n" );
- return( -1 );
- }
- sjcd_disk_length.min = info.un.track_msf.min;
- sjcd_disk_length.sec = info.un.track_msf.sec;
- sjcd_disk_length.frame = info.un.track_msf.frame;
- } else {
- printk( "SJCD: get size failed\n" );
- return( 1 );
- }
+ printk("SJCD: TOC finish 0x%02x ", sjcd_last_track_no);
+#endif
+ for (i = sjcd_first_track_no; i <= sjcd_last_track_no; i++) {
+ /*
+ * Get the first track information.
+ */
+ sjcd_send_1_cmd(SCMD_GET_DISK_INFO, bin2bcd(i));
+ sjcd_receive_status();
+
+ if (!sjcd_status_valid) {
+ printk("SJCD: cannot load status.\n");
+ return (-1);
+ }
+
+ if (!sjcd_media_is_available) {
+ printk("SJCD: no disk in drive\n");
+ return (-1);
+ }
+
+ if (!sjcd_command_failed) {
+ if (sjcd_load_response(&sjcd_table_of_contents[i],
+ sizeof(struct
+ sjcd_hw_disk_info))
+ != 0) {
+ printk
+ ("SJCD: cannot load info for %d track\n",
+ i);
+ return (-1);
+ }
+ } else {
+ printk("SJCD: get info %d failed\n", i);
+ return (-1);
+ }
+ }
+
+ /*
+ * Get the disk length info.
+ */
+ sjcd_send_1_cmd(SCMD_GET_DISK_INFO, SCMD_GET_D_SIZE);
+ sjcd_receive_status();
+
+ if (!sjcd_status_valid) {
+ printk("SJCD: cannot load status.\n");
+ return (-1);
+ }
+
+ if (!sjcd_media_is_available) {
+ printk("SJCD: no disk in drive\n");
+ return (-1);
+ }
+
+ if (!sjcd_command_failed) {
+ if (sjcd_load_response(&info, sizeof(info)) != 0) {
+ printk
+ ("SJCD: cannot load response about disk size.\n");
+ return (-1);
+ }
+ sjcd_disk_length.min = info.un.track_msf.min;
+ sjcd_disk_length.sec = info.un.track_msf.sec;
+ sjcd_disk_length.frame = info.un.track_msf.frame;
+ } else {
+ printk("SJCD: get size failed\n");
+ return (1);
+ }
#if defined( SJCD_TRACE )
- printk( "SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
- sjcd_disk_length.sec, sjcd_disk_length.frame );
+ printk("SJCD: (%02x:%02x.%02x)\n", sjcd_disk_length.min,
+ sjcd_disk_length.sec, sjcd_disk_length.frame);
#endif
- return( 0 );
+ return (0);
}
/*
* Load subchannel information.
*/
-static int sjcd_get_q_info( struct sjcd_hw_qinfo *qp ){
- int s;
+static int sjcd_get_q_info(struct sjcd_hw_qinfo *qp)
+{
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: load sub q\n" );
-#endif
- sjcd_send_cmd( SCMD_GET_QINFO );
- s = sjcd_receive_status();
- if( s < 0 || sjcd_command_failed || !sjcd_status_valid ){
- sjcd_send_cmd( 0xF2 );
- s = sjcd_receive_status();
- if( s < 0 || sjcd_command_failed || !sjcd_status_valid ) return( -1 );
- sjcd_send_cmd( SCMD_GET_QINFO );
- s = sjcd_receive_status();
- if( s < 0 || sjcd_command_failed || !sjcd_status_valid ) return( -1 );
- }
- if( sjcd_media_is_available )
- if( sjcd_load_response( qp, sizeof( *qp ) ) == 0 ) return( 0 );
- return( -1 );
+ printk("SJCD: load sub q\n");
+#endif
+ sjcd_send_cmd(SCMD_GET_QINFO);
+ s = sjcd_receive_status();
+ if (s < 0 || sjcd_command_failed || !sjcd_status_valid) {
+ sjcd_send_cmd(0xF2);
+ s = sjcd_receive_status();
+ if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
+ return (-1);
+ sjcd_send_cmd(SCMD_GET_QINFO);
+ s = sjcd_receive_status();
+ if (s < 0 || sjcd_command_failed || !sjcd_status_valid)
+ return (-1);
+ }
+ if (sjcd_media_is_available)
+ if (sjcd_load_response(qp, sizeof(*qp)) == 0)
+ return (0);
+ return (-1);
}
/*
* Start playing from the specified position.
*/
-static int sjcd_play( struct sjcd_play_msf *mp ){
- struct sjcd_play_msf msf;
-
- /*
- * Turn the device to play mode.
- */
- sjcd_send_1_cmd( SCMD_SET_MODE, SCMD_MODE_PLAY );
- if( sjcd_receive_status() < 0 ) return( -1 );
-
- /*
- * Seek to the starting point.
- */
- msf.start = mp->start;
- msf.end.min = msf.end.sec = msf.end.frame = 0x00;
- sjcd_send_6_cmd( SCMD_SEEK, &msf );
- if( sjcd_receive_status() < 0 ) return( -1 );
-
- /*
- * Start playing.
- */
- sjcd_send_6_cmd( SCMD_PLAY, mp );
- return( sjcd_receive_status() );
+static int sjcd_play(struct sjcd_play_msf *mp)
+{
+ struct sjcd_play_msf msf;
+
+ /*
+ * Turn the device to play mode.
+ */
+ sjcd_send_1_cmd(SCMD_SET_MODE, SCMD_MODE_PLAY);
+ if (sjcd_receive_status() < 0)
+ return (-1);
+
+ /*
+ * Seek to the starting point.
+ */
+ msf.start = mp->start;
+ msf.end.min = msf.end.sec = msf.end.frame = 0x00;
+ sjcd_send_6_cmd(SCMD_SEEK, &msf);
+ if (sjcd_receive_status() < 0)
+ return (-1);
+
+ /*
+ * Start playing.
+ */
+ sjcd_send_6_cmd(SCMD_PLAY, mp);
+ return (sjcd_receive_status());
}
/*
* Tray control functions.
*/
-static int sjcd_tray_close( void ){
+static int sjcd_tray_close(void)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: tray_close\n" );
+ printk("SJCD: tray_close\n");
#endif
- sjcd_send_cmd( SCMD_CLOSE_TRAY );
- return( sjcd_receive_status() );
+ sjcd_send_cmd(SCMD_CLOSE_TRAY);
+ return (sjcd_receive_status());
}
-static int sjcd_tray_lock( void ){
+static int sjcd_tray_lock(void)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: tray_lock\n" );
+ printk("SJCD: tray_lock\n");
#endif
- sjcd_send_cmd( SCMD_LOCK_TRAY );
- return( sjcd_receive_status() );
+ sjcd_send_cmd(SCMD_LOCK_TRAY);
+ return (sjcd_receive_status());
}
-static int sjcd_tray_unlock( void ){
+static int sjcd_tray_unlock(void)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: tray_unlock\n" );
+ printk("SJCD: tray_unlock\n");
#endif
- sjcd_send_cmd( SCMD_UNLOCK_TRAY );
- return( sjcd_receive_status() );
+ sjcd_send_cmd(SCMD_UNLOCK_TRAY);
+ return (sjcd_receive_status());
}
-static int sjcd_tray_open( void ){
+static int sjcd_tray_open(void)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: tray_open\n" );
+ printk("SJCD: tray_open\n");
#endif
- sjcd_send_cmd( SCMD_EJECT_TRAY );
- return( sjcd_receive_status() );
+ sjcd_send_cmd(SCMD_EJECT_TRAY);
+ return (sjcd_receive_status());
}
/*
* Do some user commands.
*/
-static int sjcd_ioctl( struct inode *ip, struct file *fp,
- unsigned int cmd, unsigned long arg ){
+static int sjcd_ioctl(struct inode *ip, struct file *fp,
+ unsigned int cmd, unsigned long arg)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD:ioctl\n" );
+ printk("SJCD:ioctl\n");
#endif
- if( ip == NULL ) return( -EINVAL );
+ if (ip == NULL)
+ return (-EINVAL);
- sjcd_get_status();
- if( !sjcd_status_valid ) return( -EIO );
- if( sjcd_update_toc() < 0 ) return( -EIO );
+ sjcd_get_status();
+ if (!sjcd_status_valid)
+ return (-EIO);
+ if (sjcd_update_toc() < 0)
+ return (-EIO);
- switch( cmd ){
- case CDROMSTART:{
+ switch (cmd) {
+ case CDROMSTART:{
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: start\n" );
+ printk("SJCD: ioctl: start\n");
#endif
- return( 0 );
- }
+ return (0);
+ }
- case CDROMSTOP:{
+ case CDROMSTOP:{
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: stop\n" );
+ printk("SJCD: ioctl: stop\n");
#endif
- sjcd_send_cmd( SCMD_PAUSE );
- ( void )sjcd_receive_status();
- sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
- return( 0 );
- }
+ sjcd_send_cmd(SCMD_PAUSE);
+ (void) sjcd_receive_status();
+ sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
+ return (0);
+ }
- case CDROMPAUSE:{
- struct sjcd_hw_qinfo q_info;
+ case CDROMPAUSE:{
+ struct sjcd_hw_qinfo q_info;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: pause\n" );
-#endif
- if( sjcd_audio_status == CDROM_AUDIO_PLAY ){
- sjcd_send_cmd( SCMD_PAUSE );
- ( void )sjcd_receive_status();
- if( sjcd_get_q_info( &q_info ) < 0 ){
- sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
- } else {
- sjcd_audio_status = CDROM_AUDIO_PAUSED;
- sjcd_playing.start = q_info.abs;
- }
- return( 0 );
- } else return( -EINVAL );
- }
-
- case CDROMRESUME:{
+ printk("SJCD: ioctl: pause\n");
+#endif
+ if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
+ sjcd_send_cmd(SCMD_PAUSE);
+ (void) sjcd_receive_status();
+ if (sjcd_get_q_info(&q_info) < 0) {
+ sjcd_audio_status =
+ CDROM_AUDIO_NO_STATUS;
+ } else {
+ sjcd_audio_status =
+ CDROM_AUDIO_PAUSED;
+ sjcd_playing.start = q_info.abs;
+ }
+ return (0);
+ } else
+ return (-EINVAL);
+ }
+
+ case CDROMRESUME:{
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: resume\n" );
-#endif
- if( sjcd_audio_status == CDROM_AUDIO_PAUSED ){
- /*
- * continue play starting at saved location
- */
- if( sjcd_play( &sjcd_playing ) < 0 ){
- sjcd_audio_status = CDROM_AUDIO_ERROR;
- return( -EIO );
- } else {
- sjcd_audio_status = CDROM_AUDIO_PLAY;
- return( 0 );
- }
- } else return( -EINVAL );
- }
-
- case CDROMPLAYTRKIND:{
- struct cdrom_ti ti; int s;
+ printk("SJCD: ioctl: resume\n");
+#endif
+ if (sjcd_audio_status == CDROM_AUDIO_PAUSED) {
+ /*
+ * continue play starting at saved location
+ */
+ if (sjcd_play(&sjcd_playing) < 0) {
+ sjcd_audio_status =
+ CDROM_AUDIO_ERROR;
+ return (-EIO);
+ } else {
+ sjcd_audio_status =
+ CDROM_AUDIO_PLAY;
+ return (0);
+ }
+ } else
+ return (-EINVAL);
+ }
+
+ case CDROMPLAYTRKIND:{
+ struct cdrom_ti ti;
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: playtrkind\n" );
-#endif
- if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( ti ) ) ) == 0 ){
- copy_from_user( &ti, (void *)arg, sizeof( ti ) );
-
- if( ti.cdti_trk0 < sjcd_first_track_no ) return( -EINVAL );
- if( ti.cdti_trk1 > sjcd_last_track_no )
- ti.cdti_trk1 = sjcd_last_track_no;
- if( ti.cdti_trk0 > ti.cdti_trk1 ) return( -EINVAL );
-
- sjcd_playing.start = sjcd_table_of_contents[ ti.cdti_trk0 ].un.track_msf;
- sjcd_playing.end = ( ti.cdti_trk1 < sjcd_last_track_no ) ?
- sjcd_table_of_contents[ ti.cdti_trk1 + 1 ].un.track_msf :
- sjcd_table_of_contents[ 0 ].un.track_msf;
-
- if( sjcd_play( &sjcd_playing ) < 0 ){
- sjcd_audio_status = CDROM_AUDIO_ERROR;
- return( -EIO );
- } else sjcd_audio_status = CDROM_AUDIO_PLAY;
- }
- return( s );
- }
-
- case CDROMPLAYMSF:{
- struct cdrom_msf sjcd_msf; int s;
+ printk("SJCD: ioctl: playtrkind\n");
+#endif
+ if ((s =
+ verify_area(VERIFY_READ, (void *) arg,
+ sizeof(ti))) == 0) {
+ copy_from_user(&ti, (void *) arg,
+ sizeof(ti));
+
+ if (ti.cdti_trk0 < sjcd_first_track_no)
+ return (-EINVAL);
+ if (ti.cdti_trk1 > sjcd_last_track_no)
+ ti.cdti_trk1 = sjcd_last_track_no;
+ if (ti.cdti_trk0 > ti.cdti_trk1)
+ return (-EINVAL);
+
+ sjcd_playing.start =
+ sjcd_table_of_contents[ti.cdti_trk0].
+ un.track_msf;
+ sjcd_playing.end =
+ (ti.cdti_trk1 <
+ sjcd_last_track_no) ?
+ sjcd_table_of_contents[ti.cdti_trk1 +
+ 1].un.
+ track_msf : sjcd_table_of_contents[0].
+ un.track_msf;
+
+ if (sjcd_play(&sjcd_playing) < 0) {
+ sjcd_audio_status =
+ CDROM_AUDIO_ERROR;
+ return (-EIO);
+ } else
+ sjcd_audio_status =
+ CDROM_AUDIO_PLAY;
+ }
+ return (s);
+ }
+
+ case CDROMPLAYMSF:{
+ struct cdrom_msf sjcd_msf;
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: playmsf\n" );
-#endif
- if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( sjcd_msf ) ) ) == 0 ){
- if( sjcd_audio_status == CDROM_AUDIO_PLAY ){
- sjcd_send_cmd( SCMD_PAUSE );
- ( void )sjcd_receive_status();
- sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
- }
-
- copy_from_user( &sjcd_msf, (void *)arg, sizeof( sjcd_msf ) );
-
- sjcd_playing.start.min = bin2bcd( sjcd_msf.cdmsf_min0 );
- sjcd_playing.start.sec = bin2bcd( sjcd_msf.cdmsf_sec0 );
- sjcd_playing.start.frame = bin2bcd( sjcd_msf.cdmsf_frame0 );
- sjcd_playing.end.min = bin2bcd( sjcd_msf.cdmsf_min1 );
- sjcd_playing.end.sec = bin2bcd( sjcd_msf.cdmsf_sec1 );
- sjcd_playing.end.frame = bin2bcd( sjcd_msf.cdmsf_frame1 );
-
- if( sjcd_play( &sjcd_playing ) < 0 ){
- sjcd_audio_status = CDROM_AUDIO_ERROR;
- return( -EIO );
- } else sjcd_audio_status = CDROM_AUDIO_PLAY;
- }
- return( s );
- }
-
- case CDROMREADTOCHDR:{
- struct cdrom_tochdr toc_header; int s;
+ printk("SJCD: ioctl: playmsf\n");
+#endif
+ if ((s =
+ verify_area(VERIFY_READ, (void *) arg,
+ sizeof(sjcd_msf))) == 0) {
+ if (sjcd_audio_status == CDROM_AUDIO_PLAY) {
+ sjcd_send_cmd(SCMD_PAUSE);
+ (void) sjcd_receive_status();
+ sjcd_audio_status =
+ CDROM_AUDIO_NO_STATUS;
+ }
+
+ copy_from_user(&sjcd_msf, (void *) arg,
+ sizeof(sjcd_msf));
+
+ sjcd_playing.start.min =
+ bin2bcd(sjcd_msf.cdmsf_min0);
+ sjcd_playing.start.sec =
+ bin2bcd(sjcd_msf.cdmsf_sec0);
+ sjcd_playing.start.frame =
+ bin2bcd(sjcd_msf.cdmsf_frame0);
+ sjcd_playing.end.min =
+ bin2bcd(sjcd_msf.cdmsf_min1);
+ sjcd_playing.end.sec =
+ bin2bcd(sjcd_msf.cdmsf_sec1);
+ sjcd_playing.end.frame =
+ bin2bcd(sjcd_msf.cdmsf_frame1);
+
+ if (sjcd_play(&sjcd_playing) < 0) {
+ sjcd_audio_status =
+ CDROM_AUDIO_ERROR;
+ return (-EIO);
+ } else
+ sjcd_audio_status =
+ CDROM_AUDIO_PLAY;
+ }
+ return (s);
+ }
+
+ case CDROMREADTOCHDR:{
+ struct cdrom_tochdr toc_header;
+ int s;
#if defined (SJCD_TRACE )
- printk( "SJCD: ioctl: readtocheader\n" );
-#endif
- if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( toc_header ) ) ) == 0 ){
- toc_header.cdth_trk0 = sjcd_first_track_no;
- toc_header.cdth_trk1 = sjcd_last_track_no;
- copy_to_user( (void *)arg, &toc_header, sizeof( toc_header ) );
- }
- return( s );
- }
-
- case CDROMREADTOCENTRY:{
- struct cdrom_tocentry toc_entry; int s;
+ printk("SJCD: ioctl: readtocheader\n");
+#endif
+ if ((s =
+ verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(toc_header))) == 0) {
+ toc_header.cdth_trk0 = sjcd_first_track_no;
+ toc_header.cdth_trk1 = sjcd_last_track_no;
+ copy_to_user((void *) arg, &toc_header,
+ sizeof(toc_header));
+ }
+ return (s);
+ }
+
+ case CDROMREADTOCENTRY:{
+ struct cdrom_tocentry toc_entry;
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: readtocentry\n" );
-#endif
- if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( toc_entry ) ) ) == 0 ){
- struct sjcd_hw_disk_info *tp;
-
- copy_from_user( &toc_entry, (void *)arg, sizeof( toc_entry ) );
-
- if( toc_entry.cdte_track == CDROM_LEADOUT )
- tp = &sjcd_table_of_contents[ 0 ];
- else if( toc_entry.cdte_track < sjcd_first_track_no ) return( -EINVAL );
- else if( toc_entry.cdte_track > sjcd_last_track_no ) return( -EINVAL );
- else tp = &sjcd_table_of_contents[ toc_entry.cdte_track ];
-
- toc_entry.cdte_adr = tp->track_control & 0x0F;
- toc_entry.cdte_ctrl = tp->track_control >> 4;
-
- switch( toc_entry.cdte_format ){
- case CDROM_LBA:
- toc_entry.cdte_addr.lba = msf2hsg( &( tp->un.track_msf ) );
- break;
- case CDROM_MSF:
- toc_entry.cdte_addr.msf.minute = bcd2bin( tp->un.track_msf.min );
- toc_entry.cdte_addr.msf.second = bcd2bin( tp->un.track_msf.sec );
- toc_entry.cdte_addr.msf.frame = bcd2bin( tp->un.track_msf.frame );
- break;
- default: return( -EINVAL );
- }
- copy_to_user( (void *)arg, &toc_entry, sizeof( toc_entry ) );
- }
- return( s );
- }
-
- case CDROMSUBCHNL:{
- struct cdrom_subchnl subchnl; int s;
+ printk("SJCD: ioctl: readtocentry\n");
+#endif
+ if ((s =
+ verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(toc_entry))) == 0) {
+ struct sjcd_hw_disk_info *tp;
+
+ copy_from_user(&toc_entry, (void *) arg,
+ sizeof(toc_entry));
+
+ if (toc_entry.cdte_track == CDROM_LEADOUT)
+ tp = &sjcd_table_of_contents[0];
+ else if (toc_entry.cdte_track <
+ sjcd_first_track_no)
+ return (-EINVAL);
+ else if (toc_entry.cdte_track >
+ sjcd_last_track_no)
+ return (-EINVAL);
+ else
+ tp = &sjcd_table_of_contents
+ [toc_entry.cdte_track];
+
+ toc_entry.cdte_adr =
+ tp->track_control & 0x0F;
+ toc_entry.cdte_ctrl =
+ tp->track_control >> 4;
+
+ switch (toc_entry.cdte_format) {
+ case CDROM_LBA:
+ toc_entry.cdte_addr.lba =
+ msf2hsg(&(tp->un.track_msf));
+ break;
+ case CDROM_MSF:
+ toc_entry.cdte_addr.msf.minute =
+ bcd2bin(tp->un.track_msf.min);
+ toc_entry.cdte_addr.msf.second =
+ bcd2bin(tp->un.track_msf.sec);
+ toc_entry.cdte_addr.msf.frame =
+ bcd2bin(tp->un.track_msf.
+ frame);
+ break;
+ default:
+ return (-EINVAL);
+ }
+ copy_to_user((void *) arg, &toc_entry,
+ sizeof(toc_entry));
+ }
+ return (s);
+ }
+
+ case CDROMSUBCHNL:{
+ struct cdrom_subchnl subchnl;
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: subchnl\n" );
-#endif
- if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( subchnl ) ) ) == 0 ){
- struct sjcd_hw_qinfo q_info;
-
- copy_from_user( &subchnl, (void *)arg, sizeof( subchnl ) );
- if( sjcd_get_q_info( &q_info ) < 0 ) return( -EIO );
-
- subchnl.cdsc_audiostatus = sjcd_audio_status;
- subchnl.cdsc_adr = q_info.track_control & 0x0F;
- subchnl.cdsc_ctrl = q_info.track_control >> 4;
- subchnl.cdsc_trk = bcd2bin( q_info.track_no );
- subchnl.cdsc_ind = bcd2bin( q_info.x );
-
- switch( subchnl.cdsc_format ){
- case CDROM_LBA:
- subchnl.cdsc_absaddr.lba = msf2hsg( &( q_info.abs ) );
- subchnl.cdsc_reladdr.lba = msf2hsg( &( q_info.rel ) );
- break;
- case CDROM_MSF:
- subchnl.cdsc_absaddr.msf.minute = bcd2bin( q_info.abs.min );
- subchnl.cdsc_absaddr.msf.second = bcd2bin( q_info.abs.sec );
- subchnl.cdsc_absaddr.msf.frame = bcd2bin( q_info.abs.frame );
- subchnl.cdsc_reladdr.msf.minute = bcd2bin( q_info.rel.min );
- subchnl.cdsc_reladdr.msf.second = bcd2bin( q_info.rel.sec );
- subchnl.cdsc_reladdr.msf.frame = bcd2bin( q_info.rel.frame );
- break;
- default: return( -EINVAL );
- }
- copy_to_user( (void *)arg, &subchnl, sizeof( subchnl ) );
- }
- return( s );
- }
-
- case CDROMVOLCTRL:{
- struct cdrom_volctrl vol_ctrl; int s;
+ printk("SJCD: ioctl: subchnl\n");
+#endif
+ if ((s =
+ verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(subchnl))) == 0) {
+ struct sjcd_hw_qinfo q_info;
+
+ copy_from_user(&subchnl, (void *) arg,
+ sizeof(subchnl));
+ if (sjcd_get_q_info(&q_info) < 0)
+ return (-EIO);
+
+ subchnl.cdsc_audiostatus =
+ sjcd_audio_status;
+ subchnl.cdsc_adr =
+ q_info.track_control & 0x0F;
+ subchnl.cdsc_ctrl =
+ q_info.track_control >> 4;
+ subchnl.cdsc_trk =
+ bcd2bin(q_info.track_no);
+ subchnl.cdsc_ind = bcd2bin(q_info.x);
+
+ switch (subchnl.cdsc_format) {
+ case CDROM_LBA:
+ subchnl.cdsc_absaddr.lba =
+ msf2hsg(&(q_info.abs));
+ subchnl.cdsc_reladdr.lba =
+ msf2hsg(&(q_info.rel));
+ break;
+ case CDROM_MSF:
+ subchnl.cdsc_absaddr.msf.minute =
+ bcd2bin(q_info.abs.min);
+ subchnl.cdsc_absaddr.msf.second =
+ bcd2bin(q_info.abs.sec);
+ subchnl.cdsc_absaddr.msf.frame =
+ bcd2bin(q_info.abs.frame);
+ subchnl.cdsc_reladdr.msf.minute =
+ bcd2bin(q_info.rel.min);
+ subchnl.cdsc_reladdr.msf.second =
+ bcd2bin(q_info.rel.sec);
+ subchnl.cdsc_reladdr.msf.frame =
+ bcd2bin(q_info.rel.frame);
+ break;
+ default:
+ return (-EINVAL);
+ }
+ copy_to_user((void *) arg, &subchnl,
+ sizeof(subchnl));
+ }
+ return (s);
+ }
+
+ case CDROMVOLCTRL:{
+ struct cdrom_volctrl vol_ctrl;
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: volctrl\n" );
-#endif
- if( ( s = verify_area( VERIFY_READ, (void *)arg, sizeof( vol_ctrl ) ) ) == 0 ){
- unsigned char dummy[ 4 ];
-
- copy_from_user( &vol_ctrl, (void *)arg, sizeof( vol_ctrl ) );
- sjcd_send_4_cmd( SCMD_SET_VOLUME, vol_ctrl.channel0, 0xFF,
- vol_ctrl.channel1, 0xFF );
- if( sjcd_receive_status() < 0 ) return( -EIO );
- ( void )sjcd_load_response( dummy, 4 );
- }
- return( s );
- }
-
- case CDROMEJECT:{
+ printk("SJCD: ioctl: volctrl\n");
+#endif
+ if ((s =
+ verify_area(VERIFY_READ, (void *) arg,
+ sizeof(vol_ctrl))) == 0) {
+ unsigned char dummy[4];
+
+ copy_from_user(&vol_ctrl, (void *) arg,
+ sizeof(vol_ctrl));
+ sjcd_send_4_cmd(SCMD_SET_VOLUME,
+ vol_ctrl.channel0, 0xFF,
+ vol_ctrl.channel1, 0xFF);
+ if (sjcd_receive_status() < 0)
+ return (-EIO);
+ (void) sjcd_load_response(dummy, 4);
+ }
+ return (s);
+ }
+
+ case CDROMEJECT:{
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: eject\n" );
+ printk("SJCD: ioctl: eject\n");
#endif
- if( !sjcd_command_is_in_progress ){
- sjcd_tray_unlock();
- sjcd_send_cmd( SCMD_EJECT_TRAY );
- ( void )sjcd_receive_status();
- }
- return( 0 );
- }
+ if (!sjcd_command_is_in_progress) {
+ sjcd_tray_unlock();
+ sjcd_send_cmd(SCMD_EJECT_TRAY);
+ (void) sjcd_receive_status();
+ }
+ return (0);
+ }
#if defined( SJCD_GATHER_STAT )
- case 0xABCD:{
- int s;
+ case 0xABCD:{
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: ioctl: statistic\n" );
+ printk("SJCD: ioctl: statistic\n");
#endif
- if( ( s = verify_area( VERIFY_WRITE, (void *)arg, sizeof( statistic ) ) ) == 0 )
- copy_to_user( (void *)arg, &statistic, sizeof( statistic ) );
- return( s );
- }
+ if ((s =
+ verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(statistic))) == 0)
+ copy_to_user((void *) arg, &statistic,
+ sizeof(statistic));
+ return (s);
+ }
#endif
- default:
- return( -EINVAL );
- }
+ default:
+ return (-EINVAL);
+ }
}
/*
* Invalidate internal buffers of the driver.
*/
-static void sjcd_invalidate_buffers( void ){
- int i;
- for( i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[ i++ ] = -1 );
- sjcd_buf_out = -1;
+static void sjcd_invalidate_buffers(void)
+{
+ int i;
+ for (i = 0; i < SJCD_BUF_SIZ; sjcd_buf_bn[i++] = -1);
+ sjcd_buf_out = -1;
}
/*
( !QUEUE_EMPTY && MAJOR( CURRENT->rq_dev ) == MAJOR_NR && \
CURRENT->cmd == READ && CURRENT->sector != -1 )
-static void sjcd_transfer( void ){
+static void sjcd_transfer(void)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: transfer:\n" );
-#endif
- if( CURRENT_IS_VALID ){
- while( CURRENT->nr_sectors ){
- int i, bn = CURRENT->sector / 4;
- for( i = 0; i < SJCD_BUF_SIZ && sjcd_buf_bn[ i ] != bn; i++ );
- if( i < SJCD_BUF_SIZ ){
- int offs = ( i * 4 + ( CURRENT->sector & 3 ) ) * 512;
- int nr_sectors = 4 - ( CURRENT->sector & 3 );
- if( sjcd_buf_out != i ){
- sjcd_buf_out = i;
- if( sjcd_buf_bn[ i ] != bn ){
- sjcd_buf_out = -1;
- continue;
- }
- }
- if( nr_sectors > CURRENT->nr_sectors )
- nr_sectors = CURRENT->nr_sectors;
+ printk("SJCD: transfer:\n");
+#endif
+ if (CURRENT_IS_VALID) {
+ while (CURRENT->nr_sectors) {
+ int i, bn = CURRENT->sector / 4;
+ for (i = 0;
+ i < SJCD_BUF_SIZ && sjcd_buf_bn[i] != bn;
+ i++);
+ if (i < SJCD_BUF_SIZ) {
+ int offs =
+ (i * 4 + (CURRENT->sector & 3)) * 512;
+ int nr_sectors = 4 - (CURRENT->sector & 3);
+ if (sjcd_buf_out != i) {
+ sjcd_buf_out = i;
+ if (sjcd_buf_bn[i] != bn) {
+ sjcd_buf_out = -1;
+ continue;
+ }
+ }
+ if (nr_sectors > CURRENT->nr_sectors)
+ nr_sectors = CURRENT->nr_sectors;
#if defined( SJCD_TRACE )
- printk( "SJCD: copy out\n" );
-#endif
- memcpy( CURRENT->buffer, sjcd_buf + offs, nr_sectors * 512 );
- CURRENT->nr_sectors -= nr_sectors;
- CURRENT->sector += nr_sectors;
- CURRENT->buffer += nr_sectors * 512;
- } else {
- sjcd_buf_out = -1;
- break;
- }
- }
- }
+ printk("SJCD: copy out\n");
+#endif
+ memcpy(CURRENT->buffer, sjcd_buf + offs,
+ nr_sectors * 512);
+ CURRENT->nr_sectors -= nr_sectors;
+ CURRENT->sector += nr_sectors;
+ CURRENT->buffer += nr_sectors * 512;
+ } else {
+ sjcd_buf_out = -1;
+ break;
+ }
+ }
+ }
#if defined( SJCD_TRACE )
- printk( "SJCD: transfer: done\n" );
+ printk("SJCD: transfer: done\n");
#endif
}
-static void sjcd_poll( void ){
+static void sjcd_poll(void)
+{
#if defined( SJCD_GATHER_STAT )
- /*
- * Update total number of ticks.
- */
- statistic.ticks++;
- statistic.tticks[ sjcd_transfer_state ]++;
+ /*
+ * Update total number of ticks.
+ */
+ statistic.ticks++;
+ statistic.tticks[sjcd_transfer_state]++;
#endif
- ReSwitch: switch( sjcd_transfer_state ){
-
- case SJCD_S_IDLE:{
+ ReSwitch:switch (sjcd_transfer_state) {
+
+ case SJCD_S_IDLE:{
#if defined( SJCD_GATHER_STAT )
- statistic.idle_ticks++;
+ statistic.idle_ticks++;
#endif
#if defined( SJCD_TRACE )
- printk( "SJCD_S_IDLE\n" );
+ printk("SJCD_S_IDLE\n");
#endif
- return;
- }
+ return;
+ }
- case SJCD_S_START:{
+ case SJCD_S_START:{
#if defined( SJCD_GATHER_STAT )
- statistic.start_ticks++;
+ statistic.start_ticks++;
#endif
- sjcd_send_cmd( SCMD_GET_STATUS );
- sjcd_transfer_state =
- sjcd_mode == SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
- sjcd_transfer_timeout = 500;
+ sjcd_send_cmd(SCMD_GET_STATUS);
+ sjcd_transfer_state =
+ sjcd_mode ==
+ SCMD_MODE_COOKED ? SJCD_S_READ : SJCD_S_MODE;
+ sjcd_transfer_timeout = 500;
#if defined( SJCD_TRACE )
- printk( "SJCD_S_START: goto SJCD_S_%s mode\n",
- sjcd_transfer_state == SJCD_S_READ ? "READ" : "MODE" );
-#endif
- break;
- }
-
- case SJCD_S_MODE:{
- if( sjcd_check_status() ){
- /*
- * Previous command is completed.
- */
- if( !sjcd_status_valid || sjcd_command_failed ){
+ printk("SJCD_S_START: goto SJCD_S_%s mode\n",
+ sjcd_transfer_state ==
+ SJCD_S_READ ? "READ" : "MODE");
+#endif
+ break;
+ }
+
+ case SJCD_S_MODE:{
+ if (sjcd_check_status()) {
+ /*
+ * Previous command is completed.
+ */
+ if (!sjcd_status_valid
+ || sjcd_command_failed) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- sjcd_mode = 0; /* unknown mode; should not be valid when failed */
- sjcd_send_1_cmd( SCMD_SET_MODE, SCMD_MODE_COOKED );
- sjcd_transfer_state = SJCD_S_READ; sjcd_transfer_timeout = 1000;
+ printk
+ ("SJCD_S_MODE: pre-cmd failed: goto to SJCD_S_STOP mode\n");
+#endif
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+
+ sjcd_mode = 0; /* unknown mode; should not be valid when failed */
+ sjcd_send_1_cmd(SCMD_SET_MODE,
+ SCMD_MODE_COOKED);
+ sjcd_transfer_state = SJCD_S_READ;
+ sjcd_transfer_timeout = 1000;
#if defined( SJCD_TRACE )
- printk( "SJCD_S_MODE: goto SJCD_S_READ mode\n" );
+ printk
+ ("SJCD_S_MODE: goto SJCD_S_READ mode\n");
#endif
- }
+ }
#if defined( SJCD_GATHER_STAT )
- else statistic.mode_ticks++;
-#endif
- break;
- }
-
- case SJCD_S_READ:{
- if( sjcd_status_valid ? 1 : sjcd_check_status() ){
- /*
- * Previous command is completed.
- */
- if( !sjcd_status_valid || sjcd_command_failed ){
+ else
+ statistic.mode_ticks++;
+#endif
+ break;
+ }
+
+ case SJCD_S_READ:{
+ if (sjcd_status_valid ? 1 : sjcd_check_status()) {
+ /*
+ * Previous command is completed.
+ */
+ if (!sjcd_status_valid
+ || sjcd_command_failed) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n" );
+ printk
+ ("SJCD_S_READ: pre-cmd failed: goto to SJCD_S_STOP mode\n");
#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- if( !sjcd_media_is_available ){
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+ if (!sjcd_media_is_available) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- if( sjcd_mode != SCMD_MODE_COOKED ){
- /*
- * We seem to come from set mode. So discard one byte of result.
- */
- if( sjcd_load_response( &sjcd_mode, 1 ) != 0 ){
+ printk
+ ("SJCD_S_READ: no disk: goto to SJCD_S_STOP mode\n");
+#endif
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+ if (sjcd_mode != SCMD_MODE_COOKED) {
+ /*
+ * We seem to come from set mode. So discard one byte of result.
+ */
+ if (sjcd_load_response
+ (&sjcd_mode, 1) != 0) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- if( sjcd_mode != SCMD_MODE_COOKED ){
+ printk
+ ("SJCD_S_READ: load failed: goto to SJCD_S_STOP mode\n");
+#endif
+ sjcd_transfer_state =
+ SJCD_S_STOP;
+ goto ReSwitch;
+ }
+ if (sjcd_mode != SCMD_MODE_COOKED) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- }
-
- if( CURRENT_IS_VALID ){
- struct sjcd_play_msf msf;
-
- sjcd_next_bn = CURRENT->sector / 4;
- hsg2msf( sjcd_next_bn, &msf.start );
- msf.end.min = 0; msf.end.sec = 0;
- msf.end.frame = sjcd_read_count = SJCD_BUF_SIZ;
+ printk
+ ("SJCD_S_READ: mode failed: goto to SJCD_S_STOP mode\n");
+#endif
+ sjcd_transfer_state =
+ SJCD_S_STOP;
+ goto ReSwitch;
+ }
+ }
+
+ if (CURRENT_IS_VALID) {
+ struct sjcd_play_msf msf;
+
+ sjcd_next_bn = CURRENT->sector / 4;
+ hsg2msf(sjcd_next_bn, &msf.start);
+ msf.end.min = 0;
+ msf.end.sec = 0;
+ msf.end.frame = sjcd_read_count =
+ SJCD_BUF_SIZ;
#if defined( SJCD_TRACE )
- printk( "SJCD: ---reading msf-address %x:%x:%x %x:%x:%x\n",
- msf.start.min, msf.start.sec, msf.start.frame,
- msf.end.min, msf.end.sec, msf.end.frame );
- printk( "sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n", \
- sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
- sjcd_buf_bn[ sjcd_buf_in ] );
-#endif
- sjcd_send_6_cmd( SCMD_DATA_READ, &msf );
- sjcd_transfer_state = SJCD_S_DATA;
- sjcd_transfer_timeout = 500;
+ printk
+ ("SJCD: ---reading msf-address %x:%x:%x %x:%x:%x\n",
+ msf.start.min, msf.start.sec,
+ msf.start.frame, msf.end.min,
+ msf.end.sec, msf.end.frame);
+ printk
+ ("sjcd_next_bn:%x buf_in:%x buf_out:%x buf_bn:%x\n",
+ sjcd_next_bn, sjcd_buf_in,
+ sjcd_buf_out,
+ sjcd_buf_bn[sjcd_buf_in]);
+#endif
+ sjcd_send_6_cmd(SCMD_DATA_READ,
+ &msf);
+ sjcd_transfer_state = SJCD_S_DATA;
+ sjcd_transfer_timeout = 500;
#if defined( SJCD_TRACE )
- printk( "SJCD_S_READ: go to SJCD_S_DATA mode\n" );
+ printk
+ ("SJCD_S_READ: go to SJCD_S_DATA mode\n");
#endif
- } else {
+ } else {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n" );
+ printk
+ ("SJCD_S_READ: nothing to read: go to SJCD_S_STOP mode\n");
#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- }
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+ }
#if defined( SJCD_GATHER_STAT )
- else statistic.read_ticks++;
+ else
+ statistic.read_ticks++;
#endif
- break;
- }
+ break;
+ }
- case SJCD_S_DATA:{
- unsigned char stat;
+ case SJCD_S_DATA:{
+ unsigned char stat;
- sjcd_s_data: stat = inb( SJCDPORT( 1 ) );
+ sjcd_s_data:stat =
+ inb(SJCDPORT
+ (1));
#if defined( SJCD_TRACE )
- printk( "SJCD_S_DATA: status = 0x%02x\n", stat );
+ printk("SJCD_S_DATA: status = 0x%02x\n", stat);
#endif
- if( SJCD_STATUS_AVAILABLE( stat ) ){
- /*
- * No data is waiting for us in the drive buffer. Status of operation
- * completion is available. Read and parse it.
- */
- sjcd_load_status();
+ if (SJCD_STATUS_AVAILABLE(stat)) {
+ /*
+ * No data is waiting for us in the drive buffer. Status of operation
+ * completion is available. Read and parse it.
+ */
+ sjcd_load_status();
- if( !sjcd_status_valid || sjcd_command_failed ){
+ if (!sjcd_status_valid
+ || sjcd_command_failed) {
#if defined( SJCD_TRACE )
- printk( "SJCD: read block %d failed, maybe audio disk? Giving up\n",
- sjcd_next_bn );
+ printk
+ ("SJCD: read block %d failed, maybe audio disk? Giving up\n",
+ sjcd_next_bn);
#endif
- if( CURRENT_IS_VALID ) end_request( 0 );
+ if (CURRENT_IS_VALID)
+ end_request(0);
#if defined( SJCD_TRACE )
- printk( "SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- if( !sjcd_media_is_available ){
- printk( "SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n" );
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- sjcd_transfer_state = SJCD_S_READ;
- goto ReSwitch;
- } else if( SJCD_DATA_AVAILABLE( stat ) ){
- /*
- * One frame is read into device buffer. We must copy it to our memory.
- * Otherwise cdrom hangs up. Check to see if we have something to copy
- * to.
- */
- if( !CURRENT_IS_VALID && sjcd_buf_in == sjcd_buf_out ){
+ printk
+ ("SJCD_S_DATA: pre-cmd failed: go to SJCD_S_STOP mode\n");
+#endif
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+
+ if (!sjcd_media_is_available) {
+ printk
+ ("SJCD_S_DATA: no disk: go to SJCD_S_STOP mode\n");
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+
+ sjcd_transfer_state = SJCD_S_READ;
+ goto ReSwitch;
+ } else if (SJCD_DATA_AVAILABLE(stat)) {
+ /*
+ * One frame is read into device buffer. We must copy it to our memory.
+ * Otherwise cdrom hangs up. Check to see if we have something to copy
+ * to.
+ */
+ if (!CURRENT_IS_VALID
+ && sjcd_buf_in == sjcd_buf_out) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n" );
- printk( " ... all the date would be discarded\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
-
- /*
- * Everything seems to be OK. Just read the frame and recalculate
- * indices.
- */
- sjcd_buf_bn[ sjcd_buf_in ] = -1; /* ??? */
- insb( SJCDPORT( 2 ), sjcd_buf + 2048 * sjcd_buf_in, 2048 );
+ printk
+ ("SJCD_S_DATA: nothing to read: go to SJCD_S_STOP mode\n");
+ printk
+ (" ... all the date would be discarded\n");
+#endif
+ sjcd_transfer_state = SJCD_S_STOP;
+ goto ReSwitch;
+ }
+
+ /*
+ * Everything seems to be OK. Just read the frame and recalculate
+ * indices.
+ */
+ sjcd_buf_bn[sjcd_buf_in] = -1; /* ??? */
+ insb(SJCDPORT(2),
+ sjcd_buf + 2048 * sjcd_buf_in, 2048);
#if defined( SJCD_TRACE )
- printk( "SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
- sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
- sjcd_buf_bn[ sjcd_buf_in ] );
-#endif
- sjcd_buf_bn[ sjcd_buf_in ] = sjcd_next_bn++;
- if( sjcd_buf_out == -1 ) sjcd_buf_out = sjcd_buf_in;
- if( ++sjcd_buf_in == SJCD_BUF_SIZ ) sjcd_buf_in = 0;
-
- /*
- * Only one frame is ready at time. So we should turn over to wait for
- * another frame. If we need that, of course.
- */
- if( --sjcd_read_count == 0 ){
- /*
- * OK, request seems to be precessed. Continue transferring...
- */
- if( !sjcd_transfer_is_active ){
- while( CURRENT_IS_VALID ){
- /*
- * Continue transferring.
- */
- sjcd_transfer();
- if( CURRENT->nr_sectors == 0 ) end_request( 1 );
- else break;
- }
- }
- if( CURRENT_IS_VALID &&
- ( CURRENT->sector / 4 < sjcd_next_bn ||
- CURRENT->sector / 4 > sjcd_next_bn + SJCD_BUF_SIZ ) ){
+ printk
+ ("SJCD_S_DATA: next_bn=%d, buf_in=%d, buf_out=%d, buf_bn=%d\n",
+ sjcd_next_bn, sjcd_buf_in,
+ sjcd_buf_out,
+ sjcd_buf_bn[sjcd_buf_in]);
+#endif
+ sjcd_buf_bn[sjcd_buf_in] = sjcd_next_bn++;
+ if (sjcd_buf_out == -1)
+ sjcd_buf_out = sjcd_buf_in;
+ if (++sjcd_buf_in == SJCD_BUF_SIZ)
+ sjcd_buf_in = 0;
+
+ /*
+ * Only one frame is ready at time. So we should turn over to wait for
+ * another frame. If we need that, of course.
+ */
+ if (--sjcd_read_count == 0) {
+ /*
+ * OK, request seems to be precessed. Continue transferring...
+ */
+ if (!sjcd_transfer_is_active) {
+ while (CURRENT_IS_VALID) {
+ /*
+ * Continue transferring.
+ */
+ sjcd_transfer();
+ if (CURRENT->
+ nr_sectors ==
+ 0)
+ end_request
+ (1);
+ else
+ break;
+ }
+ }
+ if (CURRENT_IS_VALID &&
+ (CURRENT->sector / 4 <
+ sjcd_next_bn
+ || CURRENT->sector / 4 >
+ sjcd_next_bn +
+ SJCD_BUF_SIZ)) {
#if defined( SJCD_TRACE )
- printk( "SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n" );
-#endif
- sjcd_transfer_state = SJCD_S_STOP;
- goto ReSwitch;
- }
- }
- /*
- * Now we should turn around rather than wait for while.
- */
- goto sjcd_s_data;
- }
+ printk
+ ("SJCD_S_DATA: can't read: go to SJCD_S_STOP mode\n");
+#endif
+ sjcd_transfer_state =
+ SJCD_S_STOP;
+ goto ReSwitch;
+ }
+ }
+ /*
+ * Now we should turn around rather than wait for while.
+ */
+ goto sjcd_s_data;
+ }
#if defined( SJCD_GATHER_STAT )
- else statistic.data_ticks++;
+ else
+ statistic.data_ticks++;
#endif
- break;
- }
+ break;
+ }
- case SJCD_S_STOP:{
- sjcd_read_count = 0;
- sjcd_send_cmd( SCMD_STOP );
- sjcd_transfer_state = SJCD_S_STOPPING;
- sjcd_transfer_timeout = 500;
+ case SJCD_S_STOP:{
+ sjcd_read_count = 0;
+ sjcd_send_cmd(SCMD_STOP);
+ sjcd_transfer_state = SJCD_S_STOPPING;
+ sjcd_transfer_timeout = 500;
#if defined( SJCD_GATHER_STAT )
- statistic.stop_ticks++;
+ statistic.stop_ticks++;
#endif
- break;
- }
+ break;
+ }
+
+ case SJCD_S_STOPPING:{
+ unsigned char stat;
- case SJCD_S_STOPPING:{
- unsigned char stat;
-
- stat = inb( SJCDPORT( 1 ) );
+ stat = inb(SJCDPORT(1));
#if defined( SJCD_TRACE )
- printk( "SJCD_S_STOP: status = 0x%02x\n", stat );
-#endif
- if( SJCD_DATA_AVAILABLE( stat ) ){
- int i;
+ printk("SJCD_S_STOP: status = 0x%02x\n", stat);
+#endif
+ if (SJCD_DATA_AVAILABLE(stat)) {
+ int i;
#if defined( SJCD_TRACE )
- printk( "SJCD_S_STOP: discard data\n" );
-#endif
- /*
- * Discard all the data from the pipe. Foolish method.
- */
- for( i = 2048; i--; ( void )inb( SJCDPORT( 2 ) ) );
- sjcd_transfer_timeout = 500;
- } else if( SJCD_STATUS_AVAILABLE( stat ) ){
- sjcd_load_status();
- if( sjcd_status_valid && sjcd_media_is_changed ) {
- sjcd_toc_uptodate = 0;
- sjcd_invalidate_buffers();
- }
- if( CURRENT_IS_VALID ){
- if( sjcd_status_valid ) sjcd_transfer_state = SJCD_S_READ;
- else sjcd_transfer_state = SJCD_S_START;
- } else sjcd_transfer_state = SJCD_S_IDLE;
- goto ReSwitch;
- }
+ printk("SJCD_S_STOP: discard data\n");
+#endif
+ /*
+ * Discard all the data from the pipe. Foolish method.
+ */
+ for (i = 2048; i--;
+ (void) inb(SJCDPORT(2)));
+ sjcd_transfer_timeout = 500;
+ } else if (SJCD_STATUS_AVAILABLE(stat)) {
+ sjcd_load_status();
+ if (sjcd_status_valid
+ && sjcd_media_is_changed) {
+ sjcd_toc_uptodate = 0;
+ sjcd_invalidate_buffers();
+ }
+ if (CURRENT_IS_VALID) {
+ if (sjcd_status_valid)
+ sjcd_transfer_state =
+ SJCD_S_READ;
+ else
+ sjcd_transfer_state =
+ SJCD_S_START;
+ } else
+ sjcd_transfer_state = SJCD_S_IDLE;
+ goto ReSwitch;
+ }
#if defined( SJCD_GATHER_STAT )
- else statistic.stopping_ticks++;
-#endif
- break;
- }
-
- default:
- printk( "SJCD: poll: invalid state %d\n", sjcd_transfer_state );
- return;
- }
-
- if( --sjcd_transfer_timeout == 0 ){
- printk( "SJCD: timeout in state %d\n", sjcd_transfer_state );
- while( CURRENT_IS_VALID ) end_request( 0 );
- sjcd_send_cmd( SCMD_STOP );
- sjcd_transfer_state = SJCD_S_IDLE;
- goto ReSwitch;
- }
-
- /*
- * Get back in some time. 1 should be replaced with count variable to
- * avoid unnecessary testings.
- */
- SJCD_SET_TIMER( sjcd_poll, 1 );
+ else
+ statistic.stopping_ticks++;
+#endif
+ break;
+ }
+
+ default:
+ printk("SJCD: poll: invalid state %d\n",
+ sjcd_transfer_state);
+ return;
+ }
+
+ if (--sjcd_transfer_timeout == 0) {
+ printk("SJCD: timeout in state %d\n", sjcd_transfer_state);
+ while (CURRENT_IS_VALID)
+ end_request(0);
+ sjcd_send_cmd(SCMD_STOP);
+ sjcd_transfer_state = SJCD_S_IDLE;
+ goto ReSwitch;
+ }
+
+ /*
+ * Get back in some time. 1 should be replaced with count variable to
+ * avoid unnecessary testings.
+ */
+ SJCD_SET_TIMER(sjcd_poll, 1);
}
-static void do_sjcd_request( request_queue_t * q ){
+static void do_sjcd_request(request_queue_t * q)
+{
#if defined( SJCD_TRACE )
- printk( "SJCD: do_sjcd_request(%ld+%ld)\n",
- CURRENT->sector, CURRENT->nr_sectors );
-#endif
- sjcd_transfer_is_active = 1;
- while( CURRENT_IS_VALID ){
- /*
- * Who of us are paranoiac?
- */
- if( CURRENT->bh && !buffer_locked(CURRENT->bh) )
- panic( DEVICE_NAME ": block not locked" );
-
- sjcd_transfer();
- if( CURRENT->nr_sectors == 0 ) end_request( 1 );
- else {
- sjcd_buf_out = -1; /* Want to read a block not in buffer */
- if( sjcd_transfer_state == SJCD_S_IDLE ){
- if( !sjcd_toc_uptodate ){
- if( sjcd_update_toc() < 0 ){
- printk( "SJCD: transfer: discard\n" );
- while( CURRENT_IS_VALID ) end_request( 0 );
- break;
- }
+ printk("SJCD: do_sjcd_request(%ld+%ld)\n",
+ CURRENT->sector, CURRENT->nr_sectors);
+#endif
+ sjcd_transfer_is_active = 1;
+ while (CURRENT_IS_VALID) {
+ /*
+ * Who of us are paranoiac?
+ */
+ if (CURRENT->bh && !buffer_locked(CURRENT->bh))
+ panic(DEVICE_NAME ": block not locked");
+
+ sjcd_transfer();
+ if (CURRENT->nr_sectors == 0)
+ end_request(1);
+ else {
+ sjcd_buf_out = -1; /* Want to read a block not in buffer */
+ if (sjcd_transfer_state == SJCD_S_IDLE) {
+ if (!sjcd_toc_uptodate) {
+ if (sjcd_update_toc() < 0) {
+ printk
+ ("SJCD: transfer: discard\n");
+ while (CURRENT_IS_VALID)
+ end_request(0);
+ break;
+ }
+ }
+ sjcd_transfer_state = SJCD_S_START;
+ SJCD_SET_TIMER(sjcd_poll, HZ / 100);
+ }
+ break;
+ }
}
- sjcd_transfer_state = SJCD_S_START;
- SJCD_SET_TIMER( sjcd_poll, HZ/100 );
- }
- break;
- }
- }
- sjcd_transfer_is_active = 0;
+ sjcd_transfer_is_active = 0;
#if defined( SJCD_TRACE )
- printk( "sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
- sjcd_next_bn, sjcd_buf_in, sjcd_buf_out, sjcd_buf_bn[ sjcd_buf_in ] );
- printk( "do_sjcd_request ends\n" );
+ printk
+ ("sjcd_next_bn:%x sjcd_buf_in:%x sjcd_buf_out:%x sjcd_buf_bn:%x\n",
+ sjcd_next_bn, sjcd_buf_in, sjcd_buf_out,
+ sjcd_buf_bn[sjcd_buf_in]);
+ printk("do_sjcd_request ends\n");
#endif
}
/*
* Open the device special file. Check disk is in.
*/
-int sjcd_open( struct inode *ip, struct file *fp ){
- /*
- * Check the presence of device.
- */
- if( !sjcd_present ) return( -ENXIO );
-
- /*
- * Only read operations are allowed. Really? (:-)
- */
- if( fp->f_mode & 2 ) return( -EROFS );
-
- MOD_INC_USE_COUNT;
-
- if( sjcd_open_count == 0 ){
- int s, sjcd_open_tries;
+int sjcd_open(struct inode *ip, struct file *fp)
+{
+ /*
+ * Check the presence of device.
+ */
+ if (!sjcd_present)
+ return (-ENXIO);
+
+ /*
+ * Only read operations are allowed. Really? (:-)
+ */
+ if (fp->f_mode & 2)
+ return (-EROFS);
+
+ MOD_INC_USE_COUNT;
+
+ if (sjcd_open_count == 0) {
+ int s, sjcd_open_tries;
/* We don't know that, do we? */
/*
sjcd_audio_status = CDROM_AUDIO_NO_STATUS;
*/
- sjcd_mode = 0;
- sjcd_door_was_open = 0;
- sjcd_transfer_state = SJCD_S_IDLE;
- sjcd_invalidate_buffers();
- sjcd_status_valid = 0;
-
- /*
- * Strict status checking.
- */
- for( sjcd_open_tries = 4; --sjcd_open_tries; ){
- if( !sjcd_status_valid ) sjcd_get_status();
- if( !sjcd_status_valid ){
+ sjcd_mode = 0;
+ sjcd_door_was_open = 0;
+ sjcd_transfer_state = SJCD_S_IDLE;
+ sjcd_invalidate_buffers();
+ sjcd_status_valid = 0;
+
+ /*
+ * Strict status checking.
+ */
+ for (sjcd_open_tries = 4; --sjcd_open_tries;) {
+ if (!sjcd_status_valid)
+ sjcd_get_status();
+ if (!sjcd_status_valid) {
#if defined( SJCD_DIAGNOSTIC )
- printk( "SJCD: open: timed out when check status.\n" );
+ printk
+ ("SJCD: open: timed out when check status.\n");
#endif
- goto err_out;
- } else if( !sjcd_media_is_available ){
+ goto err_out;
+ } else if (!sjcd_media_is_available) {
#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: open: no disk in drive\n");
+ printk("SJCD: open: no disk in drive\n");
#endif
- if( !sjcd_door_closed ){
- sjcd_door_was_open = 1;
+ if (!sjcd_door_closed) {
+ sjcd_door_was_open = 1;
#if defined( SJCD_TRACE )
- printk("SJCD: open: close the tray\n");
+ printk
+ ("SJCD: open: close the tray\n");
#endif
- s = sjcd_tray_close();
- if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+ s = sjcd_tray_close();
+ if (s < 0 || !sjcd_status_valid
+ || sjcd_command_failed) {
#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: open: tray close attempt failed\n");
-#endif
- goto err_out;
- }
- continue;
- } else goto err_out;
- }
- break;
- }
- s = sjcd_tray_lock();
- if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+ printk
+ ("SJCD: open: tray close attempt failed\n");
+#endif
+ goto err_out;
+ }
+ continue;
+ } else
+ goto err_out;
+ }
+ break;
+ }
+ s = sjcd_tray_lock();
+ if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: open: tray lock attempt failed\n");
+ printk("SJCD: open: tray lock attempt failed\n");
#endif
- goto err_out;
- }
+ goto err_out;
+ }
#if defined( SJCD_TRACE )
- printk( "SJCD: open: done\n" );
+ printk("SJCD: open: done\n");
#endif
- }
+ }
- ++sjcd_open_count;
- return( 0 );
+ ++sjcd_open_count;
+ return (0);
-err_out:
- MOD_DEC_USE_COUNT;
- return( -EIO );
+ err_out:
+ MOD_DEC_USE_COUNT;
+ return (-EIO);
}
/*
* On close, we flush all sjcd blocks from the buffer cache.
*/
-static int sjcd_release( struct inode *inode, struct file *file ){
- int s;
+static int sjcd_release(struct inode *inode, struct file *file)
+{
+ int s;
#if defined( SJCD_TRACE )
- printk( "SJCD: release\n" );
+ printk("SJCD: release\n");
#endif
#ifdef MODULE
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT;
#endif
- if( --sjcd_open_count == 0 ){
- sjcd_invalidate_buffers();
- s = sjcd_tray_unlock();
- if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+ if (--sjcd_open_count == 0) {
+ sjcd_invalidate_buffers();
+ s = sjcd_tray_unlock();
+ if (s < 0 || !sjcd_status_valid || sjcd_command_failed) {
#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: release: tray unlock attempt failed.\n");
-#endif
- }
- if( sjcd_door_was_open ){
- s = sjcd_tray_open();
- if( s < 0 || !sjcd_status_valid || sjcd_command_failed ){
+ printk
+ ("SJCD: release: tray unlock attempt failed.\n");
+#endif
+ }
+ if (sjcd_door_was_open) {
+ s = sjcd_tray_open();
+ if (s < 0 || !sjcd_status_valid
+ || sjcd_command_failed) {
#if defined( SJCD_DIAGNOSTIC )
- printk("SJCD: release: tray unload attempt failed.\n");
+ printk
+ ("SJCD: release: tray unload attempt failed.\n");
#endif
- }
- }
- }
- return 0;
+ }
+ }
+ }
+ return 0;
}
/*
* A list of file operations allowed for this cdrom.
*/
static struct block_device_operations sjcd_fops = {
- open: sjcd_open,
- release: sjcd_release,
- ioctl: sjcd_ioctl,
- check_media_change: sjcd_disk_change,
+ open:sjcd_open,
+ release:sjcd_release,
+ ioctl:sjcd_ioctl,
+ check_media_change:sjcd_disk_change,
};
static int blksize = 2048;
* The version is two BCD-coded bytes.
*/
static struct {
- unsigned char major, minor;
+ unsigned char major, minor;
} sjcd_version;
/*
* Test for presence of drive and initialize it. Called at boot time.
* Probe cdrom, find out version and status.
*/
-int __init sjcd_init( void ){
- int i;
+int __init sjcd_init(void)
+{
+ int i;
- printk(KERN_INFO "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n", SJCD_VERSION_MAJOR,
- SJCD_VERSION_MINOR);
+ printk(KERN_INFO
+ "SJCD: Sanyo CDR-H94A cdrom driver version %d.%d.\n",
+ SJCD_VERSION_MAJOR, SJCD_VERSION_MINOR);
#if defined( SJCD_TRACE )
- printk("SJCD: sjcd=0x%x: ", sjcd_base);
-#endif
+ printk("SJCD: sjcd=0x%x: ", sjcd_base);
+#endif
hardsect_size[MAJOR_NR] = &secsize;
blksize_size[MAJOR_NR] = &blksize;
- if( devfs_register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){
- printk( "SJCD: Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR );
- return( -EIO );
- }
-
- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
- read_ahead[ MAJOR_NR ] = 4;
- register_disk(NULL, MKDEV(MAJOR_NR,0), 1, &sjcd_fops, 0);
-
- if( check_region( sjcd_base, 4 ) ){
- printk( "SJCD: Init failed, I/O port (%X) is already in use\n",
- sjcd_base );
- sjcd_cleanup();
- return( -EIO );
- }
-
- /*
- * Check for card. Since we are booting now, we can't use standard
- * wait algorithm.
- */
- printk(KERN_INFO "SJCD: Resetting: " );
- sjcd_send_cmd( SCMD_RESET );
- for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
- unsigned long timer;
-
- /*
- * Wait 10ms approx.
- */
- for( timer = jiffies; time_before_eq(jiffies, timer); );
- if ( (i % 100) == 0 ) printk( "." );
- ( void )sjcd_check_status();
- }
- if( i == 0 || sjcd_command_failed ){
- printk( " reset failed, no drive found.\n" );
- sjcd_cleanup();
- return( -EIO );
- } else printk( "\n" );
-
- /*
- * Get and print out cdrom version.
- */
- printk(KERN_INFO "SJCD: Getting version: " );
- sjcd_send_cmd( SCMD_GET_VERSION );
- for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
- unsigned long timer;
-
- /*
- * Wait 10ms approx.
- */
- for( timer = jiffies; time_before_eq(jiffies, timer); );
- if ( (i % 100) == 0 ) printk( "." );
- ( void )sjcd_check_status();
- }
- if( i == 0 || sjcd_command_failed ){
- printk( " get version failed, no drive found.\n" );
- sjcd_cleanup();
- return( -EIO );
- }
-
- if( sjcd_load_response( &sjcd_version, sizeof( sjcd_version ) ) == 0 ){
- printk( " %1x.%02x\n", ( int )sjcd_version.major,
- ( int )sjcd_version.minor );
- } else {
- printk( " read version failed, no drive found.\n" );
- sjcd_cleanup();
- return( -EIO );
- }
-
- /*
- * Check and print out the tray state. (if it is needed?).
- */
- if( !sjcd_status_valid ){
- printk(KERN_INFO "SJCD: Getting status: " );
- sjcd_send_cmd( SCMD_GET_STATUS );
- for( i = 1000; i > 0 && !sjcd_status_valid; --i ){
- unsigned long timer;
-
- /*
- * Wait 10ms approx.
- */
- for( timer = jiffies; time_before_eq(jiffies, timer); );
- if ( (i % 100) == 0 ) printk( "." );
- ( void )sjcd_check_status();
- }
- if( i == 0 || sjcd_command_failed ){
- printk( " get status failed, no drive found.\n" );
- sjcd_cleanup();
- return( -EIO );
- } else printk( "\n" );
- }
-
- printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
- devfs_register (NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
- S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
-
- sjcd_present++;
- return( 0 );
+ if (devfs_register_blkdev(MAJOR_NR, "sjcd", &sjcd_fops) != 0) {
+ printk("SJCD: Unable to get major %d for Sanyo CD-ROM\n",
+ MAJOR_NR);
+ return (-EIO);
+ }
+
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+ read_ahead[MAJOR_NR] = 4;
+ register_disk(NULL, MKDEV(MAJOR_NR, 0), 1, &sjcd_fops, 0);
+
+ if (check_region(sjcd_base, 4)) {
+ printk
+ ("SJCD: Init failed, I/O port (%X) is already in use\n",
+ sjcd_base);
+ sjcd_cleanup();
+ return (-EIO);
+ }
+
+ /*
+ * Check for card. Since we are booting now, we can't use standard
+ * wait algorithm.
+ */
+ printk(KERN_INFO "SJCD: Resetting: ");
+ sjcd_send_cmd(SCMD_RESET);
+ for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+ unsigned long timer;
+
+ /*
+ * Wait 10ms approx.
+ */
+ for (timer = jiffies; time_before_eq(jiffies, timer););
+ if ((i % 100) == 0)
+ printk(".");
+ (void) sjcd_check_status();
+ }
+ if (i == 0 || sjcd_command_failed) {
+ printk(" reset failed, no drive found.\n");
+ sjcd_cleanup();
+ return (-EIO);
+ } else
+ printk("\n");
+
+ /*
+ * Get and print out cdrom version.
+ */
+ printk(KERN_INFO "SJCD: Getting version: ");
+ sjcd_send_cmd(SCMD_GET_VERSION);
+ for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+ unsigned long timer;
+
+ /*
+ * Wait 10ms approx.
+ */
+ for (timer = jiffies; time_before_eq(jiffies, timer););
+ if ((i % 100) == 0)
+ printk(".");
+ (void) sjcd_check_status();
+ }
+ if (i == 0 || sjcd_command_failed) {
+ printk(" get version failed, no drive found.\n");
+ sjcd_cleanup();
+ return (-EIO);
+ }
+
+ if (sjcd_load_response(&sjcd_version, sizeof(sjcd_version)) == 0) {
+ printk(" %1x.%02x\n", (int) sjcd_version.major,
+ (int) sjcd_version.minor);
+ } else {
+ printk(" read version failed, no drive found.\n");
+ sjcd_cleanup();
+ return (-EIO);
+ }
+
+ /*
+ * Check and print out the tray state. (if it is needed?).
+ */
+ if (!sjcd_status_valid) {
+ printk(KERN_INFO "SJCD: Getting status: ");
+ sjcd_send_cmd(SCMD_GET_STATUS);
+ for (i = 1000; i > 0 && !sjcd_status_valid; --i) {
+ unsigned long timer;
+
+ /*
+ * Wait 10ms approx.
+ */
+ for (timer = jiffies;
+ time_before_eq(jiffies, timer););
+ if ((i % 100) == 0)
+ printk(".");
+ (void) sjcd_check_status();
+ }
+ if (i == 0 || sjcd_command_failed) {
+ printk(" get status failed, no drive found.\n");
+ sjcd_cleanup();
+ return (-EIO);
+ } else
+ printk("\n");
+ }
+
+ printk(KERN_INFO "SJCD: Status: port=0x%x.\n", sjcd_base);
+ devfs_register(NULL, "sjcd", DEVFS_FL_DEFAULT, MAJOR_NR, 0,
+ S_IFBLK | S_IRUGO | S_IWUGO, &sjcd_fops, NULL);
+
+ sjcd_present++;
+ return (0);
}
-static int
-sjcd_cleanup(void)
+static int sjcd_cleanup(void)
{
- if( (devfs_unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL) )
- printk( "SJCD: cannot unregister device.\n" );
- else {
- release_region( sjcd_base, 4 );
- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
- }
-
- return(0);
+ if ((devfs_unregister_blkdev(MAJOR_NR, "sjcd") == -EINVAL))
+ printk("SJCD: cannot unregister device.\n");
+ else {
+ release_region(sjcd_base, 4);
+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
+ }
+
+ return (0);
}
void __exit sjcd_exit(void)
{
- devfs_unregister(devfs_find_handle(NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK,0));
- if ( sjcd_cleanup() )
- printk( "SJCD: module: cannot be removed.\n" );
- else
- printk(KERN_INFO "SJCD: module: removed.\n");
+ devfs_unregister(devfs_find_handle
+ (NULL, "sjcd", 0, 0, DEVFS_SPECIAL_BLK, 0));
+ if (sjcd_cleanup())
+ printk("SJCD: module: cannot be removed.\n");
+ else
+ printk(KERN_INFO "SJCD: module: removed.\n");
}
#ifdef MODULE
module_exit(sjcd_exit);
+MODULE_LICENSE("GPL");
/* Uncomment this if your mouse drivers expect the kernel to
* return with EAGAIN if the mouse does not have any events
- * available, even if the mouse is opened in nonblocking mode.
+ * available, even if the mouse is opened in blocking mode.
* Please report use of this "feature" to the author using the
* above address.
*/
EXPORT_SYMBOL(busmouse_add_buttons);
EXPORT_SYMBOL(register_busmouse);
EXPORT_SYMBOL(unregister_busmouse);
+
+MODULE_LICENSE("GPL");
static devfs_handle_t devfs_handle;
-static const char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
+static char banner[] __initdata = KERN_INFO "DSP56k driver installed\n";
static int __init dsp56k_init_driver(void)
{
devfs_unregister(devfs_handle);
}
module_exit(dsp56k_cleanup_driver);
+
+MODULE_LICENSE("GPL");
#ifdef CONFIG_SGI_NEWPORT_GFX
gfx_register ();
#endif
-#ifdef CONFIG_SGI
- streamable_init ();
-#endif
#ifdef CONFIG_TOSHIBA
tosh_init();
#endif
* asked to open it by an application.
*/
-static const char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
+static char banner[] __initdata = KERN_INFO "PC110 digitizer pad at 0x%X, irq %d.\n";
static int __init pc110pad_init_driver(void)
{
module_init(pc110pad_init_driver);
module_exit(pc110pad_exit_driver);
+
+MODULE_AUTHOR("Alan Cox, Robin O'Leary");
+MODULE_DESCRIPTION("Driver for the touchpad on the IBM PC110 palmtop");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
return 1;
}
-static const char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
-static const char msg_nomem[] __initdata = KERN_ERR "qpmouse: no queue memory.\n";
+static char msg_banner[] __initdata = KERN_INFO "82C710 type pointing device detected -- driver installed.\n";
+static char msg_nomem[] __initdata = KERN_ERR "qpmouse: no queue memory.\n";
static int __init qpmouse_init_driver(void)
{
module_init(qpmouse_init_driver);
module_exit(qpmouse_exit_driver);
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
#ifndef TWO_ZERO
MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.nl>");
MODULE_DESCRIPTION("RIO driver");
+MODULE_LICENSE("GPL");
MODULE_PARM(rio_poll, "i");
MODULE_PARM(rio_debug, "i");
MODULE_PARM(rio_irqmask, "i");
not freed. */
/* Call tmgr HANGUP HERE */
/* Fix this later when every thing works !!!! RAMRAJ */
- gs_got_break (PortP);
+ gs_got_break (&PortP->gs);
break;
case COMPLETE:
/* set inwordLut contents. Invoked by ioctl(). */
int sel_loadlut(const unsigned long arg)
{
- int err = -EFAULT;
-
- if (!copy_from_user(inwordLut, (u32 *)(arg+4), 32))
- err = 0;
- return err;
+ return copy_from_user(inwordLut, (u32 *)(arg+4), 32) ? -EFAULT : 0;
}
/* does screen address p correspond to character at LH/RH edge of screen? */
args = (unsigned short *)(arg + 1);
if (user) {
- int err;
- err = verify_area(VERIFY_READ, args, sizeof(short) * 5);
- if (err)
- return err;
- get_user(xs, args++);
- get_user(ys, args++);
- get_user(xe, args++);
- get_user(ye, args++);
- get_user(sel_mode, args);
+ if (verify_area(VERIFY_READ, args, sizeof(short) * 5))
+ return -EFAULT;
+ __get_user(xs, args++);
+ __get_user(ys, args++);
+ __get_user(xe, args++);
+ __get_user(ye, args++);
+ __get_user(sel_mode, args);
} else {
xs = *(args++); /* set selection from kernel */
ys = *(args++);
--- /dev/null
+/*
+ * drivers/char/serial_tx3912.c
+ *
+ * Copyright (C) 1999 Harald Koerfgen
+ * Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Serial driver for TMPR3912/05 and PR31700 processors
+ */
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/major.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/delay.h>
+#include <asm/wbflush.h>
+#include <asm/tx3912.h>
+#include "serial_tx3912.h"
+
+/*
+ * Forward declarations for serial routines
+ */
+static void rs_disable_tx_interrupts (void * ptr);
+static void rs_enable_tx_interrupts (void * ptr);
+static void rs_disable_rx_interrupts (void * ptr);
+static void rs_enable_rx_interrupts (void * ptr);
+static int rs_get_CD (void * ptr);
+static void rs_shutdown_port (void * ptr);
+static int rs_set_real_termios (void *ptr);
+static int rs_chars_in_buffer (void * ptr);
+static void rs_hungup (void *ptr);
+static void rs_close (void *ptr);
+
+/*
+ * Used by generic serial driver to access hardware
+ */
+static struct real_driver rs_real_driver = {
+ disable_tx_interrupts: rs_disable_tx_interrupts,
+ enable_tx_interrupts: rs_enable_tx_interrupts,
+ disable_rx_interrupts: rs_disable_rx_interrupts,
+ enable_rx_interrupts: rs_enable_rx_interrupts,
+ get_CD: rs_get_CD,
+ shutdown_port: rs_shutdown_port,
+ set_real_termios: rs_set_real_termios,
+ chars_in_buffer: rs_chars_in_buffer,
+ close: rs_close,
+ hungup: rs_hungup,
+};
+
+/*
+ * Structures and such for TTY sessions and usage counts
+ */
+static struct tty_driver rs_driver, rs_callout_driver;
+static struct tty_struct * rs_table[TX3912_UART_NPORTS] = { NULL, };
+static struct termios ** rs_termios;
+static struct termios ** rs_termios_locked;
+struct rs_port *rs_ports;
+int rs_refcount;
+int rs_initialized = 0;
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines. All of the following
+ * subroutines are declared as inline and are folded into
+ * rs_interrupt(). They were separated out for readability's sake.
+ *
+ * Note: rs_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off. People who may want to modify
+ * rs_interrupt() should try to keep the interrupt handler as fast as
+ * possible. After you are done making modifications, it is not a bad
+ * idea to do:
+ *
+ * gcc -S -DKERNEL -Wall -Wstrict-prototypes -O6 -fomit-frame-pointer serial.c
+ *
+ * and look at the resulting assemble code in serial.s.
+ *
+ * - Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+static inline void receive_char_pio(struct rs_port *port)
+{
+ struct tty_struct *tty = port->gs.tty;
+ unsigned char ch;
+ int counter = 2048;
+
+ /* While there are characters, get them ... */
+ while (counter>0) {
+ if (!(inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL))
+ break;
+ ch = inb(port->base + TX3912_UART_DATA);
+ if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+ *tty->flip.char_buf_ptr++ = ch;
+ *tty->flip.flag_buf_ptr++ = 0;
+ tty->flip.count++;
+ }
+ udelay(1); /* Allow things to happen - it take a while */
+ counter--;
+ }
+ if (!counter)
+ printk( "Ugh, looped in receive_char_pio!\n" );
+
+ tty_flip_buffer_push(tty);
+
+#if 0
+ /* Now handle error conditions */
+ if (*status & (INTTYPE(UART_RXOVERRUN_INT) |
+ INTTYPE(UART_FRAMEERR_INT) |
+ INTTYPE(UART_PARITYERR_INT) |
+ INTTYPE(UART_BREAK_INT))) {
+
+ /*
+ * Now check to see if character should be
+ * ignored, and mask off conditions which
+ * should be ignored.
+ */
+ if (*status & port->ignore_status_mask) {
+ goto ignore_char;
+ }
+ *status &= port->read_status_mask;
+
+ if (*status & INTTYPE(UART_BREAK_INT)) {
+ rs_dprintk(TX3912_UART_DEBUG_INTERRUPTS, "handling break....");
+ *tty->flip.flag_buf_ptr = TTY_BREAK;
+ }
+ else if (*status & INTTYPE(UART_PARITYERR_INT)) {
+ *tty->flip.flag_buf_ptr = TTY_PARITY;
+ }
+ else if (*status & INTTYPE(UART_FRAMEERR_INT)) {
+ *tty->flip.flag_buf_ptr = TTY_FRAME;
+ }
+ if (*status & INTTYPE(UART_RXOVERRUN_INT)) {
+ /*
+ * Overrun is special, since it's
+ * reported immediately, and doesn't
+ * affect the current character
+ */
+ if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+ tty->flip.count++;
+ tty->flip.flag_buf_ptr++;
+ tty->flip.char_buf_ptr++;
+ *tty->flip.flag_buf_ptr = TTY_OVERRUN;
+ }
+ }
+ }
+
+ tty->flip.flag_buf_ptr++;
+ tty->flip.char_buf_ptr++;
+ tty->flip.count++;
+
+ignore_char:
+ tty_flip_buffer_push(tty);
+#endif
+}
+
+static inline void transmit_char_pio(struct rs_port *port)
+{
+ /* While I'm able to transmit ... */
+ for (;;) {
+ if (!(inl(port->base + TX3912_UART_CTRL1) & UART_TX_EMPTY))
+ break;
+ else if (port->x_char) {
+ outb(port->x_char, port->base + TX3912_UART_DATA);
+ port->icount.tx++;
+ port->x_char = 0;
+ }
+ else if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+ port->gs.tty->hw_stopped) {
+ break;
+ }
+ else {
+ outb(port->gs.xmit_buf[port->gs.xmit_tail++],
+ port->base + TX3912_UART_DATA);
+ port->icount.tx++;
+ port->gs.xmit_tail &= SERIAL_XMIT_SIZE-1;
+ if (--port->gs.xmit_cnt <= 0) {
+ break;
+ }
+ }
+ udelay(10); /* Allow things to happen - it take a while */
+ }
+
+ if (port->gs.xmit_cnt <= 0 || port->gs.tty->stopped ||
+ port->gs.tty->hw_stopped) {
+ rs_disable_tx_interrupts(port);
+ }
+
+ if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+ if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ port->gs.tty->ldisc.write_wakeup)
+ (port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
+ rs_dprintk (TX3912_UART_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
+ port->gs.wakeup_chars);
+ wake_up_interruptible(&port->gs.tty->write_wait);
+ }
+}
+
+
+
+static inline void check_modem_status(struct rs_port *port)
+{
+ /* We don't have a carrier detect line - but just respond
+ like we had one anyways so that open() becomes unblocked */
+ wake_up_interruptible(&port->gs.open_wait);
+}
+
+int count = 0;
+
+/*
+ * This is the serial driver's interrupt routine (inlined, because
+ * there are two different versions of this, one for each serial port,
+ * differing only by the bits used in interrupt status 2 register)
+ */
+
+static inline void rs_rx_interrupt(int irq, void *dev_id,
+ struct pt_regs * regs, int intshift)
+{
+ struct rs_port * port;
+ unsigned long int2status;
+ unsigned long flags;
+ unsigned long ints;
+
+ save_and_cli(flags);
+
+ port = (struct rs_port *)dev_id;
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+
+ /* Get the interrrupts we have enabled */
+ int2status = IntStatus2 & IntEnable2;
+
+ /* Get interrupts in easy to use form */
+ ints = int2status >> intshift;
+
+ /* Clear any interrupts we might be about to handle */
+ IntClear2 = int2status & (
+ (INTTYPE(UART_RXOVERRUN_INT) |
+ INTTYPE(UART_FRAMEERR_INT) |
+ INTTYPE(UART_BREAK_INT) |
+ INTTYPE(UART_PARITYERR_INT) |
+ INTTYPE(UART_RX_INT)) << intshift);
+
+ if (!port || !port->gs.tty) {
+ restore_flags(flags);
+ return;
+ }
+
+ /* RX Receiver Holding Register Overrun */
+ if (ints & INTTYPE(UART_RXOVERRUN_INT)) {
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "overrun");
+ port->icount.overrun++;
+ }
+
+ /* RX Frame Error */
+ if (ints & INTTYPE(UART_FRAMEERR_INT)) {
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "frame error");
+ port->icount.frame++;
+ }
+
+ /* Break signal received */
+ if (ints & INTTYPE(UART_BREAK_INT)) {
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "break");
+ port->icount.brk++;
+ }
+
+ /* RX Parity Error */
+ if (ints & INTTYPE(UART_PARITYERR_INT)) {
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "parity error");
+ port->icount.parity++;
+ }
+
+ /* Receive byte (non-DMA) */
+ if (ints & INTTYPE(UART_RX_INT)) {
+ receive_char_pio(port);
+ }
+
+ restore_flags(flags);
+
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+}
+
+static inline void rs_tx_interrupt(int irq, void *dev_id,
+ struct pt_regs * regs, int intshift)
+{
+ struct rs_port * port;
+ unsigned long int2status;
+ unsigned long flags;
+ unsigned long ints;
+
+ save_and_cli(flags);
+
+ port = (struct rs_port *)dev_id;
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "rs_interrupt (port %p, shift %d)...", port, intshift);
+
+ /* Get the interrrupts we have enabled */
+ int2status = IntStatus2 & IntEnable2;
+
+ if (!port || !port->gs.tty) {
+ restore_flags(flags);
+ return;
+ }
+
+ /* Get interrupts in easy to use form */
+ ints = int2status >> intshift;
+
+ /* Clear any interrupts we might be about to handle */
+ IntClear2 = int2status & (
+ (INTTYPE(UART_TX_INT) |
+ INTTYPE(UART_EMPTY_INT) |
+ INTTYPE(UART_TXOVERRUN_INT)) << intshift);
+
+ /* TX holding register empty, so transmit byte (non-DMA) */
+ if (ints & (INTTYPE(UART_TX_INT) | INTTYPE(UART_EMPTY_INT))) {
+ transmit_char_pio(port);
+ }
+
+ /* TX Transmit Holding Register Overrun (shouldn't happen) */
+ if (ints & INTTYPE(UART_TXOVERRUN_INT)) {
+ printk ( "rs: TX overrun\n");
+ }
+
+ /*
+ check_modem_status();
+ */
+
+ restore_flags(flags);
+
+ rs_dprintk (TX3912_UART_DEBUG_INTERRUPTS, "end.\n");
+}
+
+static void rs_rx_interrupt_uarta(int irq, void *dev_id,
+ struct pt_regs * regs)
+{
+ rs_rx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+}
+
+static void rs_tx_interrupt_uarta(int irq, void *dev_id,
+ struct pt_regs * regs)
+{
+ rs_tx_interrupt(irq, dev_id, regs, UARTA_SHIFT);
+}
+
+/*
+ ***********************************************************************
+ * Here are the routines that actually *
+ * interface with the generic_serial driver *
+ ***********************************************************************
+ */
+static void rs_disable_tx_interrupts (void * ptr)
+{
+ struct rs_port *port = ptr;
+ unsigned long flags;
+
+ save_and_cli(flags);
+ port->gs.flags &= ~GS_TX_INTEN;
+
+ IntEnable2 &= ~((INTTYPE(UART_TX_INT) |
+ INTTYPE(UART_EMPTY_INT) |
+ INTTYPE(UART_TXOVERRUN_INT)) << port->intshift);
+
+ IntClear2 = (INTTYPE(UART_TX_INT) |
+ INTTYPE(UART_EMPTY_INT) |
+ INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+ restore_flags(flags);
+}
+
+static void rs_enable_tx_interrupts (void * ptr)
+{
+ struct rs_port *port = ptr;
+ unsigned long flags;
+
+ save_and_cli(flags);
+
+ IntClear2 = (INTTYPE(UART_TX_INT) |
+ INTTYPE(UART_EMPTY_INT) |
+ INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+ IntEnable2 |= (INTTYPE(UART_TX_INT) |
+ INTTYPE(UART_EMPTY_INT) |
+ INTTYPE(UART_TXOVERRUN_INT)) << port->intshift;
+
+ /* Send a char to start TX interrupts happening */
+ transmit_char_pio(port);
+
+ restore_flags(flags);
+}
+
+static void rs_disable_rx_interrupts (void * ptr)
+{
+ struct rs_port *port = ptr;
+ unsigned long flags;
+
+ save_and_cli(flags);
+
+ IntEnable2 &= ~((INTTYPE(UART_RX_INT) |
+ INTTYPE(UART_RXOVERRUN_INT) |
+ INTTYPE(UART_FRAMEERR_INT) |
+ INTTYPE(UART_BREAK_INT) |
+ INTTYPE(UART_PARITYERR_INT)) << port->intshift);
+
+ IntClear2 = (INTTYPE(UART_RX_INT) |
+ INTTYPE(UART_RXOVERRUN_INT) |
+ INTTYPE(UART_FRAMEERR_INT) |
+ INTTYPE(UART_BREAK_INT) |
+ INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+ restore_flags(flags);
+}
+
+static void rs_enable_rx_interrupts (void * ptr)
+{
+ struct rs_port *port = ptr;
+ unsigned long flags;
+
+ save_and_cli(flags);
+
+ IntEnable2 |= (INTTYPE(UART_RX_INT) |
+ INTTYPE(UART_RXOVERRUN_INT) |
+ INTTYPE(UART_FRAMEERR_INT) |
+ INTTYPE(UART_BREAK_INT) |
+ INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+ /* Empty the input buffer - apparently this is *vital* */
+ while (inl(port->base + TX3912_UART_CTRL1) & UART_RX_HOLD_FULL) {
+ inb(port->base + TX3912_UART_DATA);
+ }
+
+ IntClear2 = (INTTYPE(UART_RX_INT) |
+ INTTYPE(UART_RXOVERRUN_INT) |
+ INTTYPE(UART_FRAMEERR_INT) |
+ INTTYPE(UART_BREAK_INT) |
+ INTTYPE(UART_PARITYERR_INT)) << port->intshift;
+
+ restore_flags(flags);
+}
+
+
+static int rs_get_CD (void * ptr)
+{
+ /* No Carried Detect in Hardware - just return true */
+ func_exit();
+ return (1);
+}
+
+static void rs_shutdown_port (void * ptr)
+{
+ struct rs_port *port = ptr;
+
+ func_enter();
+
+ port->gs.flags &= ~GS_ACTIVE;
+
+ func_exit();
+}
+
+static int rs_set_real_termios (void *ptr)
+{
+ struct rs_port *port = ptr;
+ int t;
+
+ switch (port->gs.baud) {
+ /* Save some typing work... */
+#define e(x) case x:t= TX3912_UART_CTRL2_B ## x ; break
+ e(300);e(600);e(1200);e(2400);e(4800);e(9600);
+ e(19200);e(38400);e(57600);e(76800);e(115200);e(230400);
+ case 0 :t = -1;
+ break;
+ default:
+ /* Can I return "invalid"? */
+ t = TX3912_UART_CTRL2_B9600;
+ printk (KERN_INFO "rs: unsupported baud rate: %d.\n", port->gs.baud);
+ break;
+ }
+#undef e
+ if (t >= 0) {
+ /* Jim: Set Hardware Baud rate - there is some good
+ code in drivers/char/serial.c */
+
+ /* Program hardware for parity, data bits, stop bits (note: these are hardcoded to 8N1 */
+ UartA_Ctrl1 &= 0xf000000f;
+ UartA_Ctrl1 &= ~(UART_DIS_TXD | SER_SEVEN_BIT | SER_EVEN_PARITY | SER_TWO_STOP);
+
+#define CFLAG port->gs.tty->termios->c_cflag
+ if (C_PARENB(port->gs.tty)) {
+ if (!C_PARODD(port->gs.tty))
+ UartA_Ctrl1 |= SER_EVEN_PARITY;
+ else
+ UartA_Ctrl1 |= SER_ODD_PARITY;
+ }
+ if ((CFLAG & CSIZE)==CS6)
+ printk(KERN_ERR "6 bits not supported\n");
+ if ((CFLAG & CSIZE)==CS5)
+ printk(KERN_ERR "5 bits not supported\n");
+ if ((CFLAG & CSIZE)==CS7)
+ UartA_Ctrl1 |= SER_SEVEN_BIT;
+ if (C_CSTOPB(port->gs.tty))
+ UartA_Ctrl1 |= SER_TWO_STOP;
+
+ outl(t, port->base + TX3912_UART_CTRL2);
+ outl(0, port->base + TX3912_UART_DMA_CTRL1);
+ outl(0, port->base + TX3912_UART_DMA_CTRL2);
+ UartA_Ctrl1 |= TX3912_UART_CTRL1_UARTON;
+
+ /* wait until UARTA is stable */
+ while (~UartA_Ctrl1 & TX3912_UART_CTRL1_UARTON);
+ }
+
+ func_exit ();
+ return 0;
+}
+
+static int rs_chars_in_buffer (void * ptr)
+{
+ struct rs_port *port = ptr;
+ int scratch;
+
+ scratch = inl(port->base + TX3912_UART_CTRL1);
+
+ return ((scratch & UART_TX_EMPTY) ? 0 : 1);
+}
+
+/* ********************************************************************** *
+ * Here are the routines that actually *
+ * interface with the rest of the system *
+ * ********************************************************************** */
+static int rs_open (struct tty_struct * tty, struct file * filp)
+{
+ struct rs_port *port;
+ int retval, line;
+
+ func_enter();
+
+ if (!rs_initialized) {
+ return -EIO;
+ }
+
+ line = MINOR(tty->device) - tty->driver.minor_start;
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p)\n",
+ (int) current->pid, line, tty, current->tty);
+
+ if ((line < 0) || (line >= TX3912_UART_NPORTS))
+ return -ENODEV;
+
+ /* Pre-initialized already */
+ port = & rs_ports[line];
+
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "port = %p\n", port);
+
+ tty->driver_data = port;
+ port->gs.tty = tty;
+ port->gs.count++;
+
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "starting port\n");
+
+ /*
+ * Start up serial port
+ */
+ retval = gs_init_port(&port->gs);
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "done gs_init\n");
+ if (retval) {
+ port->gs.count--;
+ return retval;
+ }
+
+ port->gs.flags |= GS_ACTIVE;
+
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "before inc_use_count (count=%d.\n",
+ port->gs.count);
+ if (port->gs.count == 1) {
+ MOD_INC_USE_COUNT;
+ }
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "after inc_use_count\n");
+
+ /* Jim: Initialize port hardware here */
+
+ /* Enable high-priority interrupts for UARTA */
+ IntEnable6 |= INT6_UARTARXINT;
+ rs_enable_rx_interrupts(&rs_ports[0]);
+
+ retval = gs_block_til_ready(&port->gs, filp);
+ rs_dprintk (TX3912_UART_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n",
+ retval, port->gs.count);
+
+ if (retval) {
+ MOD_DEC_USE_COUNT;
+ port->gs.count--;
+ return retval;
+ }
+ /* tty->low_latency = 1; */
+
+ if ((port->gs.count == 1) && (port->gs.flags & ASYNC_SPLIT_TERMIOS)) {
+ if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+ *tty->termios = port->gs.normal_termios;
+ else
+ *tty->termios = port->gs.callout_termios;
+ rs_set_real_termios (port);
+ }
+
+ port->gs.session = current->session;
+ port->gs.pgrp = current->pgrp;
+ func_exit();
+
+ /* Jim */
+/* cli(); */
+
+ return 0;
+
+}
+
+
+
+static void rs_close (void *ptr)
+{
+ func_enter ();
+
+ /* Anything to do here? */
+
+ MOD_DEC_USE_COUNT;
+ func_exit ();
+}
+
+
+/* I haven't the foggiest why the decrement use count has to happen
+ here. The whole linux serial drivers stuff needs to be redesigned.
+ My guess is that this is a hack to minimize the impact of a bug
+ elsewhere. Thinking about it some more. (try it sometime) Try
+ running minicom on a serial port that is driven by a modularized
+ driver. Have the modem hangup. Then remove the driver module. Then
+ exit minicom. I expect an "oops". -- REW */
+static void rs_hungup (void *ptr)
+{
+ func_enter ();
+ MOD_DEC_USE_COUNT;
+ func_exit ();
+}
+
+static int rs_ioctl (struct tty_struct * tty, struct file * filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+ struct rs_port *port = tty->driver_data;
+ int ival;
+
+ rc = 0;
+ switch (cmd) {
+ case TIOCGSOFTCAR:
+ rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0),
+ (unsigned int *) arg);
+ break;
+ case TIOCSSOFTCAR:
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(int))) == 0) {
+ get_user(ival, (unsigned int *) arg);
+ tty->termios->c_cflag =
+ (tty->termios->c_cflag & ~CLOCAL) |
+ (ival ? CLOCAL : 0);
+ }
+ break;
+ case TIOCGSERIAL:
+ if ((rc = verify_area(VERIFY_WRITE, (void *) arg,
+ sizeof(struct serial_struct))) == 0)
+ gs_getserial(&port->gs, (struct serial_struct *) arg);
+ break;
+ case TIOCSSERIAL:
+ if ((rc = verify_area(VERIFY_READ, (void *) arg,
+ sizeof(struct serial_struct))) == 0)
+ rc = gs_setserial(&port->gs, (struct serial_struct *) arg);
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ break;
+ }
+
+ /* func_exit(); */
+ return rc;
+}
+
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct * tty, char ch)
+{
+ struct rs_port *port = (struct rs_port *)tty->driver_data;
+ func_enter ();
+
+ port->x_char = ch;
+ if (ch) {
+ /* Make sure transmit interrupts are on */
+ rs_enable_tx_interrupts(tty);
+ }
+
+ func_exit();
+}
+
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+#ifdef TX3912_UART_DEBUG_THROTTLE
+ char buf[64];
+
+ printk("throttle %s: %d....\n", tty_name(tty, buf),
+ tty->ldisc.chars_in_buffer(tty));
+#endif
+
+ func_enter ();
+
+ if (I_IXOFF(tty))
+ rs_send_xchar(tty, STOP_CHAR(tty));
+
+ func_exit ();
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+ struct rs_port *port = (struct rs_port *)tty->driver_data;
+#ifdef TX3912_UART_DEBUG_THROTTLE
+ char buf[64];
+
+ printk("unthrottle %s: %d....\n", tty_name(tty, buf),
+ tty->ldisc.chars_in_buffer(tty));
+#endif
+
+ func_enter();
+
+ if (I_IXOFF(tty)) {
+ if (port->x_char)
+ port->x_char = 0;
+ else
+ rs_send_xchar(tty, START_CHAR(tty));
+ }
+
+ func_exit();
+}
+
+
+
+
+
+/* ********************************************************************** *
+ * Here are the initialization routines. *
+ * ********************************************************************** */
+
+void * ckmalloc (int size)
+{
+ void *p;
+
+ p = kmalloc(size, GFP_KERNEL);
+ if (p)
+ memset(p, 0, size);
+ return p;
+}
+
+
+
+static int rs_init_portstructs(void)
+{
+ struct rs_port *port;
+ int i;
+
+ /* Debugging */
+ func_enter();
+
+ rs_ports = ckmalloc(TX3912_UART_NPORTS * sizeof (struct rs_port));
+ if (!rs_ports)
+ return -ENOMEM;
+
+ rs_termios = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
+ if (!rs_termios) {
+ kfree (rs_ports);
+ return -ENOMEM;
+ }
+
+ rs_termios_locked = ckmalloc(TX3912_UART_NPORTS * sizeof (struct termios *));
+ if (!rs_termios_locked) {
+ kfree (rs_ports);
+ kfree (rs_termios);
+ return -ENOMEM;
+ }
+
+ /* Adjust the values in the "driver" */
+ rs_driver.termios = rs_termios;
+ rs_driver.termios_locked = rs_termios_locked;
+
+ port = rs_ports;
+ for (i=0; i < TX3912_UART_NPORTS;i++) {
+ rs_dprintk (TX3912_UART_DEBUG_INIT, "initing port %d\n", i);
+ port->gs.callout_termios = tty_std_termios;
+ port->gs.normal_termios = tty_std_termios;
+ port->gs.magic = SERIAL_MAGIC;
+ port->gs.close_delay = HZ/2;
+ port->gs.closing_wait = 30 * HZ;
+ port->gs.rd = &rs_real_driver;
+#ifdef NEW_WRITE_LOCKING
+ port->gs.port_write_sem = MUTEX;
+#endif
+#ifdef DECLARE_WAITQUEUE
+ init_waitqueue_head(&port->gs.open_wait);
+ init_waitqueue_head(&port->gs.close_wait);
+#endif
+ port->base = (i == 0) ? TX3912_UARTA_BASE : TX3912_UARTB_BASE;
+ port->intshift = (i == 0) ? UARTA_SHIFT : UARTB_SHIFT;
+ rs_dprintk (TX3912_UART_DEBUG_INIT, "base 0x%08lx intshift %d\n",
+ port->base, port->intshift);
+ port++;
+ }
+
+ func_exit();
+ return 0;
+}
+
+static int rs_init_drivers(void)
+{
+ int error;
+
+ func_enter();
+
+ memset(&rs_driver, 0, sizeof(rs_driver));
+ rs_driver.magic = TTY_DRIVER_MAGIC;
+ rs_driver.driver_name = "serial";
+ rs_driver.name = "ttyS";
+ rs_driver.major = TTY_MAJOR;
+ rs_driver.minor_start = 64;
+ rs_driver.num = TX3912_UART_NPORTS;
+ rs_driver.type = TTY_DRIVER_TYPE_SERIAL;
+ rs_driver.subtype = SERIAL_TYPE_NORMAL;
+ rs_driver.init_termios = tty_std_termios;
+ rs_driver.init_termios.c_cflag =
+ B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+ rs_driver.refcount = &rs_refcount;
+ rs_driver.table = rs_table;
+ rs_driver.termios = rs_termios;
+ rs_driver.termios_locked = rs_termios_locked;
+
+ rs_driver.open = rs_open;
+ rs_driver.close = gs_close;
+ rs_driver.write = gs_write;
+ rs_driver.put_char = gs_put_char;
+ rs_driver.flush_chars = gs_flush_chars;
+ rs_driver.write_room = gs_write_room;
+ rs_driver.chars_in_buffer = gs_chars_in_buffer;
+ rs_driver.flush_buffer = gs_flush_buffer;
+ rs_driver.ioctl = rs_ioctl;
+ rs_driver.throttle = rs_throttle;
+ rs_driver.unthrottle = rs_unthrottle;
+ rs_driver.set_termios = gs_set_termios;
+ rs_driver.stop = gs_stop;
+ rs_driver.start = gs_start;
+ rs_driver.hangup = gs_hangup;
+
+ rs_callout_driver = rs_driver;
+ rs_callout_driver.name = "cua";
+ rs_callout_driver.major = TTYAUX_MAJOR;
+ rs_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+
+ if ((error = tty_register_driver(&rs_driver))) {
+ printk(KERN_ERR "Couldn't register serial driver, error = %d\n",
+ error);
+ return 1;
+ }
+ if ((error = tty_register_driver(&rs_callout_driver))) {
+ tty_unregister_driver(&rs_driver);
+ printk(KERN_ERR "Couldn't register callout driver, error = %d\n",
+ error);
+ return 1;
+ }
+
+ func_exit();
+ return 0;
+}
+
+
+void __init tx3912_rs_init(void)
+{
+ int rc;
+
+
+ func_enter();
+ rs_dprintk (TX3912_UART_DEBUG_INIT, "Initing serial module... (rs_debug=%d)\n", rs_debug);
+
+ rc = rs_init_portstructs ();
+ rs_init_drivers ();
+ if (request_irq(2, rs_tx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+ "serial", &rs_ports[0])) {
+ printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+ rc = 0;
+ }
+ if (request_irq(3, rs_rx_interrupt_uarta, SA_SHIRQ | SA_INTERRUPT,
+ "serial", &rs_ports[0])) {
+ printk(KERN_ERR "rs: Cannot allocate irq for UARTA.\n");
+ rc = 0;
+ }
+
+ IntEnable6 |= INT6_UARTARXINT;
+ rs_enable_rx_interrupts(&rs_ports[0]);
+
+#ifndef CONFIG_SERIAL_TX3912_CONSOLE
+{
+ unsigned int scratch = 0;
+
+ /* Setup master clock for UART */
+ scratch = inl(TX3912_CLK_CTRL_BASE);
+ scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+ scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+ TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+ | TX3912_CLK_CTRL_SIBMCLKDIR
+ | TX3912_CLK_CTRL_ENSIBMCLK
+ | TX3912_CLK_CTRL_CSERSEL;
+ outl(scratch, TX3912_CLK_CTRL_BASE);
+
+ /* Configure UARTA clock */
+ scratch = inl(TX3912_CLK_CTRL_BASE);
+ scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+ TX3912_CLK_CTRL_CSERDIV_MASK)
+ | TX3912_CLK_CTRL_ENCSERCLK
+ | TX3912_CLK_CTRL_ENUARTACLK;
+ outl(scratch, TX3912_CLK_CTRL_BASE);
+
+ /* Setup UARTA for 115200,8N1 */
+ outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+ outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+ outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+ outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+
+ /* Enable UARTA */
+ outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+ while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+ TX3912_UART_CTRL1_UARTON);
+}
+#endif
+
+ /* Note: I didn't do anything to enable the second UART */
+ if (rc >= 0)
+ rs_initialized++;
+
+ func_exit();
+}
+
+/*
+ * Begin serial console routines
+ */
+#ifdef CONFIG_SERIAL_TX3912_CONSOLE
+
+void serial_outc(unsigned char c)
+{
+ int i;
+ unsigned long int2;
+ #define BUSY_WAIT 10000
+
+ /*
+ * Turn UARTA interrupts off
+ */
+ int2 = IntEnable2;
+ IntEnable2 &=
+ ~(INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY);
+
+ /*
+ * The UART_TX_EMPTY bit in UartA_Ctrl1 seems
+ * not to be very reliable :-(
+ *
+ * Wait for the Tx register to become empty
+ */
+ for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+
+ IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+ UartA_Data = c;
+ for (i = 0; !(IntStatus2 & INT2_UARTATXINT) && (i < BUSY_WAIT); i++);
+ IntClear2 = INT2_UARTATXINT | INT2_UARTATXOVERRUN | INT2_UARTAEMPTY;
+
+ IntEnable2 = int2;
+}
+
+static int serial_console_wait_key(struct console *co)
+{
+ unsigned int int2, res;
+
+ int2 = IntEnable2;
+ IntEnable2 = 0;
+
+ while (!(UartA_Ctrl1 & UART_RX_HOLD_FULL));
+ res = UartA_Data;
+ udelay(10);
+
+ IntEnable2 = int2;
+ return res;
+}
+
+static void serial_console_write(struct console *co, const char *s,
+ unsigned count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; i++) {
+ if (*s == '\n')
+ serial_outc('\r');
+ serial_outc(*s++);
+ }
+}
+
+static kdev_t serial_console_device(struct console *c)
+{
+ return MKDEV(TTY_MAJOR, 64 + c->index);
+}
+
+static __init int serial_console_setup(struct console *co, char *options)
+{
+ unsigned int scratch = 0;
+
+ /* Setup master clock for UART */
+ scratch = inl(TX3912_CLK_CTRL_BASE);
+ scratch &= ~TX3912_CLK_CTRL_SIBMCLKDIV_MASK;
+ scratch |= ((0x2 << TX3912_CLK_CTRL_SIBMCLKDIV_SHIFT) &
+ TX3912_CLK_CTRL_SIBMCLKDIV_MASK)
+ | TX3912_CLK_CTRL_SIBMCLKDIR
+ | TX3912_CLK_CTRL_ENSIBMCLK
+ | TX3912_CLK_CTRL_CSERSEL;
+ outl(scratch, TX3912_CLK_CTRL_BASE);
+
+ /* Configure UARTA clock */
+ scratch = inl(TX3912_CLK_CTRL_BASE);
+ scratch |= ((0x3 << TX3912_CLK_CTRL_CSERDIV_SHIFT) &
+ TX3912_CLK_CTRL_CSERDIV_MASK)
+ | TX3912_CLK_CTRL_ENCSERCLK
+ | TX3912_CLK_CTRL_ENUARTACLK;
+ outl(scratch, TX3912_CLK_CTRL_BASE);
+
+ /* Setup UARTA for 115200,8N1 */
+ outl(0, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+ outl(TX3912_UART_CTRL2_B115200, TX3912_UARTA_BASE + TX3912_UART_CTRL2);
+ outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL1);
+ outl(0, TX3912_UARTA_BASE + TX3912_UART_DMA_CTRL2);
+
+ /* Enable UARTA */
+ outl(TX3912_UART_CTRL1_ENUART, TX3912_UARTA_BASE + TX3912_UART_CTRL1);
+ while (~inl(TX3912_UARTA_BASE + TX3912_UART_CTRL1) &
+ TX3912_UART_CTRL1_UARTON);
+
+ return 0;
+}
+
+static struct console sercons = {
+ name: "ttyS",
+ write: serial_console_write,
+ device: serial_console_device,
+ wait_key: serial_console_wait_key,
+ setup: serial_console_setup,
+ flags: CON_PRINTBUFFER,
+ index: -1
+};
+
+void __init tx3912_console_init(void)
+{
+ register_console(&sercons);
+}
+
+#endif
--- /dev/null
+/*
+ * drivers/char/serial_tx3912.h
+ *
+ * Copyright (C) 1999 Harald Koerfgen
+ * Copyright (C) 2000 Jim Pick <jim@jimpick.com>
+ * Copyright (C) 2001 Steven J. Hill (sjhill@realitydiluted.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Serial driver for TMPR3912/05 and PR31700 processors
+ */
+#include <linux/serialP.h>
+#include <linux/generic_serial.h>
+
+/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
+#define UART_RX_INT 9 /* receiver holding register full (31, 21) */
+#define UART_RXOVERRUN_INT 8 /* receiver overrun error (30, 20) */
+#define UART_FRAMEERR_INT 7 /* receiver frame error (29, 19) */
+#define UART_BREAK_INT 6 /* received break signal (28, 18) */
+#define UART_PARITYERR_INT 5 /* receiver parity error (27, 17) */
+#define UART_TX_INT 4 /* transmit holding register empty (26, 16) */
+#define UART_TXOVERRUN_INT 3 /* transmit overrun error (25, 15) */
+#define UART_EMPTY_INT 2 /* both trans/recv regs empty (24, 14) */
+#define UART_DMAFULL_INT 1 /* DMA at end of buffer (23, 13) */
+#define UART_DMAHALF_INT 0 /* DMA halfway through buffer */ (22, 12) */
+
+#define UARTA_SHIFT 22
+#define UARTB_SHIFT 12
+
+#define INTTYPE(interrupttype) (1 << interrupttype)
+
+/*
+ * This driver can spew a whole lot of debugging output at you. If you
+ * need maximum performance, you should disable the DEBUG define.
+ */
+#undef TX3912_UART_DEBUG
+
+#ifdef TX3912_UART_DEBUG
+#define TX3912_UART_DEBUG_OPEN 0x00000001
+#define TX3912_UART_DEBUG_SETTING 0x00000002
+#define TX3912_UART_DEBUG_FLOW 0x00000004
+#define TX3912_UART_DEBUG_MODEMSIGNALS 0x00000008
+#define TX3912_UART_DEBUG_TERMIOS 0x00000010
+#define TX3912_UART_DEBUG_TRANSMIT 0x00000020
+#define TX3912_UART_DEBUG_RECEIVE 0x00000040
+#define TX3912_UART_DEBUG_INTERRUPTS 0x00000080
+#define TX3912_UART_DEBUG_PROBE 0x00000100
+#define TX3912_UART_DEBUG_INIT 0x00000200
+#define TX3912_UART_DEBUG_CLEANUP 0x00000400
+#define TX3912_UART_DEBUG_CLOSE 0x00000800
+#define TX3912_UART_DEBUG_FIRMWARE 0x00001000
+#define TX3912_UART_DEBUG_MEMTEST 0x00002000
+#define TX3912_UART_DEBUG_THROTTLE 0x00004000
+#define TX3912_UART_DEBUG_ALL 0xffffffff
+
+int rs_debug = TX3912_UART_DEBUG_ALL & ~TX3912_UART_DEBUG_TRANSMIT;
+
+#define rs_dprintk(f, str...) if (rs_debug & f) printk (str)
+#define func_enter() rs_dprintk (TX3912_UART_DEBUG_FLOW, \
+ "rs: enter " __FUNCTION__ "\n")
+#define func_exit() rs_dprintk (TX3912_UART_DEBUG_FLOW, \
+ "rs: exit " __FUNCTION__ "\n")
+
+#else
+#define rs_dprintk(f, str...)
+#define func_enter()
+#define func_exit()
+
+#endif /* TX3912_UART_DEBUG */
+
+/*
+ * Number of serial ports
+ */
+#define TX3912_UART_NPORTS 2
+
+/*
+ * Hardware specific serial port structure
+ */
+struct rs_port {
+ struct gs_port gs; /* Must be first field! */
+
+ unsigned long base;
+ int intshift; /* Register shift */
+ struct wait_queue *shutdown_wait;
+ int stat_flags;
+ struct async_icount icount; /* Counters for 4 input IRQs */
+ int read_status_mask;
+ int ignore_status_mask;
+ int x_char; /* XON/XOFF character */
+};
fops: &softdog_fops,
};
-static const char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.05, timer margin: %d sec\n";
+static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.05, timer margin: %d sec\n";
static int __init watchdog_init(void)
{
MODULE_PARM(sx_debug, "i");
MODULE_PARM(sx_irqmask, "i");
+MODULE_LICENSE("GPL");
+
static struct real_driver sx_real_driver = {
sx_disable_tx_interrupts,
sx_enable_tx_interrupts,
sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n");
sx_write_channel_byte (port, hi_state, hi_state);
- gs_got_break (port);
+ gs_got_break (&port->gs);
}
if (hi_state & ST_DCD) {
hi_state &= ~ST_DCD;
#define R0 if (read_sx_word (board, i) != 0x55aa) return 1
#define R1 if (read_sx_word (board, i) != 0xaa55) return 1
+#if 0
/* This memtest takes a human-noticable time. You normally only do it
once a boot, so I guess that it is worth it. */
static int do_memtest_w (struct sx_board *board, int min, int max)
return 0;
}
+#endif
static int sx_fw_ioctl (struct inode *inode, struct file *filp,
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
-#include <linux/devfs_fs_kernel.h>
+#include <linux/devfs_fs_kernel.h>
#include <asm/dma.h>
#include <asm/system.h>
* card+drive info if runtime configuration has been selected.
*/
-static struct mtconfiginfo qic02_tape_dynconf = /* user settable */
- { 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, };
+static struct mtconfiginfo qic02_tape_dynconf = /* user settable */
+{ 0, 0, BOGUS_IRQ, 0, 0, TPQD_DEFAULT_FLAGS, };
static struct qic02_ccb qic02_tape_ccb; /* private stuff */
#else
# if ((QIC02_TAPE_IFC!=WANGTEK) && (QIC02_TAPE_IFC!=ARCHIVE) && (QIC02_TAPE_IFC!=MOUNTAIN))
# error No valid interface card specified
# endif
-#endif /* CONFIG_QIC02_DYNCONF */
+#endif /* CONFIG_QIC02_DYNCONF */
-static volatile int ctlbits; /* control reg bits for tape interface */
+static volatile int ctlbits; /* control reg bits for tape interface */
-static wait_queue_head_t qic02_tape_transfer; /* sync rw with interrupts */
+static wait_queue_head_t qic02_tape_transfer; /* sync rw with interrupts */
static volatile struct mtget ioctl_status; /* current generic status */
* by an interrupt.
*/
static volatile flag status_dead = YES; /* device is legally dead until proven alive */
-static flag status_zombie = YES; /* it's `zombie' until irq/dma allocated */
+static flag status_zombie = YES; /* it's `zombie' until irq/dma allocated */
static volatile flag status_bytes_wr = NO; /* write FM at close or not */
static volatile flag status_bytes_rd = NO; /* (rd|wr) used for rewinding */
-static volatile unsigned long status_cmd_pending; /* cmd in progress */
+static volatile unsigned long status_cmd_pending; /* cmd in progress */
static volatile flag status_expect_int = NO; /* ready for interrupts */
-static volatile flag status_timer_on = NO; /* using time-out */
-static volatile int status_error; /* int handler may detect error */
+static volatile flag status_timer_on = NO; /* using time-out */
+static volatile int status_error; /* int handler may detect error */
static volatile flag status_eof_detected = NO; /* end of file */
static volatile flag status_eom_detected = NO; /* end of recorded media */
static volatile flag status_eot_detected = NO; /* end of tape */
static volatile unsigned long dma_bytes_todo;
static volatile unsigned long dma_bytes_done;
-static volatile unsigned dma_mode; /* !=0 also means DMA in use */
-static flag need_rewind = YES;
+static volatile unsigned dma_mode; /* !=0 also means DMA in use */
+static flag need_rewind = YES;
static kdev_t current_tape_dev;
static int extra_blocks_left = BLOCKS_BEYOND_EW;
* mode is allowed as long as no actual writing has been done. After writing
* the File Mark, repositioning and reading are allowed again.
*/
-static int mode_access; /* access mode: READ or WRITE */
+static int mode_access; /* access mode: READ or WRITE */
static int qic02_get_resources(void);
static void qic02_release_resources(void);
* must ensure that a large enough buffer is passed to the kernel, in order
* to reduce tape repositioning wear and tear.
*/
-static void *buffaddr; /* virtual address of buffer */
+static void *buffaddr; /* virtual address of buffer */
/* This translates minor numbers to the corresponding recording format: */
static const char *format_names[] = {
- "not set", /* for dumb drives unable to handle format selection */
- "11", /* extinct */
+ "not set", /* for dumb drives unable to handle format selection */
+ "11", /* extinct */
"24",
"120",
"150",
- "300", /* untested. */
- "600" /* untested. */
+ "300", /* untested. */
+ "600" /* untested. */
};
const char *msg;
/* EXC_nr attribute should match with tpqic02.h */
} exception_list[] = {
- {0, 0,
- "Unknown exception status code", /* extra: 0 */},
- {~(0), TP_ST0|TP_CNI|TP_USL|TP_WRP,
- "Drive not online" /* 1 */},
- /* Drive presence goes before cartridge presence. */
- {~(TP_WRP|TP_USL), TP_ST0|TP_CNI,
- /* My Wangtek 5150EQ sometimes reports a status code
- * of 0x00e0, which is not a valid exception code, but
- * I think it should be recognized as "NO CARTRIDGE".
- */
- "Cartridge not in place" /* 2 */},
- {(unsigned short) ~(TP_ST1|TP_BOM), (TP_ST0|TP_WRP),
- "Write protected cartridge" /* 3 */},
- {(unsigned short) ~(TP_ST1|TP_EOR), (TP_ST0|TP_EOM),
- "End of media" /* 4 */},
- {~TP_WRP, TP_ST0|TP_UDA| TP_ST1|TP_BOM,
- "Read or Write abort. Rewind tape." /* 5 */},
- {~TP_WRP, TP_ST0|TP_UDA,
- "Read error. Bad block transferred." /* 6 */},
- {~TP_WRP, TP_ST0|TP_UDA|TP_BNL,
- "Read error. Filler block transferred." /* 7 */},
- {~TP_WRP, TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
- "Read error. No data detected." /* 8 */},
- {~TP_WRP, TP_ST0|TP_EOM|TP_UDA|TP_BNL |TP_ST1|TP_NDT,
- "Read error. No data detected. EOM." /* 9 */},
- {~(TP_WRP|TP_MBD|TP_PAR|TP_EOR), TP_ST0|TP_UDA|TP_BNL |TP_ST1|TP_NDT|TP_BOM,
- "Read error. No data detected. BOM." /* 10 */},
- {~(TP_WRP|TP_EOM), TP_ST0|TP_FIL,
- /* Status 0x0089 (EOM & FM) is viewed as an FM,
- * because it can only happen during a read.
- * EOM is checked separately for an FM condition.
- */
- "File mark detected" /* 11 */},
- {~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_ILL,
- "Illegal command" /* 12 */},
- {~(TP_ST0|TP_CNI|TP_USL|TP_WRP|TP_BOM), TP_ST1|TP_POR,
- "Reset occurred" /* 13 */},
- {~TP_WRP, TP_ST0|TP_FIL|TP_MBD, /* NOTE: ST1 not set! */
- "Marginal block detected" /* 14 */},
- {~(TP_ST0|TP_WRP|TP_EOM|TP_UDA|TP_BNL|TP_FIL |TP_NDT), TP_ST1|TP_EOR,
+ {
+ 0, 0, "Unknown exception status code", /* extra: 0 */ },
+ {
+ ~(0), TP_ST0 | TP_CNI | TP_USL | TP_WRP,
+ "Drive not online" /* 1 */ },
+ /* Drive presence goes before cartridge presence. */
+ {
+ ~(TP_WRP | TP_USL), TP_ST0 | TP_CNI,
+ /* My Wangtek 5150EQ sometimes reports a status code
+ * of 0x00e0, which is not a valid exception code, but
+ * I think it should be recognized as "NO CARTRIDGE".
+ */
+ "Cartridge not in place" /* 2 */ },
+ {
+ (unsigned short) ~(TP_ST1 | TP_BOM), (TP_ST0 | TP_WRP),
+ "Write protected cartridge" /* 3 */ },
+ {
+ (unsigned short) ~(TP_ST1 | TP_EOR), (TP_ST0 | TP_EOM),
+ "End of media" /* 4 */ },
+ {
+ ~TP_WRP, TP_ST0 | TP_UDA | TP_ST1 | TP_BOM,
+ "Read or Write abort. Rewind tape." /* 5 */ },
+ {
+ ~TP_WRP, TP_ST0 | TP_UDA,
+ "Read error. Bad block transferred." /* 6 */ },
+ {
+ ~TP_WRP, TP_ST0 | TP_UDA | TP_BNL,
+ "Read error. Filler block transferred." /* 7 */ },
+ {
+ ~TP_WRP, TP_ST0 | TP_UDA | TP_BNL | TP_ST1 | TP_NDT,
+ "Read error. No data detected." /* 8 */ },
+ {
+ ~TP_WRP,
+ TP_ST0 | TP_EOM | TP_UDA | TP_BNL | TP_ST1 |
+ TP_NDT, "Read error. No data detected. EOM." /* 9 */ },
+ {
+ ~(TP_WRP | TP_MBD | TP_PAR | TP_EOR),
+ TP_ST0 | TP_UDA | TP_BNL | TP_ST1 | TP_NDT |
+ TP_BOM,
+ "Read error. No data detected. BOM." /* 10 */ },
+ {
+ ~(TP_WRP | TP_EOM), TP_ST0 | TP_FIL,
+ /* Status 0x0089 (EOM & FM) is viewed as an FM,
+ * because it can only happen during a read.
+ * EOM is checked separately for an FM condition.
+ */
+ "File mark detected" /* 11 */ },
+ {
+ ~(TP_ST0 | TP_CNI | TP_USL | TP_WRP | TP_BOM),
+ TP_ST1 | TP_ILL, "Illegal command" /* 12 */ },
+ {
+ ~(TP_ST0 | TP_CNI | TP_USL | TP_WRP | TP_BOM),
+ TP_ST1 | TP_POR, "Reset occurred" /* 13 */ },
+ {
+ ~TP_WRP, TP_ST0 | TP_FIL | TP_MBD, /* NOTE: ST1 not set! */
+ "Marginal block detected" /* 14 */ },
+ {
+ ~(TP_ST0 | TP_WRP | TP_EOM | TP_UDA | TP_BNL | TP_FIL |
+ TP_NDT), TP_ST1 | TP_EOR,
/********** Is the extra TP_NDT really needed Eddy? **********/
- "End of recorded media" /* extra: 15 */},
- /* 15 is returned when SEEKEOD completes successfully */
- {~(TP_WRP|TP_ST0), TP_ST1|TP_BOM,
- "Beginning of media" /* extra: 16 */}
+ "End of recorded media" /* extra: 15 */ },
+ /* 15 is returned when SEEKEOD completes successfully */
+ {
+ ~(TP_WRP | TP_ST0), TP_ST1 | TP_BOM, "Beginning of media" /* extra: 16 */ }
};
+
#define NR_OF_EXC (sizeof(exception_list)/sizeof(struct exception_list_type))
/* Compare expected struct size and actual struct size. This
{
if ((flags & TPQD_ALWAYS) || (flags & QIC02_TAPE_DEBUG))
printk(TPQIC02_NAME ": %s\n", s);
-} /* tpqputs */
+} /* tpqputs */
/* Perform byte order swapping for a 16-bit word.
* [FIXME] This should probably be in include/asm/
* ([FIXME] i486 can do this faster)
*/
-static inline void byte_swap_w(volatile unsigned short * w)
+static inline void byte_swap_w(volatile unsigned short *w)
{
int t = *w;
-
- *w = (t>>8) | ((t & 0xff)<<8);
+ *w = (t >> 8) | ((t & 0xff) << 8);
}
*/
static void ifc_init(void)
{
- if (QIC02_TAPE_IFC == WANGTEK) /* || (QIC02_TAPE_IFC == EVEREX) */
- {
- ctlbits = WT_CTL_ONLINE; /* online */
- outb_p(ctlbits, QIC02_CTL_PORT);
- }
- else if (QIC02_TAPE_IFC == ARCHIVE)
- {
- ctlbits = 0; /* no interrupts yet */
- outb_p(ctlbits, QIC02_CTL_PORT);
- outb_p(0, AR_RESET_DMA_PORT); /* dummy write to reset DMA */
- }
- else /* MOUNTAIN */
- {
- ctlbits = MTN_CTL_ONLINE; /* online, and logic enabled */
- outb_p(ctlbits, QIC02_CTL_PORT);
- }
-} /* ifc_init */
+ if (QIC02_TAPE_IFC == WANGTEK) { /* || (QIC02_TAPE_IFC == EVEREX) */
+ ctlbits = WT_CTL_ONLINE; /* online */
+ outb_p(ctlbits, QIC02_CTL_PORT);
+ } else if (QIC02_TAPE_IFC == ARCHIVE) {
+ ctlbits = 0; /* no interrupts yet */
+ outb_p(ctlbits, QIC02_CTL_PORT);
+ outb_p(0, AR_RESET_DMA_PORT); /* dummy write to reset DMA */
+ } else { /* MOUNTAIN */
+
+ ctlbits = MTN_CTL_ONLINE; /* online, and logic enabled */
+ outb_p(ctlbits, QIC02_CTL_PORT);
+ }
+} /* ifc_init */
static void report_qic_exception(unsigned n)
{
- if (n >= NR_OF_EXC)
- {
- tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception");
- n = 0;
- }
- if (TPQDBG(SENSE_TEXT) || n==0)
- {
- printk(TPQIC02_NAME ": sense: %s\n", exception_list[n].msg);
- }
-} /* report_qic_exception */
+ if (n >= NR_OF_EXC) {
+ tpqputs(TPQD_ALWAYS, "Oops -- report_qic_exception");
+ n = 0;
+ }
+ if (TPQDBG(SENSE_TEXT) || n == 0) {
+ printk(TPQIC02_NAME ": sense: %s\n",
+ exception_list[n].msg);
+ }
+} /* report_qic_exception */
/* Try to map the drive-exception bits `s' to a predefined "exception number",
*/
static int decode_qic_exception_nr(unsigned s)
{
- int i;
+ int i;
- for (i=1; i<NR_OF_EXC; i++)
- {
- if ((s & exception_list[i].mask)==exception_list[i].code)
- {
- return i;
+ for (i = 1; i < NR_OF_EXC; i++) {
+ if ((s & exception_list[i].mask) == exception_list[i].code) {
+ return i;
+ }
}
- }
- printk(TPQIC02_NAME ": decode_qic_exception_nr: exception(%x) not recognized\n", s);
- return 0;
-} /* decode_qic_exception_nr */
+ printk(TPQIC02_NAME
+ ": decode_qic_exception_nr: exception(%x) not recognized\n",
+ s);
+ return 0;
+} /* decode_qic_exception_nr */
*/
static void handle_qic_exception(int exnr, int exbits)
{
- if (exnr==EXC_NCART)
- {
- /* Cartridge was changed. Redo sense().
- * EXC_NCART should be handled in open().
- * It is not permitted to remove the tape while
- * the tape driver has open files.
- */
- need_rewind = YES;
- status_eof_detected = NO;
- status_eom_detected = NO;
- }
- else if (exnr==EXC_XFILLER)
- {
- tpqputs(TPQD_ALWAYS, "[Bad block -- filler data transferred.]");
- }
- else if (exnr==EXC_XBAD)
- {
- tpqputs(TPQD_ALWAYS, "[CRC failed!]");
- }
- else if (exnr==EXC_MARGINAL)
- {
- /* A marginal block behaves much like a FM.
- * User may continue reading, if desired.
- */
- tpqputs(TPQD_ALWAYS, "[Marginal block]");
- doing_read = NO;
- }
- else if (exnr==EXC_FM)
- {
- doing_read = NO;
- }
-} /* handle_qic_exception */
+ if (exnr == EXC_NCART) {
+ /* Cartridge was changed. Redo sense().
+ * EXC_NCART should be handled in open().
+ * It is not permitted to remove the tape while
+ * the tape driver has open files.
+ */
+ need_rewind = YES;
+ status_eof_detected = NO;
+ status_eom_detected = NO;
+ } else if (exnr == EXC_XFILLER) {
+ tpqputs(TPQD_ALWAYS,
+ "[Bad block -- filler data transferred.]");
+ } else if (exnr == EXC_XBAD) {
+ tpqputs(TPQD_ALWAYS, "[CRC failed!]");
+ } else if (exnr == EXC_MARGINAL) {
+ /* A marginal block behaves much like a FM.
+ * User may continue reading, if desired.
+ */
+ tpqputs(TPQD_ALWAYS, "[Marginal block]");
+ doing_read = NO;
+ } else if (exnr == EXC_FM) {
+ doing_read = NO;
+ }
+} /* handle_qic_exception */
static inline int is_exception(void)
{
- return (inb(QIC02_STAT_PORT) & QIC02_STAT_EXCEPTION) == 0;
-} /* is_exception */
+ return (inb(QIC02_STAT_PORT) & QIC02_STAT_EXCEPTION) == 0;
+} /* is_exception */
/* Reset the tape drive and controller.
*/
static int tape_reset(int verbose)
{
- ifc_init(); /* reset interface card */
-
- /* assert reset */
- if (QIC02_TAPE_IFC == MOUNTAIN)
- {
- outb_p(ctlbits & ~MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
- }
- else /* WANGTEK, ARCHIVE */
- {
- outb_p(ctlbits | QIC02_CTL_RESET, QIC02_CTL_PORT);
- }
-
- /* Next, we need to wait >=25 usec. */
- udelay(30);
-
- /* after reset, we will be at BOT (modulo an automatic rewind) */
- status_eof_detected = NO;
- status_eom_detected = NO;
- status_cmd_pending = 0;
- need_rewind = YES;
- doing_read = doing_write = NO;
- ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
-
- /* de-assert reset */
- if (QIC02_TAPE_IFC == MOUNTAIN)
- {
- outb_p(ctlbits | MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
- }
- else
- {
- outb_p(ctlbits & ~QIC02_CTL_RESET, QIC02_CTL_PORT);
- }
-
- /* KLUDGE FOR G++ BUG */
- { int stat = inb_p(QIC02_STAT_PORT);
- status_dead = ((stat & QIC02_STAT_RESETMASK) != QIC02_STAT_RESETVAL); }
- /* if successful, inb(STAT) returned RESETVAL */
- if (status_dead == YES)
- {
- printk(TPQIC02_NAME ": reset failed!\n");
- }
- else if (verbose)
- {
- printk(TPQIC02_NAME ": reset successful\n");
- }
-
- return (status_dead == YES)? TE_DEAD : TE_OK;
-} /* tape_reset */
+ ifc_init(); /* reset interface card */
+
+ /* assert reset */
+ if (QIC02_TAPE_IFC == MOUNTAIN) {
+ outb_p(ctlbits & ~MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
+ } else { /* WANGTEK, ARCHIVE */
+
+ outb_p(ctlbits | QIC02_CTL_RESET, QIC02_CTL_PORT);
+ }
+
+ /* Next, we need to wait >=25 usec. */
+ udelay(30);
+
+ /* after reset, we will be at BOT (modulo an automatic rewind) */
+ status_eof_detected = NO;
+ status_eom_detected = NO;
+ status_cmd_pending = 0;
+ need_rewind = YES;
+ doing_read = doing_write = NO;
+ ioctl_status.mt_fileno = ioctl_status.mt_blkno = 0;
+
+ /* de-assert reset */
+ if (QIC02_TAPE_IFC == MOUNTAIN) {
+ outb_p(ctlbits | MTN_QIC02_CTL_RESET_NOT, QIC02_CTL_PORT);
+ } else {
+ outb_p(ctlbits & ~QIC02_CTL_RESET, QIC02_CTL_PORT);
+ }
+
+ /* KLUDGE FOR G++ BUG */
+ {
+ int stat = inb_p(QIC02_STAT_PORT);
+ status_dead =
+ ((stat & QIC02_STAT_RESETMASK) != QIC02_STAT_RESETVAL);
+ }
+ /* if successful, inb(STAT) returned RESETVAL */
+ if (status_dead == YES) {
+ printk(TPQIC02_NAME ": reset failed!\n");
+ } else if (verbose) {
+ printk(TPQIC02_NAME ": reset successful\n");
+ }
+
+ return (status_dead == YES) ? TE_DEAD : TE_OK;
+} /* tape_reset */
{
int i;
- outb_p(cmd, QIC02_CMD_PORT); /* output the command */
+ outb_p(cmd, QIC02_CMD_PORT); /* output the command */
/* wait 1 usec before asserting /REQUEST */
udelay(1);
if ((!ignore_ex) && is_exception()) {
tpqputs(TPQD_ALWAYS, "*** exception detected in notify_cmd");
/** force a reset here **/
- if (tape_reset(1)==TE_DEAD)
+ if (tape_reset(1) == TE_DEAD)
return TE_DEAD;
if (is_exception()) {
tpqputs(TPQD_ALWAYS, "exception persists after reset.");
}
}
- outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* set request bit */
+ outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* set request bit */
i = TAPE_NOTIFY_TIMEOUT;
/* The specs say this takes about 500 usec, but there is no upper limit!
* If the drive were busy retensioning or something like that,
* it could be *much* longer!
*/
- while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) && (--i>0))
- /*skip*/; /* wait for ready */
- if (i==0) {
- tpqputs(TPQD_ALWAYS, "timed out waiting for ready in notify_cmd");
+ while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) && (--i > 0))
+ /*skip */ ;
+ /* wait for ready */
+ if (i == 0) {
+ tpqputs(TPQD_ALWAYS,
+ "timed out waiting for ready in notify_cmd");
status_dead = YES;
return TE_TIM;
}
- outb_p(ctlbits & ~QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* reset request bit */
+ outb_p(ctlbits & ~QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* reset request bit */
i = TAPE_NOTIFY_TIMEOUT;
/* according to the specs this one should never time-out */
- while (((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) == 0) && (--i>0))
- /*skip*/; /* wait for not ready */
- if (i==0) {
+ while (((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) == 0) && (--i > 0))
+ /*skip */ ;
+ /* wait for not ready */
+ if (i == 0) {
tpqputs(TPQD_ALWAYS, "timed out waiting for !ready in notify_cmd");
status_dead = YES;
return TE_TIM;
}
/* command accepted */
return TE_OK;
-} /* notify_cmd */
+} /* notify_cmd */
* First, busy wait a few usec:
*/
spin_t = 50;
- while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (--spin_t>0))
+ while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && (--spin_t > 0))
/*SKIP*/;
if ((stat & QIC02_STAT_READY) == 0)
- return TE_OK; /* covers 99.99% of all calls */
+ return TE_OK; /* covers 99.99% of all calls */
/* Then use schedule() a few times */
- spin_t = 3; /* max 0.03 sec busy waiting */
+ spin_t = 3; /* max 0.03 sec busy waiting */
if (spin_t > timeout)
spin_t = timeout;
timeout -= spin_t;
spin_t += jiffies;
- while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t))
- schedule(); /* don't waste all the CPU time */
+ /* FIXME...*/
+ while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK)
+ && time_before(jiffies, spin_t))
+ schedule(); /* don't waste all the CPU time */
if ((stat & QIC02_STAT_READY) == 0)
return TE_OK;
spin_t += timeout;
TPQDEB({printk("wait_for_ready: additional timeout: %d\n", spin_t);})
- /* not ready and no exception && timeout not expired yet */
+ /* not ready and no exception && timeout not expired yet */
while (((stat = inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK) && time_before(jiffies, spin_t)) {
/* be `nice` to other processes on long operations... */
current->state = TASK_INTERRUPTIBLE;
/* nap 0.30 sec between checks, */
/* but could be woken up earlier by signals... */
- schedule_timeout(3*HZ/10);
+ schedule_timeout(3 * HZ / 10);
}
/* don't use jiffies for this test because it may have changed by now */
}
if ((stat & QIC02_STAT_EXCEPTION) == 0) {
- tpqputs(TPQD_ALWAYS, "exception detected after waiting_for_ready");
+ tpqputs(TPQD_ALWAYS,
+ "exception detected after waiting_for_ready");
return TE_EX;
} else {
return TE_OK;
}
-} /* wait_for_ready */
+} /* wait_for_ready */
{
int i, stat;
- for (i=0; i<size; i++) {
+ for (i = 0; i < size; i++) {
stat = wait_for_ready(TIM_S);
if (stat != TE_OK)
return stat;
}
return TE_OK;
-
-} /* send_qic02_data */
+
+} /* send_qic02_data */
/* Send a QIC-02 command (`cmd') to the tape drive, with
tpqputs(TPQD_ALWAYS, "send_qic02_cmd: Exception!");
return TE_EX;
}
- if (stat & QIC02_STAT_READY) { /* if not ready */
+ if (stat & QIC02_STAT_READY) { /* if not ready */
tpqputs(TPQD_ALWAYS, "send_qic02_cmd: not Ready!");
return TE_ERR;
}
*/
status_cmd_pending = cmd;
- stat = notify_cmd(cmd, ignore_ex); /* tell drive new command was loaded, */
- /* inherit exception check. */
+ stat = notify_cmd(cmd, ignore_ex); /* tell drive new command was loaded, */
+ /* inherit exception check. */
if (TP_HAVE_SEEK && (cmd == AR_QCMDV_SEEK_BLK)) {
/* This one needs to send 3 more bytes, MSB first */
stat = send_qic02_data(seek_addr_buf, sizeof(seek_addr_buf), ignore_ex);
tpqputs(TPQD_ALWAYS, "send_qic02_cmd failed");
}
return stat;
-} /* send_qic02_cmd */
+} /* send_qic02_cmd */
*/
static int rdstatus(char *stp, unsigned size, char qcmd)
{
- int s, n;
- char *q = stp;
+ int s, n;
+ char *q = stp;
/* Try to busy-wait a few (700) usec, after that de-schedule.
*
* de-schedule immediately, we waste a lot of time because a
* task switch is much longer than we usually have to wait here.
*/
- n = 1000; /* 500 is not enough on a 486/33 */
- while ((n>0) && ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK))
- n--; /* wait for ready or exception or timeout */
- if (n==0) {
+ n = 1000; /* 500 is not enough on a 486/33 */
+ while ((n > 0) && ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK))
+ n--; /* wait for ready or exception or timeout */
+ if (n == 0) {
/* n (above) should be chosen such that on your machine
* you rarely ever see the message below, and it should
* be small enough to give reasonable response time.]
*/
+ /* FIXME */
tpqputs(TPQD_ALWAYS, "waiting looong in rdstatus() -- drive dead?");
while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_MASK) == QIC02_STAT_MASK)
schedule();
tpqputs(TPQD_ALWAYS, "finished waiting in rdstatus()");
}
- (void) notify_cmd(qcmd, 1); /* send read status command */
+ (void) notify_cmd(qcmd, 1); /* send read status command */
/* ignore return code -- should always be ok, STAT may contain
* exception flag from previous exception which we are trying to clear.
*/
if (TP_DIAGS(current_tape_dev))
printk(TPQIC02_NAME ": reading status bytes: ");
- for (q=stp; q<stp+size; q++)
- {
- do s = inb_p(QIC02_STAT_PORT);
+ for (q = stp; q < stp + size; q++) {
+ do
+ s = inb_p(QIC02_STAT_PORT);
while ((s & QIC02_STAT_MASK) == QIC02_STAT_MASK); /* wait for ready or exception */
- if ((s & QIC02_STAT_EXCEPTION) == 0) { /* if exception */
+ if ((s & QIC02_STAT_EXCEPTION) == 0) { /* if exception */
tpqputs(TPQD_ALWAYS, "rdstatus: exception error");
- ioctl_status.mt_erreg = 0; /* dunno... */
- return TE_NS; /* error, shouldn't happen... */
+ ioctl_status.mt_erreg = 0; /* dunno... */
+ return TE_NS; /* error, shouldn't happen... */
}
- *q = inb_p(QIC02_DATA_PORT); /* read status byte */
+ *q = inb_p(QIC02_DATA_PORT); /* read status byte */
if (TP_DIAGS(current_tape_dev))
- printk("[%1d]=0x%x ", q-stp, (unsigned) (*q) & 0xff);
+ printk("[%1d]=0x%x ", q - stp,
+ (unsigned) (*q) & 0xff);
outb_p(ctlbits | QIC02_CTL_REQUEST, QIC02_CTL_PORT); /* set request */
* My drive doesn't seem to need it here yet, but others do?
*/
while (inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY)
- /*skip*/; /* wait for ready */
+ /*skip */ ;
+ /* wait for ready */
if (TP_DIAGS(current_tape_dev))
printk("\n");
return TE_OK;
-} /* rdstatus */
+} /* rdstatus */
/* should probably swap status bytes #definition */
#endif
return stat;
-} /* get_status */
+} /* get_status */
#if 0
*/
static int get_ext_status3(void)
{
- char vus[64]; /* vendor unique status */
+ char vus[64]; /* vendor unique status */
int stat, i;
tpqputs(TPQD_ALWAYS, "Attempting to read Extended Status 3...");
return stat;
tpqputs(TPQD_ALWAYS, "Returned status bytes:");
- for (i=0; i<sizeof(vus); i++) {
- if ( i % 8 == 0 )
+ for (i = 0; i < sizeof(vus); i++) {
+ if (i % 8 == 0)
printk("\n" TPQIC02_NAME ": %2d:");
printk(" %2x", vus[i] & 0xff);
}
printk("\n");
return TE_OK;
-} /* get_ext_status3 */
+} /* get_ext_status3 */
#endif
static void finish_rw(int cmd);
if (TPQDBG(SENSE_TEXT))
- printk(TPQIC02_NAME ": tp_sense(ignore=0x%x) enter\n", ignore);
+ printk(TPQIC02_NAME ": tp_sense(ignore=0x%x) enter\n",
+ ignore);
/* sense() is not allowed during a read or write cycle */
if (doing_write == YES)
tpqputs(TPQD_ALWAYS, "Warning: File Mark inserted because of sense() request");
/* The extra test is to avoid calling finish_rw during booting */
- if ((doing_read!=NO) || (doing_write!=NO))
+ if ((doing_read != NO) || (doing_write != NO))
finish_rw(QCMD_RD_STAT);
if (get_status(&tperror) != TE_OK) {
}
err = tperror.exs; /* get exception status bits */
- if (err & (TP_ST0|TP_ST1))
+ if (err & (TP_ST0 | TP_ST1))
printk(TPQIC02_NAME ": tp_sense: status: %x, error count: %d, underruns: %d\n",
- tperror.exs, tperror.dec, tperror.urc);
- else if ((tperror.dec!=0) || (tperror.urc!=0) || TPQDBG(SENSE_CNTS))
- printk(TPQIC02_NAME ": tp_sense: no hard errors, soft error count: %d, underruns: %d\n",
- tperror.dec, tperror.urc);
+ tperror.exs, tperror.dec, tperror.urc);
+ else if ((tperror.dec != 0) || (tperror.urc != 0)
+ || TPQDBG(SENSE_CNTS))
+ printk(TPQIC02_NAME
+ ": tp_sense: no hard errors, soft error count: %d, underruns: %d\n",
+ tperror.dec, tperror.urc);
/* Set generic status. HP-UX defines these, but some extra would
* be useful. Problem is to remain compatible. [Do we want to be
* compatible??]
*/
if (err & TP_ST0) {
- if (err & TP_CNI) /* no cartridge */
+ if (err & TP_CNI) /* no cartridge */
gs |= GMT_DR_OPEN(-1);
if (status_dead == NO)
gs |= GMT_ONLINE(-1); /* always online */
- if (err & TP_USL) /* not online */
+ if (err & TP_USL) /* not online */
gs &= ~GMT_ONLINE(-1);
if (err & TP_WRP)
gs |= GMT_WR_PROT(-1);
- if (err & TP_EOM) { /* end of media */
+ if (err & TP_EOM) { /* end of media */
gs |= GMT_EOT(-1); /* not sure this is correct for writes */
status_eom_detected = YES;
/* I don't know whether drive always reports EOF at or before EOM. */
ioctl_status.mt_dsreg = tperror.exs; /* "drive status" */
ioctl_status.mt_erreg = tperror.dec; /* "sense key error" */
- if (err & (TP_ST0|TP_ST1)) {
+ if (err & (TP_ST0 | TP_ST1)) {
/* My Wangtek occasionally reports `status' 1212 which should be ignored. */
exnr = decode_qic_exception_nr(err);
- handle_qic_exception(exnr, err); /* update driver state wrt drive status */
+ handle_qic_exception(exnr, err); /* update driver state wrt drive status */
report_qic_exception(exnr);
}
err &= ~ignore; /* mask unwanted errors -- not the correct way, use exception nrs?? */
((err & TP_ST1) && (err & REPORT_ERR1)))
return TE_ERR;
return TE_OK;
-} /* tp_sense */
+} /* tp_sense */
stat = inb(QIC02_STAT_PORT) & QIC02_STAT_MASK;
if (TPQDBG(REWIND))
- printk(TPQIC02_NAME ": Waiting for (re-)wind to finish: stat=0x%x\n", stat);
+ printk(TPQIC02_NAME
+ ": Waiting for (re-)wind to finish: stat=0x%x\n",
+ stat);
stat = wait_for_ready(timeout);
if (stat != TE_OK) {
- tpqputs(TPQD_ALWAYS, "(re-) winding failed\n");
+ tpqputs(TPQD_ALWAYS, "(re-) winding failed\n");
}
return stat;
-} /* wait_for_rewind */
+} /* wait_for_rewind */
if (status_dead == YES) {
tpqputs(TPQD_ALWAYS, "Drive is dead. Do a `mt reset`.");
- return -ENXIO; /* User should do an MTRESET. */
+ return -ENXIO; /* User should do an MTRESET. */
}
- stat = wait_for_ready(timeout); /* wait for ready or exception */
+ stat = wait_for_ready(timeout); /* wait for ready or exception */
if (stat == TE_EX) {
- if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK)
+ if (tp_sense(TP_WRP | TP_BOM | TP_EOM | TP_FIL) != TE_OK)
return -EIO;
/* else nothing to worry about, I hope */
stat = TE_OK;
}
if (stat != TE_OK) {
- printk(TPQIC02_NAME ": ll_do_qic_cmd(%x, %ld) failed\n", cmd, (long) timeout);
+ printk(TPQIC02_NAME ": ll_do_qic_cmd(%x, %ld) failed\n",
+ cmd, (long) timeout);
return -EIO;
}
-
-
#if OBSOLETE
/* wait for ready since it may not be active immediately after reading status */
while ((inb_p(QIC02_STAT_PORT) & QIC02_STAT_READY) != 0);
stat = send_qic02_cmd(cmd, timeout, 0); /* (checks for exceptions) */
- if (cmd==QCMD_RD_FM) {
+ if (cmd == QCMD_RD_FM) {
status_eof_detected = NO;
ioctl_status.mt_fileno++;
/* Should update block count as well, but can't.
* Can do a `read address' for some drives, when MTNOP is done.
*/
- } else if (cmd==QCMD_WRT_FM) {
+ } else if (cmd == QCMD_WRT_FM) {
status_eof_detected = NO;
ioctl_status.mt_fileno++;
- } else if ((cmd==QCMD_REWIND) || (cmd==QCMD_ERASE) || (cmd==QCMD_RETEN)) {
+ } else if ((cmd == QCMD_REWIND) || (cmd == QCMD_ERASE)
+ || (cmd == QCMD_RETEN)) {
status_eof_detected = NO;
status_eom_detected = NO;
status_eot_detected = NO;
reported_write_eof = NO;
}
/* sense() will set eof/eom as required */
- if (stat==TE_EX) {
- if (tp_sense(TP_WRP|TP_BOM|TP_EOM|TP_FIL)!=TE_OK) {
- printk(TPQIC02_NAME ": Exception persist in ll_do_qic_cmd[1](%x, %ld)", cmd, (long) timeout);
+ if (stat == TE_EX) {
+ if (tp_sense(TP_WRP | TP_BOM | TP_EOM | TP_FIL) != TE_OK) {
+ printk(TPQIC02_NAME
+ ": Exception persist in ll_do_qic_cmd[1](%x, %ld)",
+ cmd, (long) timeout);
status_dead = YES;
return -ENXIO;
/* if rdstatus fails too, we're in trouble */
}
- }
- else if (stat!=TE_OK) {
- printk(TPQIC02_NAME ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n", stat);
+ } else if (stat != TE_OK) {
+ printk(TPQIC02_NAME
+ ": ll_do_qic_cmd: send_qic02_cmd failed, stat = 0x%x\n",
+ stat);
return -EIO; /*** -EIO is probably not always appropriate */
}
else
stat = wait_for_ready(timeout);
- if (stat==TE_EX) {
- if (tp_sense((cmd==QCMD_SEEK_EOD ? /*****************************/
- TP_EOR|TP_NDT|TP_UDA|TP_BNL|TP_WRP|TP_BOM|TP_EOM|TP_FIL :
- TP_WRP|TP_BOM|TP_EOM|TP_FIL))!=TE_OK) {
- printk(TPQIC02_NAME ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n", cmd, (long) timeout);
- if (cmd!=QCMD_RD_FM)
+ if (stat == TE_EX) {
+ if (tp_sense((cmd == QCMD_SEEK_EOD ? /*****************************/
+ TP_EOR | TP_NDT | TP_UDA | TP_BNL | TP_WRP |
+ TP_BOM | TP_EOM | TP_FIL : TP_WRP | TP_BOM |
+ TP_EOM | TP_FIL)) != TE_OK) {
+ printk(TPQIC02_NAME
+ ": Exception persist in ll_do_qic_cmd[2](%x, %ld)\n",
+ cmd, (long) timeout);
+ if (cmd != QCMD_RD_FM)
status_dead = YES;
return -ENXIO;
/* if rdstatus fails too, we're in trouble */
}
- }
- else if (stat!=TE_OK) {
- printk(TPQIC02_NAME ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n", cmd, stat);
+ } else if (stat != TE_OK) {
+ printk(TPQIC02_NAME
+ ": ll_do_qic_cmd %x: wait failed, stat == 0x%x\n",
+ cmd, stat);
return -EIO;
}
return 0;
-} /* ll_do_qic_cmd */
+} /* ll_do_qic_cmd */
/*
/* Mountain reference says can terminate by de-asserting online */
ctlbits &= ~MTN_QIC02_CTL_ONLINE;
}
-
- if (tp_sense(TP_FIL|TP_EOM|TP_WRP) != TE_OK) {
- tpqputs(TPQD_ALWAYS, "finish_rw[read1]: ignore the 2 lines above");
+
+ if (tp_sense(TP_FIL | TP_EOM | TP_WRP) != TE_OK) {
+ tpqputs(TPQD_ALWAYS,
+ "finish_rw[read1]: ignore the 2 lines above");
if (is_exception()) {
- if (tp_sense(TP_ILL|TP_FIL|TP_EOM|TP_WRP) != TE_OK)
- tpqputs(TPQD_ALWAYS, "finish_rw[read2]: read cycle error");
+ if (tp_sense
+ (TP_ILL | TP_FIL | TP_EOM |
+ TP_WRP) != TE_OK)
+ tpqputs(TPQD_ALWAYS,"finish_rw[read2]: read cycle error");
}
}
}
}
-} /* terminate_read */
+} /* terminate_read */
static void terminate_write(int cmd)
/* finish off write cycle */
stat = ll_do_qic_cmd(QCMD_WRT_FM, TIM_M);
if (stat != TE_OK)
- tpqputs(TPQD_ALWAYS, "Couldn't finish write cycle properly");
+ tpqputs(TPQD_ALWAYS,
+ "Couldn't finish write cycle properly");
(void) tp_sense(0);
}
/* If there is an EOF token waiting to be returned to
* the (writing) application, discard it now.
* We could be at EOT, so don't reset return_write_eof.
*/
- reported_write_eof=YES;
+ reported_write_eof = YES;
}
-} /* terminate_write */
+} /* terminate_write */
/* terminate read or write cycle because of command `cmd' */
static void finish_rw(int cmd)
{
if (wait_for_ready(TIM_S) != TE_OK) {
- tpqputs(TPQD_ALWAYS, "error: drive not ready in finish_rw() !");
+ tpqputs(TPQD_ALWAYS,
+ "error: drive not ready in finish_rw() !");
return;
}
terminate_read(cmd);
terminate_write(cmd);
-} /* finish_rw */
+} /* finish_rw */
/* Perform a QIC command through ll_do_qic_cmd().
return stat;
}
need_rewind = NO;
- if (cmd==QCMD_REWIND) /* don't wind beyond BOT ;-) */
+ if (cmd == QCMD_REWIND) /* don't wind beyond BOT ;-) */
return 0;
}
return ll_do_qic_cmd(cmd, timeout);
-} /* do_qic_cmd */
+} /* do_qic_cmd */
/* Not all ioctls are supported for all drives. Some rely on
*/
switch (cmd) {
- case MTRESET:
- /* reset verbose */
- return (tape_reset(1)==TE_OK)? 0 : -EIO;
-
- case MTFSF:
- tpqputs(TPQD_IOCTLS, "MTFSF forward searching filemark");
- if ((mode_access==WRITE) && status_bytes_wr)
+ case MTRESET:
+ /* reset verbose */
+ return (tape_reset(1) == TE_OK) ? 0 : -EIO;
+
+ case MTFSF:
+ tpqputs(TPQD_IOCTLS, "MTFSF forward searching filemark");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ return do_qic_cmd(QCMD_RD_FM, TIM_F);
+
+ case MTBSF:
+ if (TP_HAVE_BSF) {
+ tpqputs(TPQD_IOCTLS,
+ "MTBSF backward searching filemark -- optional command");
+ if ((mode_access == WRITE) && status_bytes_wr)
return -EACCES;
- return do_qic_cmd(QCMD_RD_FM, TIM_F);
-
- case MTBSF:
- if (TP_HAVE_BSF) {
- tpqputs(TPQD_IOCTLS, "MTBSF backward searching filemark -- optional command");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
- } else {
- stat = -ENXIO;
- }
- status_eom_detected = status_eof_detected = NO;
- return stat;
-
- case MTFSR:
- if (TP_HAVE_FSR) { /* This is an optional QIC-02 command */
- tpqputs(TPQD_IOCTLS, "MTFSR forward space record");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
- } else {
- /**** fake it by doing a read data block command? ******/
- tpqputs(TPQD_IOCTLS, "MTFSR not supported");
- stat = -ENXIO;
- }
- return stat;
-
- case MTBSR:
- if (TP_HAVE_BSR) { /* This is an optional QIC-02 command */
- /* we need this for appending files with GNU tar!! */
- tpqputs(TPQD_IOCTLS, "MTFSR backward space record");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
- } else {
- tpqputs(TPQD_IOCTLS, "MTBSR not supported");
- stat = -ENXIO;
- }
- status_eom_detected = status_eof_detected = NO;
- return stat;
+ stat = do_qic_cmd(QCMD_RD_FM_BCK, TIM_F);
+ } else {
+ stat = -ENXIO;
+ }
+ status_eom_detected = status_eof_detected = NO;
+ return stat;
- case MTWEOF:
- tpqputs(TPQD_IOCTLS, "MTWEOF write eof mark");
- /* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */
- if (mode_access==READ)
+ case MTFSR:
+ if (TP_HAVE_FSR) { /* This is an optional QIC-02 command */
+ tpqputs(TPQD_IOCTLS, "MTFSR forward space record");
+ if ((mode_access == WRITE) && status_bytes_wr)
return -EACCES;
+ stat = do_qic_cmd(QCMD_SPACE_FWD, TIM_F);
+ } else {
+ /**** fake it by doing a read data block command? ******/
+ tpqputs(TPQD_IOCTLS, "MTFSR not supported");
+ stat = -ENXIO;
+ }
+ return stat;
- /* allow tape movement after writing FM */
- status_bytes_rd = status_bytes_wr; /* Kludge-O-Matic */
- status_bytes_wr = NO;
- return do_qic_cmd(QCMD_WRT_FM, TIM_M);
- /* not sure what to do with status_bytes when WFM should fail */
-
- case MTREW:
- tpqputs(TPQD_IOCTLS, "MTREW rewinding tape");
- if ((mode_access==WRITE) && status_bytes_wr)
+ case MTBSR:
+ if (TP_HAVE_BSR) { /* This is an optional QIC-02 command */
+ /* we need this for appending files with GNU tar!! */
+ tpqputs(TPQD_IOCTLS, "MTFSR backward space record");
+ if ((mode_access == WRITE) && status_bytes_wr)
return -EACCES;
- status_eom_detected = status_eof_detected = NO;
- return do_qic_cmd(QCMD_REWIND, TIM_R);
+ stat = do_qic_cmd(QCMD_SPACE_BCK, TIM_F);
+ } else {
+ tpqputs(TPQD_IOCTLS, "MTBSR not supported");
+ stat = -ENXIO;
+ }
+ status_eom_detected = status_eof_detected = NO;
+ return stat;
- case MTOFFL:
- tpqputs(TPQD_IOCTLS, "MTOFFL rewinding & going offline");
- /* Doing a drive select will clear (unlock) the current drive.
- * But that requires support for multiple drives and locking.
- */
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- status_eom_detected = status_eof_detected = NO;
+ case MTWEOF:
+ tpqputs(TPQD_IOCTLS, "MTWEOF write eof mark");
+ /* Plain GNU mt(1) 2.2 uses read-only mode for writing FM. :-( */
+ if (mode_access == READ)
+ return -EACCES;
+
+ /* allow tape movement after writing FM */
+ status_bytes_rd = status_bytes_wr; /* Kludge-O-Matic */
+ status_bytes_wr = NO;
+ return do_qic_cmd(QCMD_WRT_FM, TIM_M);
+ /* not sure what to do with status_bytes when WFM should fail */
+
+ case MTREW:
+ tpqputs(TPQD_IOCTLS, "MTREW rewinding tape");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ status_eom_detected = status_eof_detected = NO;
+ return do_qic_cmd(QCMD_REWIND, TIM_R);
+
+ case MTOFFL:
+ tpqputs(TPQD_IOCTLS, "MTOFFL rewinding & going offline");
+ /* Doing a drive select will clear (unlock) the current drive.
+ * But that requires support for multiple drives and locking.
+ */
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ status_eom_detected = status_eof_detected = NO;
/**** do rewind depending on minor bits??? ***/
- stat = do_qic_cmd(QCMD_REWIND, TIM_R);
- return stat;
+ stat = do_qic_cmd(QCMD_REWIND, TIM_R);
+ return stat;
- case MTNOP:
- tpqputs(TPQD_IOCTLS, "MTNOP setting status only");
+ case MTNOP:
+ tpqputs(TPQD_IOCTLS, "MTNOP setting status only");
/********** should do `read position' for drives that support it **********/
- return (tp_sense(-1)==TE_OK)? 0 : -EIO; /**** check return codes ****/
-
- case MTRETEN:
- tpqputs(TPQD_IOCTLS, "MTRETEN retension tape");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- status_eom_detected = status_eof_detected = NO;
- return do_qic_cmd(QCMD_RETEN, TIM_R);
-
- case MTBSFM:
- /* Think think is like MTBSF, except that
- * we shouldn't skip the FM. Tricky.
- * Maybe use RD_FM_BCK, then do a SPACE_FWD?
- */
- tpqputs(TPQD_IOCTLS, "MTBSFM not supported");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- return -ENXIO;
+ return (tp_sense(-1) == TE_OK) ? 0 : -EIO; /**** check return codes ****/
+
+ case MTRETEN:
+ tpqputs(TPQD_IOCTLS, "MTRETEN retension tape");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ status_eom_detected = status_eof_detected = NO;
+ return do_qic_cmd(QCMD_RETEN, TIM_R);
+
+ case MTBSFM:
+ /* Think think is like MTBSF, except that
+ * we shouldn't skip the FM. Tricky.
+ * Maybe use RD_FM_BCK, then do a SPACE_FWD?
+ */
+ tpqputs(TPQD_IOCTLS, "MTBSFM not supported");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ return -ENXIO;
- case MTFSFM:
- /* I think this is like MTFSF, except that
- * we shouldn't skip the FM. Tricky.
- * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?
- * But then the FM will have been skipped...
- * Maybe use RD_FM, then RD_FM_BCK, but not all
- * drives will support that!
- */
- tpqputs(TPQD_IOCTLS, "MTFSFM not supported");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- return -ENXIO;
+ case MTFSFM:
+ /* I think this is like MTFSF, except that
+ * we shouldn't skip the FM. Tricky.
+ * Maybe use QCMD_RD_DATA until we get a TP_FIL exception?
+ * But then the FM will have been skipped...
+ * Maybe use RD_FM, then RD_FM_BCK, but not all
+ * drives will support that!
+ */
+ tpqputs(TPQD_IOCTLS, "MTFSFM not supported");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ return -ENXIO;
- case MTEOM:
- /* This should leave the tape ready for appending
- * another file to the end, such that it would append
- * after the last FM on tape.
+ case MTEOM:
+ /* This should leave the tape ready for appending
+ * another file to the end, such that it would append
+ * after the last FM on tape.
+ */
+ tpqputs(TPQD_IOCTLS, "MTEOM search for End Of recorded Media");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ if (TP_HAVE_EOD) {
+ /* Use faster seeking when possible.
+ * This requires the absence of data beyond the EOM.
+ * It seems that my drive does not always perform the
+ * SEEK_EOD correctly, unless it is preceded by a
+ * rewind command.
*/
- tpqputs(TPQD_IOCTLS, "MTEOM search for End Of recorded Media");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- if (TP_HAVE_EOD) {
- /* Use faster seeking when possible.
- * This requires the absence of data beyond the EOM.
- * It seems that my drive does not always perform the
- * SEEK_EOD correctly, unless it is preceded by a
- * rewind command.
- */
# if 0
- status_eom_detected = status_eof_detected = NO;
+ status_eom_detected = status_eof_detected = NO;
# endif
- stat = do_qic_cmd(QCMD_REWIND, TIM_R);
- if (stat)
- return stat;
- stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
- /* After a successful seek, TP_EOR should be returned */
- } else {
- /* else just seek until the drive returns exception "No Data" */
- stat = 0;
- while ((stat==0) && (!status_eom_detected)) {
- stat = do_qic_cmd(QCMD_RD_FM, TIM_F); /***** should use MTFSFM here???? ******/
- }
- if (tperror.exs & TP_NDT)
- return 0;
+ stat = do_qic_cmd(QCMD_REWIND, TIM_R);
+ if (stat)
+ return stat;
+ stat = do_qic_cmd(QCMD_SEEK_EOD, TIM_F);
+ /* After a successful seek, TP_EOR should be returned */
+ } else {
+ /* else just seek until the drive returns exception "No Data" */
+ stat = 0;
+ while ((stat == 0) && (!status_eom_detected)) {
+ stat = do_qic_cmd(QCMD_RD_FM, TIM_F); /***** should use MTFSFM here???? ******/
}
- return stat;
-
- case MTERASE:
- tpqputs(TPQD_IOCTLS, "MTERASE -- ERASE TAPE !");
- if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
- tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
- return -EACCES;
- } else {
- time_t t = jiffies;
+ if (tperror.exs & TP_NDT)
+ return 0;
+ }
+ return stat;
- /* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
- if (mode_access==READ)
- return -EACCES;
+ case MTERASE:
+ tpqputs(TPQD_IOCTLS, "MTERASE -- ERASE TAPE !");
+ if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
+ tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
+ return -EACCES;
+ } else {
+ time_t t = jiffies;
- /* give user a few seconds to pull out tape */
- while (jiffies - t < 4*HZ)
- schedule();
- }
+ /* Plain GNU mt(1) 2.2 erases a tape in O_RDONLY. :-( */
+ if (mode_access == READ)
+ return -EACCES;
- /* don't bother writing filemark first */
- status_eom_detected = status_eof_detected = NO;
- return do_qic_cmd(QCMD_ERASE, TIM_R);
-
- case MTRAS1:
- if (TP_HAVE_RAS1) {
- tpqputs(TPQD_IOCTLS, "MTRAS1: non-destructive self test");
- stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
- if (stat != 0) {
- tpqputs(TPQD_ALWAYS, "RAS1 failed");
- return stat;
- }
- return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */
- }
- tpqputs(TPQD_IOCTLS, "RAS1 not supported");
- return -ENXIO;
+ /* FIXME */
+ /* give user a few seconds to pull out tape */
+ while (jiffies - t < 4 * HZ)
+ schedule();
+ }
- case MTRAS2:
- if (TP_HAVE_RAS2) {
- tpqputs(TPQD_IOCTLS, "MTRAS2: destructive self test");
- stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
- if (stat != 0) {
- tpqputs(TPQD_ALWAYS, "RAS2 failed");
- return stat;
- }
- return (tp_sense(0)==TE_OK)? 0 : -EIO; /* get_ext_status3(); */
+ /* don't bother writing filemark first */
+ status_eom_detected = status_eof_detected = NO;
+ return do_qic_cmd(QCMD_ERASE, TIM_R);
+
+ case MTRAS1:
+ if (TP_HAVE_RAS1) {
+ tpqputs(TPQD_IOCTLS, "MTRAS1: non-destructive self test");
+ stat = do_qic_cmd(QCMD_SELF_TST1, TIM_R);
+ if (stat != 0) {
+ tpqputs(TPQD_ALWAYS, "RAS1 failed");
+ return stat;
}
- tpqputs(TPQD_IOCTLS, "RAS2 not supported");
- return -ENXIO;
+ return (tp_sense(0) == TE_OK) ? 0 : -EIO; /* get_ext_status3(); */
+ }
+ tpqputs(TPQD_IOCTLS, "RAS1 not supported");
+ return -ENXIO;
- case MTSEEK:
- if (TP_HAVE_SEEK && (QIC02_TAPE_IFC==ARCHIVE)) {
- tpqputs(TPQD_IOCTLS, "MTSEEK seeking block");
- if ((mode_access==WRITE) && status_bytes_wr)
- return -EACCES;
- /* NOTE: address (24 bits) is in seek_addr_buf[] */
- return do_qic_cmd(AR_QCMDV_SEEK_BLK, TIM_F);
+ case MTRAS2:
+ if (TP_HAVE_RAS2) {
+ tpqputs(TPQD_IOCTLS, "MTRAS2: destructive self test");
+ stat = do_qic_cmd(QCMD_SELF_TST2, TIM_R);
+ if (stat != 0) {
+ tpqputs(TPQD_ALWAYS, "RAS2 failed");
+ return stat;
}
- else
- return -ENOTTY;
+ return (tp_sense(0) == TE_OK) ? 0 : -EIO; /* get_ext_status3(); */
+ }
+ tpqputs(TPQD_IOCTLS, "RAS2 not supported");
+ return -ENXIO;
- default:
+ case MTSEEK:
+ if (TP_HAVE_SEEK && (QIC02_TAPE_IFC == ARCHIVE)) {
+ tpqputs(TPQD_IOCTLS, "MTSEEK seeking block");
+ if ((mode_access == WRITE) && status_bytes_wr)
+ return -EACCES;
+ /* NOTE: address (24 bits) is in seek_addr_buf[] */
+ return do_qic_cmd(AR_QCMDV_SEEK_BLK, TIM_F);
+ } else
return -ENOTTY;
+
+ default:
+ return -ENOTTY;
}
-} /* do_ioctl_cmd */
+} /* do_ioctl_cmd */
/* dma_transfer(): This routine is called for every 512 bytes to be read
* - adjust the timeout
* - tell the tape controller to start transferring
* We assume the dma address and mode are, and remain, valid.
- */
+ */
static inline void dma_transfer(void)
{
unsigned long flags;
- if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+ if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT); /* back to normal */
else if (QIC02_TAPE_IFC == ARCHIVE)
outb_p(0, AR_RESET_DMA_PORT);
- else /* QIC02_TAPE_IFC == MOUNTAIN */
+ else /* QIC02_TAPE_IFC == MOUNTAIN */
outb_p(ctlbits, QIC02_CTL_PORT);
- flags=claim_dma_lock();
+ flags = claim_dma_lock();
clear_dma_ff(QIC02_TAPE_DMA);
set_dma_mode(QIC02_TAPE_DMA, dma_mode);
- set_dma_addr(QIC02_TAPE_DMA, virt_to_bus(buffaddr) + dma_bytes_done);
+ set_dma_addr(QIC02_TAPE_DMA,
+ virt_to_bus(buffaddr) + dma_bytes_done);
set_dma_count(QIC02_TAPE_DMA, TAPE_BLKSIZE);
/* start tape DMA controller */
- if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
- outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC02_CTL_PORT); /* trigger DMA transfer */
+ if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+ outb_p(WT_CTL_DMA | WT_CTL_ONLINE, QIC02_CTL_PORT); /* trigger DMA transfer */
else if (QIC02_TAPE_IFC == ARCHIVE) {
- outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC02_CTL_PORT); /* enable interrupts again */
- outb_p(0, AR_START_DMA_PORT); /* start DMA transfer */
+ outb_p(AR_CTL_IEN | AR_CTL_DNIEN, QIC02_CTL_PORT); /* enable interrupts again */
+ outb_p(0, AR_START_DMA_PORT); /* start DMA transfer */
/* In dma_end() AR_RESET_DMA_PORT is written too. */
- } else /* QIC02_TAPE_IFC == MOUNTAIN */ {
+ } else { /* QIC02_TAPE_IFC == MOUNTAIN */
+
inb(MTN_R_DESELECT_DMA_PORT);
- outb_p(ctlbits | (MTN_CTL_EXC_IEN | MTN_CTL_DNIEN), QIC02_CTL_PORT);
- outb_p(0, MTN_W_SELECT_DMA_PORT); /* start DMA transfer */
+ outb_p(ctlbits | (MTN_CTL_EXC_IEN | MTN_CTL_DNIEN),
+ QIC02_CTL_PORT);
+ outb_p(0, MTN_W_SELECT_DMA_PORT); /* start DMA transfer */
if (dma_mode == DMA_MODE_WRITE)
- outb_p(0, MTN_W_DMA_WRITE_PORT); /* start DMA transfer */
+ outb_p(0, MTN_W_DMA_WRITE_PORT); /* start DMA transfer */
}
/* start computer DMA controller */
/* block transfer should start now, jumping to the
* interrupt routine when done or an exception was detected.
*/
-} /* dma_transfer */
+} /* dma_transfer */
/* start_dma() sets a DMA transfer up between the tape controller and
{
int stat;
unsigned long flags;
-
+
tpqputs(TPQD_DEBUG, "start_dma() enter");
- TPQDEB({printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n", doing_read, doing_write);})
+ TPQDEB( {printk(TPQIC02_NAME ": doing_read==%d, doing_write==%d\n",
+ doing_read, doing_write);})
- dma_bytes_done = 0;
+ dma_bytes_done = 0;
dma_bytes_todo = bytes_todo;
status_error = NO;
/* dma_mode!=0 indicates that the dma controller is in use */
- dma_mode = (mode == WRITE)? DMA_MODE_WRITE : DMA_MODE_READ;
+ dma_mode = (mode == WRITE) ? DMA_MODE_WRITE : DMA_MODE_READ;
/* Only give READ/WRITE DATA command to tape drive if we haven't
* done that already. Otherwise the drive will rewind to the beginning
#if 0
/* Next dummy get status is to make sure CNI is valid,
- since we're only just starting a read/write it doesn't
- matter some exceptions are cleared by reading the status;
- we're only interested in CNI and WRP. -Eddy */
+ since we're only just starting a read/write it doesn't
+ matter some exceptions are cleared by reading the status;
+ we're only interested in CNI and WRP. -Eddy */
get_status(&tperror);
#else
/* TP_CNI should now be handled in open(). -Hennus */
#endif
- stat = tp_sense(((mode == WRITE)? 0 : TP_WRP) | TP_BOM | TP_FIL);
+ stat =
+ tp_sense(((mode ==
+ WRITE) ? 0 : TP_WRP) | TP_BOM | TP_FIL);
if (stat != TE_OK)
return stat;
#if OBSOLETE
/************* not needed iff rd_status() would wait for ready!!!!!! **********/
if (wait_for_ready(TIM_S) != TE_OK) { /*** not sure this is needed ***/
- tpqputs(TPQD_ALWAYS, "wait_for_ready failed in start_dma");
+ tpqputs(TPQD_ALWAYS,
+ "wait_for_ready failed in start_dma");
return -EIO;
}
#endif
/* Tell the controller the data direction */
/* r/w, timeout medium, check exceptions, sets status_cmd_pending. */
- stat = send_qic02_cmd((mode == WRITE)? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
- if (stat!=TE_OK) {
+ stat = send_qic02_cmd((mode == WRITE)
+ ? QCMD_WRT_DATA : QCMD_RD_DATA, TIM_M, 0);
+ if (stat != TE_OK) {
printk(TPQIC02_NAME ": start_dma: init %s failed\n",
- (mode == WRITE)? "write" : "read");
+ (mode == WRITE) ? "write" : "read");
(void) tp_sense(0);
return stat;
}
if (wait_for_ready(TIM_M) != TE_OK)
return -EIO;
switch (mode) {
- case READ:
- doing_read = YES;
- break;
- case WRITE:
- doing_write = YES;
- break;
- default:
- printk(TPQIC02_NAME ": requested unknown mode %d\n", mode);
- panic(TPQIC02_NAME ": invalid mode in start_dma()");
+ case READ:
+ doing_read = YES;
+ break;
+ case WRITE:
+ doing_write = YES;
+ break;
+ default:
+ printk(TPQIC02_NAME
+ ": requested unknown mode %d\n", mode);
+ panic(TPQIC02_NAME
+ ": invalid mode in start_dma()");
}
} else if (is_exception()) {
*
* ******** this also affects EOF/EOT handling! ************
*/
- tpqputs(TPQD_ALWAYS, "detected exception in start_dma() while transfer in progress");
+ tpqputs(TPQD_ALWAYS,
+ "detected exception in start_dma() while transfer in progress");
status_error = YES;
return TE_END;
}
/* This assumes tape is already positioned, but these
* semi-'intelligent' drives are unpredictable...
*/
- TIMERON(TIM_M*2);
+ TIMERON(TIM_M * 2);
/* initiate first data block read from/write to the tape controller */
TPQPUTS("start_dma() end");
return TE_OK;
-} /* start_dma */
+} /* start_dma */
/* This cleans up after the dma transfer has completed
* sense() will set `status_eof_detected' and
* `status_eom_detected', as required.
*/
-static void end_dma(unsigned long * bytes_done)
+static void end_dma(unsigned long *bytes_done)
{
int stat = TE_OK;
unsigned long flags;
TPQPUTS("end_dma() enter");
- flags=claim_dma_lock();
-
+ flags = claim_dma_lock();
+
disable_dma(QIC02_TAPE_DMA);
clear_dma_ff(QIC02_TAPE_DMA);
-
+
release_dma_lock(flags);
- if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
+ if (QIC02_TAPE_IFC == WANGTEK) /* or EVEREX */
outb_p(WT_CTL_ONLINE, QIC02_CTL_PORT); /* back to normal */
else if (QIC02_TAPE_IFC == ARCHIVE)
outb_p(0, AR_RESET_DMA_PORT);
- else /* QIC02_TAPE_IFC == MOUNTAIN */ {
+ else { /* QIC02_TAPE_IFC == MOUNTAIN */
+
/* Clear control bits, de-select ONLINE during tp_sense */
ctlbits &= ~MTN_QIC02_CTL_ONLINE;
}
stat = wait_for_ready(TIM_M);
- if (status_error || (stat!=TE_OK)) {
+ if (status_error || (stat != TE_OK)) {
tpqputs(TPQD_DMAX, "DMA transfer exception");
- stat = tp_sense((dma_mode==READ)? TP_WRP : 0);
+ stat = tp_sense((dma_mode == READ) ? TP_WRP : 0);
/* no return here -- got to clean up first! */
- } else /* if (QIC02_TAPE_IFC == MOUNTAIN) */ {
+ } else { /* if (QIC02_TAPE_IFC == MOUNTAIN) */
+
outb_p(ctlbits, QIC02_CTL_PORT);
}
if (QIC02_TAPE_IFC == MOUNTAIN)
inb(MTN_R_DESELECT_DMA_PORT);
- /* take the tape controller offline */
+ /* take the tape controller offline */
/* finish off DMA stuff */
TPQPUTS("end_dma() exit");
/*** could return stat here ***/
-} /* end_dma */
+} /* end_dma */
/*********** Below are the (public) OS-interface procedures ***********/
static void qic02_tape_times_out(unsigned long dummy)
{
printk("time-out in %s driver\n", TPQIC02_NAME);
- if ((status_cmd_pending>0) || dma_mode) {
+ if ((status_cmd_pending > 0) || dma_mode) {
/* takes tooo long, shut it down */
status_dead = YES;
status_cmd_pending = 0;
wake_up(&qic02_tape_transfer);
}
}
-} /* qic02_tape_times_out */
+} /* qic02_tape_times_out */
/*
* Interrupt handling:
* When we are finished, set flags to indicate end, disable timer.
* NOTE: This *must* be fast!
*/
-static void qic02_tape_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void qic02_tape_interrupt(int irq, void *dev_id,
+ struct pt_regs *regs)
{
int stat, r, i;
unsigned long flags;
stat = inb(QIC02_STAT_PORT); /* Knock, knock */
if (QIC02_TAPE_IFC == ARCHIVE) { /* "Who's there?" */
if (((stat & (AR_STAT_DMADONE)) == 0) &&
- ((stat & (QIC02_STAT_EXCEPTION)) != 0)) {
+ ((stat & (QIC02_STAT_EXCEPTION)) != 0)) {
TIMERCONT;
- return; /* "Linux with IRQ sharing" */
+ return; /* "Linux with IRQ sharing" */
}
}
if ((stat & QIC02_STAT_EXCEPTION) == 0) { /* exception occurred */
/* Possible causes for an exception during a transfer:
- * - during a write-cycle: end of tape (EW) hole detected.
- * - during a read-cycle: filemark or EOD detected.
- * - something went wrong
+ * - during a write-cycle: end of tape (EW) hole detected.
+ * - during a read-cycle: filemark or EOD detected.
+ * - something went wrong
* So don't continue with the next block.
*/
- tpqputs(TPQD_ALWAYS, "isr: exception on tape controller");
+ tpqputs(TPQD_ALWAYS,
+ "isr: exception on tape controller");
printk(" status %02x\n", stat);
status_error = TE_EX;
*/
r = 0;
- /* Skip next ready check for Archive controller because
- * it may be busy reading ahead. Weird. --hhb
- */
+ /* Skip next ready check for Archive controller because
+ * it may be busy reading ahead. Weird. --hhb
+ */
if (QIC02_TAPE_IFC == WANGTEK) /* I think this is a drive-dependency, not IFC -- hhb */
- if (stat & QIC02_STAT_READY) { /* not ready */
- tpqputs(TPQD_ALWAYS, "isr: ? Tape controller not ready");
+ if (stat & QIC02_STAT_READY) { /* not ready */
+ tpqputs(TPQD_ALWAYS,
+ "isr: ? Tape controller not ready");
r = 1;
}
- flags=claim_dma_lock();
-
- if ( (i = get_dma_residue(QIC02_TAPE_DMA)) != 0 ) {
- printk(TPQIC02_NAME ": dma_residue == %x !!!\n", i);
+ flags = claim_dma_lock();
+
+ if ((i = get_dma_residue(QIC02_TAPE_DMA)) != 0) {
+ printk(TPQIC02_NAME ": dma_residue == %x !!!\n",
+ i);
r = 1; /* big trouble, but can't do much about it... */
}
-
+
release_dma_lock(flags);
- if (r)
+ if (r)
return;
/* finish DMA cycle */
wake_up(&qic02_tape_transfer);
} else {
/* start next transfer, account for track-switching time */
- mod_timer(&tp_timer, jiffies + 6*HZ);
+ mod_timer(&tp_timer, jiffies + 6 * HZ);
dma_transfer();
}
} else {
printk(TPQIC02_NAME ": Unexpected interrupt, stat == %x\n",
inb(QIC02_STAT_PORT));
}
-} /* qic02_tape_interrupt */
+} /* qic02_tape_interrupt */
/* read/write routines:
* request would return the EOF flag for the previous file.
*/
-static ssize_t qic02_tape_read(struct file * filp, char * buf, size_t count, loff_t *ppos)
+static ssize_t qic02_tape_read(struct file *filp, char *buf, size_t count,
+ loff_t * ppos)
{
- int err;
- kdev_t dev = filp->f_dentry->d_inode->i_rdev;
- unsigned short flags = filp->f_flags;
- unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
- int stat;
-
- if (status_zombie==YES)
- {
- tpqputs(TPQD_ALWAYS, "configs not set");
- return -ENXIO;
- }
-
- if (TP_DIAGS(current_tape_dev))
- /* can't print a ``long long'' (for filp->f_pos), so chop it */
- printk(TPQIC02_NAME ": request READ, minor=%x, buf=%p, count=%lx"
- ", pos=%lx, flags=%x\n",
- MINOR(dev), buf, (long) count,
- (unsigned long) filp->f_pos, flags);
-
- if (count % TAPE_BLKSIZE) /* Only allow mod 512 bytes at a time. */
- {
- tpqputs(TPQD_BLKSZ, "Wrong block size");
- return -EINVAL;
- }
-
- /* Just assume everything is ok. Controller will scream if not. */
-
- if (status_bytes_wr) /* Once written, no more reads, 'till after WFM. */
- {
- return -EACCES;
- }
-
- /* This is rather ugly because it has to implement a finite state
- * machine in order to handle the EOF situations properly.
- */
- while ((signed)count>=0)
- {
- bytes_done = 0;
- /* see how much fits in the kernel buffer */
- bytes_todo = TPQBUF_SIZE;
- if (bytes_todo>count)
- {
- bytes_todo = count;
+ int err;
+ kdev_t dev = filp->f_dentry->d_inode->i_rdev;
+ unsigned short flags = filp->f_flags;
+ unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
+ int stat;
+
+ if (status_zombie == YES) {
+ tpqputs(TPQD_ALWAYS, "configs not set");
+ return -ENXIO;
}
-
- /* Must ensure that user program sees exactly one EOF token (==0) */
- if (return_read_eof==YES)
- {
- if (TPQDBG(DEBUG))
- {
- printk("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%lu\n", return_read_eof, reported_read_eof, total_bytes_done);
- }
-
- if (reported_read_eof==NO)
- {
- /* have not yet returned EOF to user program */
- if (total_bytes_done>0)
- {
- return total_bytes_done; /* next time return EOF */
- }
- else
- {
- reported_read_eof = YES; /* move on next time */
- return 0; /* return EOF */
- }
- }
- else
- {
- /* Application program has already received EOF
- * (above), now continue with next file on tape,
- * if possible.
- * When the FM is reached, EXCEPTION is set,
- * causing a sense(). Subsequent read/writes will
- * continue after the FM.
- */
- /*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/
- if (status_eom_detected)
- {
- /* If EOM, nothing left to read, so keep returning EOFs.
- *** should probably set some flag to avoid clearing
- *** status_eom_detected through ioctls or something
- */
- return 0;
+
+ if (TP_DIAGS(current_tape_dev))
+ /* can't print a ``long long'' (for filp->f_pos), so chop it */
+ printk(TPQIC02_NAME
+ ": request READ, minor=%x, buf=%p, count=%lx"
+ ", pos=%lx, flags=%x\n", MINOR(dev), buf,
+ (long) count, (unsigned long) filp->f_pos, flags);
+
+ if (count % TAPE_BLKSIZE) { /* Only allow mod 512 bytes at a time. */
+ tpqputs(TPQD_BLKSZ, "Wrong block size");
+ return -EINVAL;
+ }
+
+ /* Just assume everything is ok. Controller will scream if not. */
+
+ if (status_bytes_wr) { /* Once written, no more reads, 'till after WFM. */
+ return -EACCES;
+ }
+
+ /* This is rather ugly because it has to implement a finite state
+ * machine in order to handle the EOF situations properly.
+ */
+ while ((signed) count >= 0) {
+ bytes_done = 0;
+ /* see how much fits in the kernel buffer */
+ bytes_todo = TPQBUF_SIZE;
+ if (bytes_todo > count) {
+ bytes_todo = count;
}
- else
- {
- /* just eof, there may be more files ahead... */
- return_read_eof = NO;
- reported_read_eof = NO;
- status_eof_detected = NO; /* reset this too */
- /*fall through*/
+
+ /* Must ensure that user program sees exactly one EOF token (==0) */
+ if (return_read_eof == YES) {
+ if (TPQDBG(DEBUG)) {
+ printk
+ ("read: return_read_eof==%d, reported_read_eof==%d, total_bytes_done==%lu\n",
+ return_read_eof, reported_read_eof,
+ total_bytes_done);
+ }
+
+ if (reported_read_eof == NO) {
+ /* have not yet returned EOF to user program */
+ if (total_bytes_done > 0) {
+ return total_bytes_done; /* next time return EOF */
+ } else {
+ reported_read_eof = YES; /* move on next time */
+ return 0; /* return EOF */
+ }
+ } else {
+ /* Application program has already received EOF
+ * (above), now continue with next file on tape,
+ * if possible.
+ * When the FM is reached, EXCEPTION is set,
+ * causing a sense(). Subsequent read/writes will
+ * continue after the FM.
+ */
+ /*********** ?????????? this should check for (EOD|NDT), not EOM, 'cause we can read past EW: ************/
+ if (status_eom_detected) {
+ /* If EOM, nothing left to read, so keep returning EOFs.
+ *** should probably set some flag to avoid clearing
+ *** status_eom_detected through ioctls or something
+ */
+ return 0;
+ } else {
+ /* just eof, there may be more files ahead... */
+ return_read_eof = NO;
+ reported_read_eof = NO;
+ status_eof_detected = NO; /* reset this too */
+ /*fall through */
+ }
+ }
}
- }
- }
-
+
/*****************************/
- if (bytes_todo==0)
- {
- return total_bytes_done;
- }
-
- if (bytes_todo>0)
- {
- /* start reading data */
- if (is_exception()) /****************************************/
- {
- tpqputs(TPQD_DMAX, "is_exception() before start_dma()!");
- }
-
+ if (bytes_todo == 0) {
+ return total_bytes_done;
+ }
+
+ if (bytes_todo > 0) {
+ /* start reading data */
+ if (is_exception()) {
+/****************************************/
+ tpqputs(TPQD_DMAX,
+ "is_exception() before start_dma()!");
+ }
+
/******************************************************************
***** if start_dma() fails because the head is positioned 0 bytes
***** before the FM, (causing EXCEPTION to be set) return_read_eof should
***** be set to YES, and we should return total_bytes_done, rather than -ENXIO.
***** The app should recognize this as an EOF condition.
***************************************************************************/
- stat = start_dma(READ, bytes_todo);
- if (stat == TE_OK)
- {
- /* Wait for transfer to complete, interrupt should wake us */
- while (dma_mode != 0)
- {
- sleep_on(&qic02_tape_transfer);
- }
- if (status_error)
- {
- return_read_eof = YES;
- }
-
- }
- else if (stat != TE_END)
- {
- /* should do sense() on error here */
+ stat = start_dma(READ, bytes_todo);
+ if (stat == TE_OK) {
+ /* Wait for transfer to complete, interrupt should wake us */
+ while (dma_mode != 0) {
+ sleep_on(&qic02_tape_transfer);
+ }
+ if (status_error) {
+ return_read_eof = YES;
+ }
+
+ } else if (stat != TE_END) {
+ /* should do sense() on error here */
#if 0
- return -ENXIO;
+ return -ENXIO;
#else
- printk("Trouble: stat==%02x\n", stat);
- return_read_eof = YES;
+ printk("Trouble: stat==%02x\n", stat);
+ return_read_eof = YES;
/*************** check EOF/EOT handling!!!!!! **/
#endif
- }
- end_dma(&bytes_done);
- if (bytes_done>bytes_todo)
- {
- tpqputs(TPQD_ALWAYS, "read: Oops, read more bytes than requested");
- return -EIO;
- }
- /* copy buffer to user-space in one go */
- if (bytes_done>0)
- {
- err = copy_to_user(buf, buffaddr, bytes_done);
- if (err)
- {
- return -EFAULT;
- }
- }
+ }
+ end_dma(&bytes_done);
+ if (bytes_done > bytes_todo) {
+ tpqputs(TPQD_ALWAYS,
+ "read: Oops, read more bytes than requested");
+ return -EIO;
+ }
+ /* copy buffer to user-space in one go */
+ if (bytes_done > 0) {
+ err =
+ copy_to_user(buf, buffaddr,
+ bytes_done);
+ if (err) {
+ return -EFAULT;
+ }
+ }
#if 1
- /* Checks Ton's patch below */
- if ((return_read_eof == NO) && (status_eof_detected == YES))
- {
- printk(TPQIC02_NAME ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n", return_read_eof);
- }
+ /* Checks Ton's patch below */
+ if ((return_read_eof == NO)
+ && (status_eof_detected == YES)) {
+ printk(TPQIC02_NAME
+ ": read(): return_read_eof=%d, status_eof_detected=YES. return_read_eof:=YES\n",
+ return_read_eof);
+ }
#endif
- if ((bytes_todo != bytes_done) || (status_eof_detected == YES))
- {
- /* EOF or EOM detected. return EOF next time. */
- return_read_eof = YES;
- }
-
- } /* else: ignore read request for 0 bytes */
-
- if (bytes_done>0)
- {
- status_bytes_rd = YES;
- buf += bytes_done;
- *ppos += bytes_done;
- total_bytes_done += bytes_done;
- count -= bytes_done;
+ if ((bytes_todo != bytes_done)
+ || (status_eof_detected == YES)) {
+ /* EOF or EOM detected. return EOF next time. */
+ return_read_eof = YES;
+ }
+
+ }
+ /* else: ignore read request for 0 bytes */
+ if (bytes_done > 0) {
+ status_bytes_rd = YES;
+ buf += bytes_done;
+ *ppos += bytes_done;
+ total_bytes_done += bytes_done;
+ count -= bytes_done;
+ }
}
- }
- tpqputs(TPQD_ALWAYS, "read request for <0 bytes");
- return -EINVAL;
-} /* qic02_tape_read */
+ tpqputs(TPQD_ALWAYS, "read request for <0 bytes");
+ return -EINVAL;
+} /* qic02_tape_read */
* tape device again. The driver will detect an exception status in (No Cartridge)
* and force a rewind. After that tar may continue writing.
*/
-static ssize_t qic02_tape_write( struct file * filp, const char * buf,
- size_t count, loff_t *ppos)
+static ssize_t qic02_tape_write(struct file *filp, const char *buf,
+ size_t count, loff_t * ppos)
{
- int err;
- kdev_t dev = filp->f_dentry->d_inode->i_rdev;
- unsigned short flags = filp->f_flags;
- unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
-
- if (status_zombie==YES)
- {
- tpqputs(TPQD_ALWAYS, "configs not set");
- return -ENXIO;
- }
-
- if (TP_DIAGS(current_tape_dev))
- {
- /* can't print a ``long long'' (for filp->f_pos), so chop it */
- printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
- ", count=%lx, pos=%lx, flags=%x\n",
- MINOR(dev), buf,
- (long) count, (unsigned long) filp->f_pos, flags);
- }
-
- if (count % TAPE_BLKSIZE) /* only allow mod 512 bytes at a time */
- {
- tpqputs(TPQD_BLKSZ, "Wrong block size");
- return -EINVAL;
- }
-
- if (mode_access==READ)
- {
- tpqputs(TPQD_ALWAYS, "Not in write mode");
- return -EACCES;
- }
-
- /* open() does a sense() and we can assume the tape isn't changed
- * between open() and release(), so the tperror.exs bits will still
- * be valid.
- */
- if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP))
- {
- tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
- return -EACCES; /* don't even try when write protected */
- }
-
- if (doing_read == YES)
- {
- terminate_read(0);
- }
-
- while ((signed)count>=0)
- {
- /* see how much fits in the kernel buffer */
- bytes_done = 0;
- bytes_todo = TPQBUF_SIZE;
- if (bytes_todo>count)
- {
- bytes_todo = count;
+ int err;
+ kdev_t dev = filp->f_dentry->d_inode->i_rdev;
+ unsigned short flags = filp->f_flags;
+ unsigned long bytes_todo, bytes_done, total_bytes_done = 0;
+
+ if (status_zombie == YES) {
+ tpqputs(TPQD_ALWAYS, "configs not set");
+ return -ENXIO;
}
-
- if (return_write_eof == YES)
- {
- /* return_write_eof should be reset on reverse tape movements. */
-
- if (reported_write_eof==NO)
- {
- if (bytes_todo>0)
- {
- tpqputs(TPQD_ALWAYS, "partial write");
- /* partial write signals EOF to user program */
- }
- reported_write_eof = YES;
- return total_bytes_done;
- }
- else
- {
- return -ENOSPC; /* return error */
- }
- }
-
- /* Quit when done. */
- if (bytes_todo==0)
- {
- return total_bytes_done;
+
+ if (TP_DIAGS(current_tape_dev)) {
+ /* can't print a ``long long'' (for filp->f_pos), so chop it */
+ printk(TPQIC02_NAME ": request WRITE, minor=%x, buf=%p"
+ ", count=%lx, pos=%lx, flags=%x\n",
+ MINOR(dev), buf,
+ (long) count, (unsigned long) filp->f_pos, flags);
+ }
+
+ if (count % TAPE_BLKSIZE) { /* only allow mod 512 bytes at a time */
+ tpqputs(TPQD_BLKSZ, "Wrong block size");
+ return -EINVAL;
+ }
+
+ if (mode_access == READ) {
+ tpqputs(TPQD_ALWAYS, "Not in write mode");
+ return -EACCES;
+ }
+
+ /* open() does a sense() and we can assume the tape isn't changed
+ * between open() and release(), so the tperror.exs bits will still
+ * be valid.
+ */
+ if ((tperror.exs & TP_ST0) && (tperror.exs & TP_WRP)) {
+ tpqputs(TPQD_ALWAYS, "Cartridge is write-protected.");
+ return -EACCES; /* don't even try when write protected */
+ }
+
+ if (doing_read == YES) {
+ terminate_read(0);
}
-
- /* copy from user to DMA buffer and initiate transfer. */
- if (bytes_todo>0)
- {
- err = copy_from_user(buffaddr, buf, bytes_todo);
- if (err)
- {
- return -EFAULT;
- }
+
+ while ((signed) count >= 0) {
+ /* see how much fits in the kernel buffer */
+ bytes_done = 0;
+ bytes_todo = TPQBUF_SIZE;
+ if (bytes_todo > count) {
+ bytes_todo = count;
+ }
+
+ if (return_write_eof == YES) {
+ /* return_write_eof should be reset on reverse tape movements. */
+
+ if (reported_write_eof == NO) {
+ if (bytes_todo > 0) {
+ tpqputs(TPQD_ALWAYS,
+ "partial write");
+ /* partial write signals EOF to user program */
+ }
+ reported_write_eof = YES;
+ return total_bytes_done;
+ } else {
+ return -ENOSPC; /* return error */
+ }
+ }
+
+ /* Quit when done. */
+ if (bytes_todo == 0) {
+ return total_bytes_done;
+ }
+
+ /* copy from user to DMA buffer and initiate transfer. */
+ if (bytes_todo > 0) {
+ err = copy_from_user(buffaddr, buf, bytes_todo);
+ if (err) {
+ return -EFAULT;
+ }
/****************** similar problem with read() at FM could happen here at EOT.
******************/
/***** if at EOT, 0 bytes can be written. start_dma() will
***** fail and write() will return ENXIO error
*****/
- if (start_dma(WRITE, bytes_todo) != TE_OK)
- {
- tpqputs(TPQD_ALWAYS, "write: start_dma() failed");
- /* should do sense() on error here */
- return -ENXIO; /*********** FIXTHIS **************/
- }
-
- /* Wait for write to complete, interrupt should wake us. */
- while ((status_error == 0) && (dma_mode != 0))
- {
- sleep_on(&qic02_tape_transfer);
- }
-
- end_dma(&bytes_done);
- if (bytes_done>bytes_todo)
- {
- tpqputs(TPQD_ALWAYS, "write: Oops, wrote more bytes than requested");
- return -EIO;
- }
- /* If the dma-transfer was aborted because of an exception,
- * status_error will have been set in the interrupt handler.
- * Then end_dma() will do a sense().
- * If the exception was EXC_EOM, the EW-hole was encountered
- * and two more blocks could be written. For the time being we'll
- * just consider this to be the EOT.
- * Otherwise, something Bad happened, such as the maximum number
- * of block-rewrites was exceeded. [e.g. A very bad spot on tape was
- * encountered. Normally short dropouts are compensated for by
- * rewriting the block in error, up to 16 times. I'm not sure
- * QIC-24 drives can do this.]
- */
- if (status_error)
- {
- if (status_eom_detected == YES)
- {
- tpqputs(TPQD_ALWAYS, "write: EW detected");
- return_write_eof = YES;
- }
- else
- {
- /* probably EXC_RWA */
- tpqputs(TPQD_ALWAYS, "write: dma: error in writing");
- return -EIO;
- }
- }
- if (bytes_todo != bytes_done)
- {
- /* EOF or EOM detected. return EOT next time. */
- return_write_eof = YES;
- }
- }
- /* else: ignore write request for 0 bytes. */
-
- if (bytes_done>0)
- {
- status_bytes_wr = YES;
- buf += bytes_done;
- *ppos += bytes_done;
- total_bytes_done += bytes_done;
- count -= bytes_done;
- }
- }
-
- tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
- if (TPQDBG(DEBUG))
- {
- printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
- ", total_bytes_done %lx, count %lx\n",
- status_bytes_wr, buf, total_bytes_done, (long) count);
- }
- return -EINVAL;
-} /* qic02_tape_write */
+ if (start_dma(WRITE, bytes_todo) != TE_OK) {
+ tpqputs(TPQD_ALWAYS,
+ "write: start_dma() failed");
+ /* should do sense() on error here */
+ return -ENXIO;
+ /*********** FIXTHIS **************/
+ }
+
+ /* Wait for write to complete, interrupt should wake us. */
+ while ((status_error == 0) && (dma_mode != 0)) {
+ sleep_on(&qic02_tape_transfer);
+ }
+
+ end_dma(&bytes_done);
+ if (bytes_done > bytes_todo) {
+ tpqputs(TPQD_ALWAYS,
+ "write: Oops, wrote more bytes than requested");
+ return -EIO;
+ }
+ /* If the dma-transfer was aborted because of an exception,
+ * status_error will have been set in the interrupt handler.
+ * Then end_dma() will do a sense().
+ * If the exception was EXC_EOM, the EW-hole was encountered
+ * and two more blocks could be written. For the time being we'll
+ * just consider this to be the EOT.
+ * Otherwise, something Bad happened, such as the maximum number
+ * of block-rewrites was exceeded. [e.g. A very bad spot on tape was
+ * encountered. Normally short dropouts are compensated for by
+ * rewriting the block in error, up to 16 times. I'm not sure
+ * QIC-24 drives can do this.]
+ */
+ if (status_error) {
+ if (status_eom_detected == YES) {
+ tpqputs(TPQD_ALWAYS,
+ "write: EW detected");
+ return_write_eof = YES;
+ } else {
+ /* probably EXC_RWA */
+ tpqputs(TPQD_ALWAYS,
+ "write: dma: error in writing");
+ return -EIO;
+ }
+ }
+ if (bytes_todo != bytes_done) {
+ /* EOF or EOM detected. return EOT next time. */
+ return_write_eof = YES;
+ }
+ }
+ /* else: ignore write request for 0 bytes. */
+
+ if (bytes_done > 0) {
+ status_bytes_wr = YES;
+ buf += bytes_done;
+ *ppos += bytes_done;
+ total_bytes_done += bytes_done;
+ count -= bytes_done;
+ }
+ }
+
+ tpqputs(TPQD_ALWAYS, "write request for <0 bytes");
+ if (TPQDBG(DEBUG)) {
+ printk(TPQIC02_NAME ": status_bytes_wr %x, buf %p"
+ ", total_bytes_done %lx, count %lx\n",
+ status_bytes_wr, buf, total_bytes_done,
+ (long) count);
+ }
+ return -EINVAL;
+} /* qic02_tape_write */
* Don't rewind if the minor bits specify density 0.
*/
-static int qic02_tape_open(struct inode * inode, struct file * filp)
+static int qic02_tape_open(struct inode *inode, struct file *filp)
{
- static int qic02_tape_open_no_use_count(struct inode *, struct file *);
- int open_error;
+ static int qic02_tape_open_no_use_count(struct inode *,
+ struct file *);
+ int open_error;
- open_error = qic02_tape_open_no_use_count(inode, filp);
- return open_error;
+ open_error = qic02_tape_open_no_use_count(inode, filp);
+ return open_error;
}
-static int qic02_tape_open_no_use_count(struct inode * inode, struct file * filp)
+static int qic02_tape_open_no_use_count(struct inode *inode,
+ struct file *filp)
{
- kdev_t dev = inode->i_rdev;
- unsigned short flags = filp->f_flags;
- unsigned short dens = 0;
- int s;
+ kdev_t dev = inode->i_rdev;
+ unsigned short flags = filp->f_flags;
+ unsigned short dens = 0;
+ int s;
- if (TP_DIAGS(dev))
- {
- printk("qic02_tape_open: dev=%s, flags=%x ",
- kdevname(dev), flags);
- }
+ if (TP_DIAGS(dev)) {
+ printk("qic02_tape_open: dev=%s, flags=%x ",
+ kdevname(dev), flags);
+ }
- if (MINOR(dev)==255) /* special case for resetting */
- {
- if (capable(CAP_SYS_ADMIN))
- {
- return (tape_reset(1)==TE_OK) ? -EAGAIN : -ENXIO;
+ if (MINOR(dev) == 255) { /* special case for resetting */
+ if (capable(CAP_SYS_ADMIN)) {
+ return (tape_reset(1) == TE_OK) ? -EAGAIN : -ENXIO;
+ } else {
+ return -EPERM;
+ }
}
- else
- {
- return -EPERM;
+
+ if (status_dead == YES) {
+ /* Allow `mt reset' ioctl() even when already open()ed. */
+ return 0;
}
- }
-
- if (status_dead==YES)
- {
- /* Allow `mt reset' ioctl() even when already open()ed. */
- return 0;
- }
-
+
/* Only one at a time from here on... */
- if (file_count(filp)>1) /* filp->f_count==1 for the first open() */
- {
- return -EBUSY;
- }
-
- if (status_zombie==YES)
- {
- /* no irq/dma/port stuff allocated yet, no reset done
- * yet, so return until MTSETCONFIG has been done.
+ if (file_count(filp) > 1) { /* filp->f_count==1 for the first open() */
+ return -EBUSY;
+ }
+
+ if (status_zombie == YES) {
+ /* no irq/dma/port stuff allocated yet, no reset done
+ * yet, so return until MTSETCONFIG has been done.
+ */
+ return 0;
+ }
+
+ status_bytes_rd = NO;
+ status_bytes_wr = NO;
+
+ return_read_eof = NO; /********????????????????*****/
+ return_write_eof = (status_eot_detected) ? YES : NO;
+
+ /* Clear this in case user app close()d before reading EOF token */
+ status_eof_detected = NO;
+
+ reported_read_eof = NO;
+ reported_write_eof = NO;
+
+
+ switch (flags & O_ACCMODE) {
+ case O_RDONLY:
+ mode_access = READ;
+ break;
+ case O_WRONLY: /* Fallthru... Strictly speaking this is not correct... */
+ case O_RDWR: /* Reads are allowed as long as nothing is written */
+ mode_access = WRITE;
+ break;
+ }
+
+ /* This is to avoid tape-changed problems (TP_CNI exception).
+ *
+ * Since removing the cartridge will not raise an exception,
+ * we always do a tp_sense() to make sure we have the proper
+ * CNI status, the 2150L may need an additional sense.... - Eddy
*/
- return 0;
- }
-
- status_bytes_rd = NO;
- status_bytes_wr = NO;
-
- return_read_eof = NO; /********????????????????*****/
- return_write_eof = (status_eot_detected)? YES : NO;
-
- /* Clear this in case user app close()d before reading EOF token */
- status_eof_detected = NO;
-
- reported_read_eof = NO;
- reported_write_eof = NO;
-
-
- switch (flags & O_ACCMODE)
- {
- case O_RDONLY:
- mode_access = READ;
- break;
- case O_WRONLY: /* Fallthru... Strictly speaking this is not correct... */
- case O_RDWR: /* Reads are allowed as long as nothing is written */
- mode_access = WRITE;
- break;
- }
-
- /* This is to avoid tape-changed problems (TP_CNI exception).
- *
- * Since removing the cartridge will not raise an exception,
- * we always do a tp_sense() to make sure we have the proper
- * CNI status, the 2150L may need an additional sense.... - Eddy
- */
- s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
-
- if (s == TE_OK)
- {
- /* Try to clear cartridge-changed status for Archive-2150L */
- if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI))
- {
- s = tp_sense(TP_WRP|TP_EOM|TP_BOM|TP_CNI|TP_EOR);
- }
- }
-
- if (s != TE_OK)
- {
- tpqputs(TPQD_ALWAYS, "open: sense() failed");
- return -EIO;
- }
-
- /* exception bits should be up-to-date now, so check for
- * tape presence and exit if absent.
- * Even `mt stat' will fail without a tape.
- */
- if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI))
- {
- tpqputs(TPQD_ALWAYS, "No tape present.");
- return -EIO;
- }
-
- /* At this point we can assume that a tape is present and
- * that it will remain present until release() is called.
- */
-
- /* not allowed to do QCMD_DENS_* unless tape is rewound */
- if ((TP_DENS(dev)!=0) && (TP_DENS(current_tape_dev) != TP_DENS(dev)))
- {
- /* force rewind if minor bits have changed,
- * i.e. user wants to use tape in different format.
- * [assuming single drive operation]
+ s = tp_sense(TP_WRP | TP_EOM | TP_BOM | TP_CNI | TP_EOR);
+
+ if (s == TE_OK) {
+ /* Try to clear cartridge-changed status for Archive-2150L */
+ if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) {
+ s = tp_sense(TP_WRP | TP_EOM | TP_BOM | TP_CNI |
+ TP_EOR);
+ }
+ }
+
+ if (s != TE_OK) {
+ tpqputs(TPQD_ALWAYS, "open: sense() failed");
+ return -EIO;
+ }
+
+ /* exception bits should be up-to-date now, so check for
+ * tape presence and exit if absent.
+ * Even `mt stat' will fail without a tape.
*/
- if (TP_HAVE_DENS)
- {
- tpqputs(TPQD_REWIND, "Density minor bits have changed. Forcing rewind.");
- need_rewind = YES;
- }
- }
- else
- {
- /* density bits still the same, but TP_DIAGS bit
- * may have changed.
+ if ((tperror.exs & TP_ST0) && (tperror.exs & TP_CNI)) {
+ tpqputs(TPQD_ALWAYS, "No tape present.");
+ return -EIO;
+ }
+
+ /* At this point we can assume that a tape is present and
+ * that it will remain present until release() is called.
*/
- current_tape_dev = dev;
- }
-
- if (need_rewind == YES) /***************** CHECK THIS!!!!!!!! **********/
- {
- s = do_qic_cmd(QCMD_REWIND, TIM_R);
- if (s != 0)
- {
- tpqputs(TPQD_ALWAYS, "open: rewind failed");
- return -EIO;
+
+ /* not allowed to do QCMD_DENS_* unless tape is rewound */
+ if ((TP_DENS(dev) != 0)
+ && (TP_DENS(current_tape_dev) != TP_DENS(dev))) {
+ /* force rewind if minor bits have changed,
+ * i.e. user wants to use tape in different format.
+ * [assuming single drive operation]
+ */
+ if (TP_HAVE_DENS) {
+ tpqputs(TPQD_REWIND,
+ "Density minor bits have changed. Forcing rewind.");
+ need_rewind = YES;
+ }
+ } else {
+ /* density bits still the same, but TP_DIAGS bit
+ * may have changed.
+ */
+ current_tape_dev = dev;
+ }
+
+ if (need_rewind == YES) {
+/***************** CHECK THIS!!!!!!!! **********/
+ s = do_qic_cmd(QCMD_REWIND, TIM_R);
+ if (s != 0) {
+ tpqputs(TPQD_ALWAYS, "open: rewind failed");
+ return -EIO;
+ }
}
- }
/* Note: After a reset command, the controller will rewind the tape
* just before performing any tape movement operation! ************ SO SET need_rewind flag!!!!!
- */
- if (status_dead==YES)
- {
- tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset");
- if (tape_reset(1)!=TE_OK)
- {
- return -ENXIO;
+ */
+ if (status_dead == YES) {
+ tpqputs(TPQD_ALWAYS, "open: tape dead, attempting reset");
+ if (tape_reset(1) != TE_OK) {
+ return -ENXIO;
+ } else {
+ status_dead = NO;
+ if (tp_sense(~(TP_ST1 | TP_ILL)) != TE_OK) {
+ tpqputs(TPQD_ALWAYS,
+ "open: tp_sense() failed\n");
+ status_dead = YES; /* try reset next time */
+ return -EIO;
+ }
+ }
}
- else
- {
- status_dead = NO;
- if (tp_sense(~(TP_ST1|TP_ILL)) != TE_OK)
- {
- tpqputs(TPQD_ALWAYS, "open: tp_sense() failed\n");
- status_dead = YES; /* try reset next time */
+
+ /* things should be ok, once we get here */
+
+
+ /* set density: only allowed when TP_BOM status bit is set,
+ * so we must have done a rewind by now. If not, just skip over.
+ * Only give set density command when minor bits have changed.
+ */
+ if (TP_DENS(current_tape_dev) == TP_DENS(dev)) {
+ return 0;
+ }
+
+ current_tape_dev = dev;
+ need_rewind = NO;
+ if (TP_HAVE_DENS) {
+ dens = TP_DENS(dev);
+ }
+
+ if (dens < sizeof(format_names) / sizeof(char *)) {
+ printk(TPQIC02_NAME ": format: %s%s\n",
+ (dens != 0) ? "QIC-" : "", format_names[dens]);
+ } else {
+ tpqputs(TPQD_REWIND, "Wait for retensioning...");
+ }
+
+ switch (TP_DENS(dev)) {
+ case 0: /* Minor 0 is for drives without set-density support */
+ s = 0;
+ break;
+ case 1:
+ s = do_qic_cmd(QCMD_DENS_11, TIM_S);
+ break;
+ case 2:
+ s = do_qic_cmd(QCMD_DENS_24, TIM_S);
+ break;
+ case 3:
+ s = do_qic_cmd(QCMD_DENS_120, TIM_S);
+ break;
+ case 4:
+ s = do_qic_cmd(QCMD_DENS_150, TIM_S);
+ break;
+ case 5:
+ s = do_qic_cmd(QCMD_DENS_300, TIM_S);
+ break;
+ case 6:
+ s = do_qic_cmd(QCMD_DENS_600, TIM_S);
+ break;
+ default: /* otherwise do a retension before anything else */
+ s = do_qic_cmd(QCMD_RETEN, TIM_R);
+ }
+ if (s != 0) {
+ status_dead = YES; /* force reset */
+ current_tape_dev = 0; /* earlier 0xff80 */
return -EIO;
- }
- }
- }
-
- /* things should be ok, once we get here */
-
-
- /* set density: only allowed when TP_BOM status bit is set,
- * so we must have done a rewind by now. If not, just skip over.
- * Only give set density command when minor bits have changed.
- */
- if (TP_DENS(current_tape_dev) == TP_DENS(dev) )
- {
+ }
+
return 0;
- }
-
- current_tape_dev = dev;
- need_rewind = NO;
- if (TP_HAVE_DENS)
- {
- dens = TP_DENS(dev);
- }
-
- if (dens < sizeof(format_names)/sizeof(char *))
- {
- printk(TPQIC02_NAME ": format: %s%s\n", (dens!=0)? "QIC-" : "", format_names[dens]);
- }
- else
- {
- tpqputs(TPQD_REWIND, "Wait for retensioning...");
- }
-
- switch (TP_DENS(dev))
- {
- case 0: /* Minor 0 is for drives without set-density support */
- s = 0;
- break;
- case 1:
- s = do_qic_cmd(QCMD_DENS_11, TIM_S);
- break;
- case 2:
- s = do_qic_cmd(QCMD_DENS_24, TIM_S);
- break;
- case 3:
- s = do_qic_cmd(QCMD_DENS_120, TIM_S);
- break;
- case 4:
- s = do_qic_cmd(QCMD_DENS_150, TIM_S);
- break;
- case 5:
- s = do_qic_cmd(QCMD_DENS_300, TIM_S);
- break;
- case 6:
- s = do_qic_cmd(QCMD_DENS_600, TIM_S);
- break;
- default: /* otherwise do a retension before anything else */
- s = do_qic_cmd(QCMD_RETEN, TIM_R);
- }
- if (s != 0)
- {
- status_dead = YES; /* force reset */
- current_tape_dev = 0; /* earlier 0xff80 */
- return -EIO;
- }
-
- return 0;
-} /* qic02_tape_open */
-
-
-static int qic02_tape_release(struct inode * inode, struct file * filp)
+} /* qic02_tape_open */
+
+
+static int qic02_tape_release(struct inode *inode, struct file *filp)
{
- kdev_t dev = inode->i_rdev;
-
- lock_kernel();
- if (TP_DIAGS(dev))
- {
- printk("qic02_tape_release: dev=%s\n", kdevname(dev));
- }
-
- if (status_zombie==NO) /* don't rewind in zombie mode */
- {
- /* Terminate any pending write cycle. Terminating the read-cycle
- * is delayed until it is required to do so for a new command.
- */
- terminate_write(-1);
-
- if (status_dead==YES)
- {
- tpqputs(TPQD_ALWAYS, "release: device dead!?");
+ kdev_t dev = inode->i_rdev;
+
+ lock_kernel();
+ if (TP_DIAGS(dev)) {
+ printk("qic02_tape_release: dev=%s\n", kdevname(dev));
}
-
- /* Rewind only if minor number requires it AND
- * read/writes have been done. ************* IS THIS CORRECT??????????
- */
- if ((TP_REWCLOSE(dev)) && (status_bytes_rd | status_bytes_wr))
- {
- tpqputs(TPQD_REWIND, "release: Doing rewind...");
- (void) do_qic_cmd(QCMD_REWIND, TIM_R);
+
+ if (status_zombie == NO) { /* don't rewind in zombie mode */
+ /* Terminate any pending write cycle. Terminating the read-cycle
+ * is delayed until it is required to do so for a new command.
+ */
+ terminate_write(-1);
+
+ if (status_dead == YES) {
+ tpqputs(TPQD_ALWAYS, "release: device dead!?");
+ }
+
+ /* Rewind only if minor number requires it AND
+ * read/writes have been done. ************* IS THIS CORRECT??????????
+ */
+ if ((TP_REWCLOSE(dev))
+ && (status_bytes_rd | status_bytes_wr)) {
+ tpqputs(TPQD_REWIND, "release: Doing rewind...");
+ (void) do_qic_cmd(QCMD_REWIND, TIM_R);
+ }
}
- }
- unlock_kernel();
- return 0;
-} /* qic02_tape_release */
+ unlock_kernel();
+ return 0;
+} /* qic02_tape_release */
#ifdef CONFIG_QIC02_DYNCONF
/* Set masks etc. based on the interface card type. */
static int update_ifc_masks(int ifc)
{
- QIC02_TAPE_IFC = ifc;
-
- if ((QIC02_TAPE_IFC == WANGTEK) || (QIC02_TAPE_IFC == EVEREX))
- {
- QIC02_STAT_PORT = QIC02_TAPE_PORT;
- QIC02_CTL_PORT = QIC02_TAPE_PORT;
- QIC02_CMD_PORT = QIC02_TAPE_PORT+1;
- QIC02_DATA_PORT = QIC02_TAPE_PORT+1;
- QIC02_STAT_READY = WT_QIC02_STAT_READY;
- QIC02_STAT_EXCEPTION = WT_QIC02_STAT_EXCEPTION;
- QIC02_STAT_MASK = WT_QIC02_STAT_MASK;
-
- QIC02_STAT_RESETMASK = WT_QIC02_STAT_RESETMASK;
- QIC02_STAT_RESETVAL = WT_QIC02_STAT_RESETVAL;
-
- QIC02_CTL_RESET = WT_QIC02_CTL_RESET;
- QIC02_CTL_REQUEST = WT_QIC02_CTL_REQUEST;
-
- if (QIC02_TAPE_DMA == 3)
- {
- WT_CTL_DMA = WT_CTL_DMA3;
- }
- else if (QIC02_TAPE_DMA == 1)
- {
- WT_CTL_DMA = WT_CTL_DMA1;
- }
- else
- {
- tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
- return -EIO;
- }
+ QIC02_TAPE_IFC = ifc;
+
+ if ((QIC02_TAPE_IFC == WANGTEK) || (QIC02_TAPE_IFC == EVEREX)) {
+ QIC02_STAT_PORT = QIC02_TAPE_PORT;
+ QIC02_CTL_PORT = QIC02_TAPE_PORT;
+ QIC02_CMD_PORT = QIC02_TAPE_PORT + 1;
+ QIC02_DATA_PORT = QIC02_TAPE_PORT + 1;
+ QIC02_STAT_READY = WT_QIC02_STAT_READY;
+ QIC02_STAT_EXCEPTION = WT_QIC02_STAT_EXCEPTION;
+ QIC02_STAT_MASK = WT_QIC02_STAT_MASK;
+
+ QIC02_STAT_RESETMASK = WT_QIC02_STAT_RESETMASK;
+ QIC02_STAT_RESETVAL = WT_QIC02_STAT_RESETVAL;
+
+ QIC02_CTL_RESET = WT_QIC02_CTL_RESET;
+ QIC02_CTL_REQUEST = WT_QIC02_CTL_REQUEST;
+
+ if (QIC02_TAPE_DMA == 3) {
+ WT_CTL_DMA = WT_CTL_DMA3;
+ } else if (QIC02_TAPE_DMA == 1) {
+ WT_CTL_DMA = WT_CTL_DMA1;
+ } else {
+ tpqputs(TPQD_ALWAYS,
+ "Unsupported or incorrect DMA channel");
+ return -EIO;
+ }
- if (QIC02_TAPE_IFC == EVEREX)
- {
- /* Everex is a special case for Wangtek (actually
- * it's the other way 'round, but I saw Wangtek first)
- */
- if (QIC02_TAPE_DMA==3)
- {
- WT_CTL_DMA = WT_CTL_DMA1;
- }
-
- /* Fixup the kernel copy of the IFC type to that
- * we don't have to distinguish between Wangtek and
- * and Everex at runtime.
- */
- QIC02_TAPE_IFC = WANGTEK;
- }
- }
- else if (QIC02_TAPE_IFC == ARCHIVE)
- {
- QIC02_STAT_PORT = QIC02_TAPE_PORT+1;
- QIC02_CTL_PORT = QIC02_TAPE_PORT+1;
- QIC02_CMD_PORT = QIC02_TAPE_PORT;
- QIC02_DATA_PORT = QIC02_TAPE_PORT;
- QIC02_STAT_READY = AR_QIC02_STAT_READY;
- QIC02_STAT_EXCEPTION = AR_QIC02_STAT_EXCEPTION;
- QIC02_STAT_MASK = AR_QIC02_STAT_MASK;
-
- QIC02_STAT_RESETMASK = AR_QIC02_STAT_RESETMASK;
- QIC02_STAT_RESETVAL = AR_QIC02_STAT_RESETVAL;
-
- QIC02_CTL_RESET = AR_QIC02_CTL_RESET;
- QIC02_CTL_REQUEST = AR_QIC02_CTL_REQUEST;
-
- if (QIC02_TAPE_DMA > 3)
- {
- tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
- return -EIO;
- }
- }
- else if (QIC02_TAPE_IFC == MOUNTAIN)
- {
- QIC02_STAT_PORT = QIC02_TAPE_PORT+1;
- QIC02_CTL_PORT = QIC02_TAPE_PORT+1;
- QIC02_CMD_PORT = QIC02_TAPE_PORT;
- QIC02_DATA_PORT = QIC02_TAPE_PORT;
-
- QIC02_STAT_READY = MTN_QIC02_STAT_READY;
- QIC02_STAT_EXCEPTION = MTN_QIC02_STAT_EXCEPTION;
- QIC02_STAT_MASK = MTN_QIC02_STAT_MASK;
-
- QIC02_STAT_RESETMASK = MTN_QIC02_STAT_RESETMASK;
- QIC02_STAT_RESETVAL = MTN_QIC02_STAT_RESETVAL;
-
- QIC02_CTL_RESET = MTN_QIC02_CTL_RESET;
- QIC02_CTL_REQUEST = MTN_QIC02_CTL_REQUEST;
-
- if (QIC02_TAPE_DMA > 3)
- {
- tpqputs(TPQD_ALWAYS, "Unsupported or incorrect DMA channel");
- return -EIO;
- }
- }
- else
- {
- tpqputs(TPQD_ALWAYS, "Invalid interface type");
- return -ENXIO;
- }
- return qic02_get_resources();
-} /* update_ifc_masks */
+ if (QIC02_TAPE_IFC == EVEREX) {
+ /* Everex is a special case for Wangtek (actually
+ * it's the other way 'round, but I saw Wangtek first)
+ */
+ if (QIC02_TAPE_DMA == 3) {
+ WT_CTL_DMA = WT_CTL_DMA1;
+ }
+
+ /* Fixup the kernel copy of the IFC type to that
+ * we don't have to distinguish between Wangtek and
+ * and Everex at runtime.
+ */
+ QIC02_TAPE_IFC = WANGTEK;
+ }
+ } else if (QIC02_TAPE_IFC == ARCHIVE) {
+ QIC02_STAT_PORT = QIC02_TAPE_PORT + 1;
+ QIC02_CTL_PORT = QIC02_TAPE_PORT + 1;
+ QIC02_CMD_PORT = QIC02_TAPE_PORT;
+ QIC02_DATA_PORT = QIC02_TAPE_PORT;
+ QIC02_STAT_READY = AR_QIC02_STAT_READY;
+ QIC02_STAT_EXCEPTION = AR_QIC02_STAT_EXCEPTION;
+ QIC02_STAT_MASK = AR_QIC02_STAT_MASK;
+
+ QIC02_STAT_RESETMASK = AR_QIC02_STAT_RESETMASK;
+ QIC02_STAT_RESETVAL = AR_QIC02_STAT_RESETVAL;
+
+ QIC02_CTL_RESET = AR_QIC02_CTL_RESET;
+ QIC02_CTL_REQUEST = AR_QIC02_CTL_REQUEST;
+
+ if (QIC02_TAPE_DMA > 3) {
+ tpqputs(TPQD_ALWAYS,
+ "Unsupported or incorrect DMA channel");
+ return -EIO;
+ }
+ } else if (QIC02_TAPE_IFC == MOUNTAIN) {
+ QIC02_STAT_PORT = QIC02_TAPE_PORT + 1;
+ QIC02_CTL_PORT = QIC02_TAPE_PORT + 1;
+ QIC02_CMD_PORT = QIC02_TAPE_PORT;
+ QIC02_DATA_PORT = QIC02_TAPE_PORT;
+
+ QIC02_STAT_READY = MTN_QIC02_STAT_READY;
+ QIC02_STAT_EXCEPTION = MTN_QIC02_STAT_EXCEPTION;
+ QIC02_STAT_MASK = MTN_QIC02_STAT_MASK;
+
+ QIC02_STAT_RESETMASK = MTN_QIC02_STAT_RESETMASK;
+ QIC02_STAT_RESETVAL = MTN_QIC02_STAT_RESETVAL;
+
+ QIC02_CTL_RESET = MTN_QIC02_CTL_RESET;
+ QIC02_CTL_REQUEST = MTN_QIC02_CTL_REQUEST;
+
+ if (QIC02_TAPE_DMA > 3) {
+ tpqputs(TPQD_ALWAYS,
+ "Unsupported or incorrect DMA channel");
+ return -EIO;
+ }
+ } else {
+ tpqputs(TPQD_ALWAYS, "Invalid interface type");
+ return -ENXIO;
+ }
+ return qic02_get_resources();
+} /* update_ifc_masks */
#endif
/* ioctl allows user programs to rewind the tape and stuff like that */
-static int qic02_tape_ioctl(struct inode * inode, struct file * filp,
- unsigned int iocmd, unsigned long ioarg)
+static int qic02_tape_ioctl(struct inode *inode, struct file *filp,
+ unsigned int iocmd, unsigned long ioarg)
{
- int error;
- int dev_maj = MAJOR(inode->i_rdev);
- int c;
- struct mtop operation;
- unsigned char blk_addr[6];
- struct mtpos ioctl_tell;
-
-
- if (TP_DIAGS(current_tape_dev))
- {
- printk(TPQIC02_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj, iocmd, ioarg);
- }
-
- if (!inode || !ioarg)
- {
- return -EINVAL;
- }
-
- /* check iocmd first */
+ int error;
+ int dev_maj = MAJOR(inode->i_rdev);
+ int c;
+ struct mtop operation;
+ unsigned char blk_addr[6];
+ struct mtpos ioctl_tell;
- if (dev_maj != QIC02_TAPE_MAJOR)
- {
- printk(TPQIC02_NAME ": Oops! Wrong device?\n");
- /* A panic() would be appropriate here */
- return -ENODEV;
- }
- c = _IOC_NR(iocmd);
-
-#ifdef CONFIG_QIC02_DYNCONF
- if (c == _IOC_NR(MTIOCGETCONFIG))
- {
- CHECK_IOC_SIZE(mtconfiginfo);
+ if (TP_DIAGS(current_tape_dev)) {
+ printk(TPQIC02_NAME ": ioctl(%4x, %4x, %4lx)\n", dev_maj,
+ iocmd, ioarg);
+ }
- if (copy_to_user((char *) ioarg, (char *) &qic02_tape_dynconf, sizeof(qic02_tape_dynconf)))
- {
- return -EFAULT;
+ if (!inode || !ioarg) {
+ return -EINVAL;
}
- return 0;
- }
- else if (c == _IOC_NR(MTIOCSETCONFIG))
- {
- /* One should always do a MTIOCGETCONFIG first, then update
- * user-settings, then write back with MTIOCSETCONFIG.
- * The qic02conf program should re-open() the device before actual
- * use, to make sure everything is initialized.
- */
-
- CHECK_IOC_SIZE(mtconfiginfo);
-
- if (!capable(CAP_SYS_ADMIN))
- {
- return -EPERM;
+ /* check iocmd first */
+
+ if (dev_maj != QIC02_TAPE_MAJOR) {
+ printk(TPQIC02_NAME ": Oops! Wrong device?\n");
+ /* A panic() would be appropriate here */
+ return -ENODEV;
}
-
- if ((doing_read!=NO) || (doing_write!=NO))
- {
- return -EBUSY;
+
+ c = _IOC_NR(iocmd);
+
+#ifdef CONFIG_QIC02_DYNCONF
+ if (c == _IOC_NR(MTIOCGETCONFIG)) {
+ CHECK_IOC_SIZE(mtconfiginfo);
+
+ if (copy_to_user
+ ((char *) ioarg, (char *) &qic02_tape_dynconf,
+ sizeof(qic02_tape_dynconf))) {
+ return -EFAULT;
+ }
+ return 0;
+
+ } else if (c == _IOC_NR(MTIOCSETCONFIG)) {
+ /* One should always do a MTIOCGETCONFIG first, then update
+ * user-settings, then write back with MTIOCSETCONFIG.
+ * The qic02conf program should re-open() the device before actual
+ * use, to make sure everything is initialized.
+ */
+
+ CHECK_IOC_SIZE(mtconfiginfo);
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ return -EPERM;
+ }
+
+ if ((doing_read != NO) || (doing_write != NO)) {
+ return -EBUSY;
+ }
+
+ if (status_zombie == NO) {
+ qic02_release_resources(); /* and go zombie */
+ }
+
+ /* copy struct from user space to kernel space */
+ if (copy_from_user
+ ((char *) &qic02_tape_dynconf, (char *) ioarg,
+ sizeof(qic02_tape_dynconf))) {
+ return -EFAULT;
+ }
+ return update_ifc_masks(qic02_tape_dynconf.ifc_type);
}
-
- if (status_zombie==NO)
- {
- qic02_release_resources(); /* and go zombie */
+ if (status_zombie == YES) {
+ tpqputs(TPQD_ALWAYS, "Configs not set");
+ return -ENXIO;
}
-
- /* copy struct from user space to kernel space */
- if (copy_from_user((char *) &qic02_tape_dynconf, (char *) ioarg, sizeof(qic02_tape_dynconf)))
- {
- return -EFAULT;
- }
- return update_ifc_masks(qic02_tape_dynconf.ifc_type);
- }
- if (status_zombie==YES)
- {
- tpqputs(TPQD_ALWAYS, "Configs not set");
- return -ENXIO;
- }
#endif
- if (c == _IOC_NR(MTIOCTOP))
- {
- CHECK_IOC_SIZE(mtop);
+ if (c == _IOC_NR(MTIOCTOP)) {
+ CHECK_IOC_SIZE(mtop);
+
+ /* copy mtop struct from user space to kernel space */
+ if (copy_from_user
+ ((char *) &operation, (char *) ioarg,
+ sizeof(operation))) {
+ return -EFAULT;
+ }
- /* copy mtop struct from user space to kernel space */
- if (copy_from_user((char *) &operation, (char *) ioarg, sizeof(operation)))
- {
- return -EFAULT;
- }
+ /* ---note: mt_count is signed, negative seeks must be
+ * --- translated to seeks in opposite direction!
+ * (only needed for Sun-programs, I think.)
+ */
+ /* ---note: MTFSF with count 0 should position the
+ * --- tape at the beginning of the current file.
+ */
- /* ---note: mt_count is signed, negative seeks must be
- * --- translated to seeks in opposite direction!
- * (only needed for Sun-programs, I think.)
- */
- /* ---note: MTFSF with count 0 should position the
- * --- tape at the beginning of the current file.
- */
+ if (TP_DIAGS(current_tape_dev)) {
+ printk("OP op=%4x, count=%4x\n", operation.mt_op,
+ operation.mt_count);
+ }
+
+ if (operation.mt_count < 0) {
+ tpqputs(TPQD_ALWAYS,
+ "Warning: negative mt_count ignored");
+ }
- if (TP_DIAGS(current_tape_dev))
- {
- printk("OP op=%4x, count=%4x\n", operation.mt_op, operation.mt_count);
- }
-
- if (operation.mt_count < 0)
- {
- tpqputs(TPQD_ALWAYS, "Warning: negative mt_count ignored");
- }
-
- ioctl_status.mt_resid = operation.mt_count;
- if (operation.mt_op == MTSEEK)
- {
- if (!TP_HAVE_SEEK)
- {
- return -ENOTTY;
- }
-
- seek_addr_buf[0] = (operation.mt_count>>16)&0xff;
- seek_addr_buf[1] = (operation.mt_count>>8)&0xff;
- seek_addr_buf[2] = (operation.mt_count)&0xff;
- if (operation.mt_count>>24)
- {
- return -EINVAL;
- }
- if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
- {
- return error;
- }
-
- ioctl_status.mt_resid = 0;
- }
- else
- {
- while (operation.mt_count > 0)
- {
- operation.mt_count--;
- if ((error = do_ioctl_cmd(operation.mt_op)) != 0)
- {
- return error;
- }
-
ioctl_status.mt_resid = operation.mt_count;
- }
- }
- return 0;
-
- }
- else if (c == _IOC_NR(MTIOCGET))
- {
- if (TP_DIAGS(current_tape_dev))
- {
- printk("GET ");
- }
-
- CHECK_IOC_SIZE(mtget);
+ if (operation.mt_op == MTSEEK) {
+ if (!TP_HAVE_SEEK) {
+ return -ENOTTY;
+ }
- /* It appears (gmt(1)) that it is normal behaviour to
- * first set the status with MTNOP, and then to read
- * it out with MTIOCGET
- */
+ seek_addr_buf[0] =
+ (operation.mt_count >> 16) & 0xff;
+ seek_addr_buf[1] =
+ (operation.mt_count >> 8) & 0xff;
+ seek_addr_buf[2] = (operation.mt_count) & 0xff;
+ if (operation.mt_count >> 24) {
+ return -EINVAL;
+ }
+ if ((error = do_ioctl_cmd(operation.mt_op)) != 0) {
+ return error;
+ }
- /* copy results to user space */
- if (copy_to_user((char *) ioarg, (char *) &ioctl_status, sizeof(ioctl_status)))
- {
- return -EFAULT;
- }
- return 0;
- }
- else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS)))
- {
- if (TP_DIAGS(current_tape_dev))
- {
- printk("POS ");
- }
-
- CHECK_IOC_SIZE(mtpos);
-
- tpqputs(TPQD_IOCTLS, "MTTELL reading block address");
- if ((doing_read==YES) || (doing_write==YES))
- {
- finish_rw(AR_QCMDV_TELL_BLK);
- }
-
- c = rdstatus((char *) blk_addr, sizeof(blk_addr), AR_QCMDV_TELL_BLK);
- if (c!=TE_OK)
- {
- return -EIO;
- }
-
- ioctl_tell.mt_blkno = (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
+ ioctl_status.mt_resid = 0;
+ } else {
+ while (operation.mt_count > 0) {
+ operation.mt_count--;
+ if ((error =
+ do_ioctl_cmd(operation.mt_op)) != 0) {
+ return error;
+ }
- /* copy results to user space */
- if (copy_to_user((char *) ioarg, (char *) &ioctl_tell, sizeof(ioctl_tell)))
- {
- return -EFAULT;
- }
- return 0;
+ ioctl_status.mt_resid = operation.mt_count;
+ }
+ }
+ return 0;
+
+ } else if (c == _IOC_NR(MTIOCGET)) {
+ if (TP_DIAGS(current_tape_dev)) {
+ printk("GET ");
+ }
+
+ CHECK_IOC_SIZE(mtget);
+
+ /* It appears (gmt(1)) that it is normal behaviour to
+ * first set the status with MTNOP, and then to read
+ * it out with MTIOCGET
+ */
+
+ /* copy results to user space */
+ if (copy_to_user
+ ((char *) ioarg, (char *) &ioctl_status,
+ sizeof(ioctl_status))) {
+ return -EFAULT;
+ }
+ return 0;
+ } else if (TP_HAVE_TELL && (c == _IOC_NR(MTIOCPOS))) {
+ if (TP_DIAGS(current_tape_dev)) {
+ printk("POS ");
+ }
+
+ CHECK_IOC_SIZE(mtpos);
+
+ tpqputs(TPQD_IOCTLS, "MTTELL reading block address");
+ if ((doing_read == YES) || (doing_write == YES)) {
+ finish_rw(AR_QCMDV_TELL_BLK);
+ }
+
+ c = rdstatus((char *) blk_addr, sizeof(blk_addr),
+ AR_QCMDV_TELL_BLK);
+ if (c != TE_OK) {
+ return -EIO;
+ }
- }
- else
- {
- return -ENOTTY; /* Other cmds not supported. */
- }
-} /* qic02_tape_ioctl */
+ ioctl_tell.mt_blkno =
+ (blk_addr[3] << 16) | (blk_addr[4] << 8) | blk_addr[5];
+
+ /* copy results to user space */
+ if (copy_to_user
+ ((char *) ioarg, (char *) &ioctl_tell,
+ sizeof(ioctl_tell))) {
+ return -EFAULT;
+ }
+ return 0;
+
+ } else {
+ return -ENOTTY; /* Other cmds not supported. */
+ }
+} /* qic02_tape_ioctl */
/* These are (most) of the interface functions: */
static struct file_operations qic02_tape_fops = {
- owner: THIS_MODULE,
- llseek: no_llseek,
- read: qic02_tape_read,
- write: qic02_tape_write,
- ioctl: qic02_tape_ioctl,
- open: qic02_tape_open,
- release: qic02_tape_release,
+ owner:THIS_MODULE,
+ llseek:no_llseek,
+ read:qic02_tape_read,
+ write:qic02_tape_write,
+ ioctl:qic02_tape_ioctl,
+ open:qic02_tape_open,
+ release:qic02_tape_release,
};
static void qic02_release_resources(void)
{
- free_irq(QIC02_TAPE_IRQ, NULL);
- free_dma(QIC02_TAPE_DMA);
- release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
- if (buffaddr)
- {
- free_pages((unsigned long)buffaddr, get_order(TPQBUF_SIZE));
- }
- buffaddr = 0; /* Better to cause a panic than overwite someone else */
- status_zombie = YES;
-} /* qic02_release_resources */
+ free_irq(QIC02_TAPE_IRQ, NULL);
+ free_dma(QIC02_TAPE_DMA);
+ release_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
+ if (buffaddr) {
+ free_pages((unsigned long) buffaddr,
+ get_order(TPQBUF_SIZE));
+ }
+ buffaddr = 0; /* Better to cause a panic than overwite someone else */
+ status_zombie = YES;
+} /* qic02_release_resources */
static int qic02_get_resources(void)
{
- /* First perform some checks. If one of them fails,
- * the tape driver will not be registered to the system.
- */
- if (QIC02_TAPE_IRQ>16)
- {
- tpqputs(TPQD_ALWAYS, "Bogus interrupt number.");
- return -ENXIO;
- }
-
- /* for DYNCONF, allocating IO, DMA and IRQ should not be done until
- * the config parameters have been set using MTSETCONFIG.
- */
-
- if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE))
- {
- printk(TPQIC02_NAME ": IO space at 0x%x [%d ports] already reserved\n",
- QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
- return -ENXIO;
- }
-
- /* get IRQ */
- if (request_irq(QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02", NULL))
- {
- printk(TPQIC02_NAME ": can't allocate IRQ%d for QIC-02 tape\n",
- QIC02_TAPE_IRQ);
- return -EBUSY;
- }
-
- /* After IRQ, allocate DMA channel */
- if (request_dma(QIC02_TAPE_DMA,"QIC-02"))
- {
- printk(TPQIC02_NAME ": can't allocate DMA%d for QIC-02 tape\n",
- QIC02_TAPE_DMA);
- free_irq(QIC02_TAPE_IRQ, NULL);
- return -EBUSY;
- }
-
- /* Grab the IO region. We already made sure it's available. */
- request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE, TPQIC02_NAME);
-
- /* Setup the page-address for the dma transfer. */
- buffaddr = (void *)__get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
-
- if (!buffaddr)
- {
- qic02_release_resources();
- return -EBUSY; /* Not ideal, EAGAIN perhaps? */
- }
-
- memset(buffaddr, 0, TPQBUF_SIZE);
-
- printk(TPQIC02_NAME ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
- QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
- ((QIC02_TAPE_IFC==ARCHIVE) || (QIC02_TAPE_IFC==MOUNTAIN))?
- QIC02_CMD_PORT : QIC02_STAT_PORT,
- (QIC02_TAPE_IFC==MOUNTAIN)? "Mountain" :
- ((QIC02_TAPE_IFC==ARCHIVE)? "Archive" : "Wangtek"));
-
- if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK)
- {
- /* No drive detected, so vanish */
- tpqputs(TPQD_ALWAYS, "No drive detected -- releasing IO/IRQ/DMA.");
- status_dead = YES;
- qic02_release_resources();
- return -EIO;
- }
-
- /* All should be ok now */
- status_zombie = NO;
- return 0;
-} /* qic02_get_resources */
+ /* First perform some checks. If one of them fails,
+ * the tape driver will not be registered to the system.
+ */
+ if (QIC02_TAPE_IRQ > 16) {
+ tpqputs(TPQD_ALWAYS, "Bogus interrupt number.");
+ return -ENXIO;
+ }
+
+ /* for DYNCONF, allocating IO, DMA and IRQ should not be done until
+ * the config parameters have been set using MTSETCONFIG.
+ */
+
+ if (check_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE)) {
+ printk(TPQIC02_NAME
+ ": IO space at 0x%x [%d ports] already reserved\n",
+ QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE);
+ return -ENXIO;
+ }
+
+ /* get IRQ */
+ if (request_irq
+ (QIC02_TAPE_IRQ, qic02_tape_interrupt, SA_INTERRUPT, "QIC-02",
+ NULL)) {
+ printk(TPQIC02_NAME
+ ": can't allocate IRQ%d for QIC-02 tape\n",
+ QIC02_TAPE_IRQ);
+ return -EBUSY;
+ }
+
+ /* After IRQ, allocate DMA channel */
+ if (request_dma(QIC02_TAPE_DMA, "QIC-02")) {
+ printk(TPQIC02_NAME
+ ": can't allocate DMA%d for QIC-02 tape\n",
+ QIC02_TAPE_DMA);
+ free_irq(QIC02_TAPE_IRQ, NULL);
+ return -EBUSY;
+ }
+
+ /* Grab the IO region. We already made sure it's available. */
+ request_region(QIC02_TAPE_PORT, QIC02_TAPE_PORT_RANGE,
+ TPQIC02_NAME);
+
+ /* Setup the page-address for the dma transfer. */
+ buffaddr =
+ (void *) __get_dma_pages(GFP_KERNEL, get_order(TPQBUF_SIZE));
+
+ if (!buffaddr) {
+ qic02_release_resources();
+ return -EBUSY; /* Not ideal, EAGAIN perhaps? */
+ }
+
+ memset(buffaddr, 0, TPQBUF_SIZE);
+
+ printk(TPQIC02_NAME
+ ": Settings: IRQ %d, DMA %d, IO 0x%x, IFC %s\n",
+ QIC02_TAPE_IRQ, QIC02_TAPE_DMA, ((QIC02_TAPE_IFC == ARCHIVE)
+ || (QIC02_TAPE_IFC ==
+ MOUNTAIN)) ?
+ QIC02_CMD_PORT : QIC02_STAT_PORT,
+ (QIC02_TAPE_IFC ==
+ MOUNTAIN) ? "Mountain" : ((QIC02_TAPE_IFC ==
+ ARCHIVE) ? "Archive" :
+ "Wangtek"));
+
+ if (tape_reset(0) != TE_OK
+ || tp_sense(TP_WRP | TP_POR | TP_CNI) != TE_OK) {
+ /* No drive detected, so vanish */
+ tpqputs(TPQD_ALWAYS,
+ "No drive detected -- releasing IO/IRQ/DMA.");
+ status_dead = YES;
+ qic02_release_resources();
+ return -EIO;
+ }
+
+ /* All should be ok now */
+ status_zombie = NO;
+ return 0;
+} /* qic02_get_resources */
int __init qic02_tape_init(void)
{
- if (TPSTATSIZE != 6)
- {
- printk(TPQIC02_NAME ": internal error: tpstatus struct incorrect!\n");
- return -ENODEV;
- }
- if ((TPQBUF_SIZE<512) || (TPQBUF_SIZE>=0x10000))
- {
- printk(TPQIC02_NAME ": internal error: DMA buffer size out of range\n");
- return -ENODEV;
- }
-
- current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0);
+ if (TPSTATSIZE != 6) {
+ printk(TPQIC02_NAME
+ ": internal error: tpstatus struct incorrect!\n");
+ return -ENODEV;
+ }
+ if ((TPQBUF_SIZE < 512) || (TPQBUF_SIZE >= 0x10000)) {
+ printk(TPQIC02_NAME
+ ": internal error: DMA buffer size out of range\n");
+ return -ENODEV;
+ }
+
+ current_tape_dev = MKDEV(QIC02_TAPE_MAJOR, 0);
#ifndef CONFIG_QIC02_DYNCONF
- printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n",
- QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
+ printk(TPQIC02_NAME ": IRQ %d, DMA %d, IO 0x%x, IFC %s, %s, %s\n",
+ QIC02_TAPE_IRQ, QIC02_TAPE_DMA,
# if QIC02_TAPE_IFC == WANGTEK
- QIC02_STAT_PORT, "Wangtek",
+ QIC02_STAT_PORT, "Wangtek",
# elif QIC02_TAPE_IFC == ARCHIVE
- QIC02_CMD_PORT, "Archive",
+ QIC02_CMD_PORT, "Archive",
# elif QIC02_TAPE_IFC == MOUNTAIN
- QIC02_CMD_PORT, "Mountain",
+ QIC02_CMD_PORT, "Mountain",
# else
# error
# endif
- rcs_revision, rcs_date);
- if (qic02_get_resources())
- {
- return -ENODEV;
- }
+ rcs_revision, rcs_date);
+ if (qic02_get_resources()) {
+ return -ENODEV;
+ }
#else
- printk(TPQIC02_NAME ": Runtime config, %s, %s\n",
- rcs_revision, rcs_date);
+ printk(TPQIC02_NAME ": Runtime config, %s, %s\n",
+ rcs_revision, rcs_date);
#endif
- printk(TPQIC02_NAME ": DMA buffers: %u blocks\n", NR_BLK_BUF);
- /* If we got this far, install driver functions */
- if (devfs_register_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops))
- {
- printk(TPQIC02_NAME ": Unable to get chrdev major %d\n", QIC02_TAPE_MAJOR);
+ printk(TPQIC02_NAME ": DMA buffers: %u blocks\n", NR_BLK_BUF);
+ /* If we got this far, install driver functions */
+ if (devfs_register_chrdev
+ (QIC02_TAPE_MAJOR, TPQIC02_NAME, &qic02_tape_fops)) {
+ printk(TPQIC02_NAME ": Unable to get chrdev major %d\n",
+ QIC02_TAPE_MAJOR);
#ifndef CONFIG_QIC02_DYNCONF
- qic02_release_resources();
+ qic02_release_resources();
#endif
- return -ENODEV;
- }
- devfs_register (NULL, "ntpqic11", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 2,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "tpqic11", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 3,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "ntpqic24", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 4,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "tpqic24", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 5,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "ntpqic120", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 6,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "tpqic120", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 7,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "ntpqic150", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 8,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- devfs_register (NULL, "tpqic150", DEVFS_FL_DEFAULT,
- QIC02_TAPE_MAJOR, 9,
- S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
- &qic02_tape_fops, NULL);
- init_waitqueue_head(&qic02_tape_transfer);
- /* prepare timer */
- TIMEROFF;
- init_timer(&tp_timer);
- tp_timer.function = qic02_tape_times_out;
-
+ return -ENODEV;
+ }
+ devfs_register(NULL, "ntpqic11", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 2,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "tpqic11", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 3,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "ntpqic24", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 4,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "tpqic24", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 5,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "ntpqic120", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 6,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "tpqic120", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 7,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "ntpqic150", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 8,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ devfs_register(NULL, "tpqic150", DEVFS_FL_DEFAULT,
+ QIC02_TAPE_MAJOR, 9,
+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+ &qic02_tape_fops, NULL);
+ init_waitqueue_head(&qic02_tape_transfer);
+ /* prepare timer */
+ TIMEROFF;
+ init_timer(&tp_timer);
+ tp_timer.function = qic02_tape_times_out;
+
#ifndef CONFIG_QIC02_DYNCONF
- if (tape_reset(0)!=TE_OK || tp_sense(TP_WRP|TP_POR|TP_CNI)!=TE_OK)
- {
- /* No drive detected, so vanish */
- tpqputs(TPQD_ALWAYS, "No drive detected -- driver going on vacation...");
- qic02_release_resources();
- status_dead = YES;
- return -ENODEV;
- }
- else
- {
- if (is_exception())
- {
- tpqputs(TPQD_ALWAYS, "exception detected\n");
- (void) tp_sense(TP_WRP|TP_POR|TP_CNI);
+ if (tape_reset(0) != TE_OK
+ || tp_sense(TP_WRP | TP_POR | TP_CNI) != TE_OK) {
+ /* No drive detected, so vanish */
+ tpqputs(TPQD_ALWAYS,
+ "No drive detected -- driver going on vacation...");
+ qic02_release_resources();
+ status_dead = YES;
+ return -ENODEV;
+ } else {
+ if (is_exception()) {
+ tpqputs(TPQD_ALWAYS, "exception detected\n");
+ (void) tp_sense(TP_WRP | TP_POR | TP_CNI);
+ }
}
- }
#endif
- /* initialize generic status for ioctl requests */
-
- ioctl_status.mt_type = QIC02_TAPE_DRIVE; /* MT_IS* id nr */
-
- ioctl_status.mt_resid = 0; /* ---residual count */
- ioctl_status.mt_gstat = 0; /* ---generic status */
- ioctl_status.mt_erreg = 0; /* not used */
- ioctl_status.mt_fileno = 0; /* number of current file on tape */
- ioctl_status.mt_blkno = 0; /* number of current (logical) block */
+ /* initialize generic status for ioctl requests */
+
+ ioctl_status.mt_type = QIC02_TAPE_DRIVE; /* MT_IS* id nr */
- return 0;
-} /* qic02_tape_init */
+ ioctl_status.mt_resid = 0; /* ---residual count */
+ ioctl_status.mt_gstat = 0; /* ---generic status */
+ ioctl_status.mt_erreg = 0; /* not used */
+ ioctl_status.mt_fileno = 0; /* number of current file on tape */
+ ioctl_status.mt_blkno = 0; /* number of current (logical) block */
+
+ return 0;
+} /* qic02_tape_init */
#ifdef MODULE
void cleanup_module(void)
{
- if (status_zombie == NO)
- {
- qic02_release_resources();
- }
- devfs_unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
- devfs_unregister(devfs_find_handle(NULL, "ntpqic11", QIC02_TAPE_MAJOR, 2, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "tpqic11", QIC02_TAPE_MAJOR, 3, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "ntpqic24", QIC02_TAPE_MAJOR, 4, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "tpqic24", QIC02_TAPE_MAJOR, 5, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "ntpqic120", QIC02_TAPE_MAJOR, 6, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "tpqic120", QIC02_TAPE_MAJOR, 7, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "ntpqic150", QIC02_TAPE_MAJOR, 8, DEVFS_SPECIAL_CHR, 0));
- devfs_unregister(devfs_find_handle(NULL, "tpqic150", QIC02_TAPE_MAJOR, 9, DEVFS_SPECIAL_CHR, 0));
+ if (status_zombie == NO) {
+ qic02_release_resources();
+ }
+ devfs_unregister_chrdev(QIC02_TAPE_MAJOR, TPQIC02_NAME);
+ devfs_unregister(devfs_find_handle
+ (NULL, "ntpqic11", QIC02_TAPE_MAJOR, 2,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "tpqic11", QIC02_TAPE_MAJOR, 3,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "ntpqic24", QIC02_TAPE_MAJOR, 4,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "tpqic24", QIC02_TAPE_MAJOR, 5,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "ntpqic120", QIC02_TAPE_MAJOR, 6,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "tpqic120", QIC02_TAPE_MAJOR, 7,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "ntpqic150", QIC02_TAPE_MAJOR, 8,
+ DEVFS_SPECIAL_CHR, 0));
+ devfs_unregister(devfs_find_handle
+ (NULL, "tpqic150", QIC02_TAPE_MAJOR, 9,
+ DEVFS_SPECIAL_CHR, 0));
}
int init_module(void)
{
- int retval;
- retval=qic02_tape_init();
+ int retval;
+ retval = qic02_tape_init();
# ifdef CONFIG_QIC02_DYNCONF
- /* This allows the dynamic config program to setup the card
- * by presetting qic02_tape_dynconf via insmod
- */
- if (!retval && qic02_tape_dynconf.ifc_type)
- {
- retval=update_ifc_masks(qic02_tape_dynconf.ifc_type);
- if (retval)
- {
- cleanup_module();
+ /* This allows the dynamic config program to setup the card
+ * by presetting qic02_tape_dynconf via insmod
+ */
+ if (!retval && qic02_tape_dynconf.ifc_type) {
+ retval = update_ifc_masks(qic02_tape_dynconf.ifc_type);
+ if (retval) {
+ cleanup_module();
+ }
}
- }
# endif
- return retval;
+ return retval;
}
#endif
+
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
file_list_lock();
for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) {
struct file * filp = list_entry(l, struct file, f_list);
- if (!filp->f_dentry)
- continue;
if (filp->f_dentry->d_inode->i_rdev == CONSOLE_DEV ||
filp->f_dentry->d_inode->i_rdev == SYSCONS_DEV) {
cons_filp = filp;
+++ /dev/null
-/* $Id: vino.h,v 1.2 1999/02/09 23:03:53 ulfc Exp $
- * drivers/sgi/vino.h
- *
- * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
- */
-
-#define VINO_BASE 0x0008000
-
-#define VINO_REVID 0x0000
-#define VINO_CTRL 0x0008
-#define VINO_INTSTAT 0x0010 /* Interrupt status */
-#define VINO_I2C_CTRL 0x0018
-#define VINO_I2C_DATA 0x0020
-#define VINO_A_ALPHA 0x0028 /* Channel A ... */
-#define VINO_A_CLIPS 0x0030 /* Clipping start */
-#define VINO_A_CLIPE 0x0038 /* Clipping end */
-#define VINO_A_FRAMERT 0x0040 /* Framerate */
-#define VINO_A_FLDCNT 0x0048 /* Field counter */
-#define VINO_A_LNSZ 0x0050
-#define VINO_A_LNCNT 0x0058
-#define VINO_A_PGIX 0x0060 /* Page index */
-#define VINO_A_DESC_PTR 0x0068 /* Ptr to next four descriptors */
-#define VINO_A_DESC_TLB_PTR 0x0070 /* Ptr to start of descriptor table */
-#define VINO_A_DESC_DATA0 0x0078 /* Descriptor data 0 */
-#define VINO_A_DESC_DATA1 0x0080 /* ... */
-#define VINO_A_DESC_DATA2 0x0088
-#define VINO_A_DESC_DATA3 0x0090
-#define VINO_A_FIFO_THRESHOLD 0x0098 /* FIFO threshold */
-#define VINO_A_FIFO_RP 0x00a0
-#define VINO_A_FIFO_WP 0x00a8
-#define VINO_B_ALPHA 0x00b0 /* Channel B ... */
-#define VINO_B_CLIPS 0x00b8
-#define VINO_B_CLIPE 0x00c0
-#define VINO_B_FRAMERT 0x00c8
-#define VINO_B_FLDCNT 0x00d0
-#define VINO_B_LNSZ 0x00d8
-#define VINO_B_LNCNT 0x00e0
-#define VINO_B_PGIX 0x00e8
-#define VINO_B_DESC_PTR 0x00f0
-#define VINO_B_DESC_TLB_PTR 0x00f8
-#define VINO_B_DESC_DATA0 0x0100
-#define VINO_B_DESC_DATA1 0x0108
-#define VINO_B_DESC_DATA2 0x0110
-#define VINO_B_DESC_DATA3 0x0118
-#define VINO_B_FIFO_THRESHOLD 0x0120
-#define VINO_B_FIFO_RP 0x0128
-#define VINO_B_FIFO_WP 0x0130
-
-/* Bits in the VINO_REVID register */
-
-#define VINO_REVID_REV_MASK 0x000f /* bits 0:3 */
-#define VINO_REVID_ID_MASK 0x00f0 /* bits 4:7 */
-
-/* Bits in the VINO_CTRL register */
-
-#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
-#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */
-#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */
-#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */
-#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */
-#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */
-#define VINO_CTRL_B_END_DESC_TLB_INT (1<<6) /* End of desc table int */
-#define VINO_CTRL_A_DMA_ENBL (1<<7)
-#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
-#define VINO_CTRL_A_SYNC_ENBL (1<<9)
-#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
-#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
-#define VINO_CTRL_A_LUMA_ONLY (1<<12)
-#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
-#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
-#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
-#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
-#define VINO_CTRL_B_DMA_ENBL (1<<19)
-#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
-#define VINO_CTRL_B_SYNC_ENBL (1<<21)
-#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
-#define VINO_CTRL_B_RGB (1<<22) /* 1=RGB 0=YUV */
-#define VINO_CTRL_B_LUMA_ONLY (1<<23)
-#define VINO_CTRL_B_DEC_ENBL (1<<24) /* Decimation */
-#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 25:28 */
-#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
-#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
-
-/* Bits in the Interrupt and Status register */
-
-#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */
-#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */
-#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */
-#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */
-#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */
-#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */
-
-/* Bits in the Clipping Start register */
-
-#define VINO_CLIPS_START 0x3ff /* bits 0:9 */
-#define VINO_CLIPS_ODD_MASK 0x7fc00 /* bits 10:18 */
-#define VINO_CLIPS_EVEN_MASK 0xff80000 /* bits 19:27 */
-
-/* Bits in the Clipping End register */
-
-#define VINO_CLIPE_END 0x3ff /* bits 0:9 */
-#define VINO_CLIPE_ODD_MASK 0x7fc00 /* bits 10:18 */
-#define VINO_CLIPE_EVEN_MASK 0xff80000 /* bits 19:27 */
-
-/* Bits in the Frame Rate register */
-
-#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
-#define VINO_FRAMERT_RT_MASK 0x1ffe /* bits 1:12 */
-
-/* Bits in the VINO_I2C_CTRL */
-
-#define VINO_CTRL_I2C_IDLE (1<<0) /* write: 0=force idle
- * read: 0=idle 1=not idle */
-#define VINO_CTRL_I2C_DIR (1<<1) /* 0=read 1=write */
-#define VINO_CTRL_I2C_MORE_BYTES (1<<2) /* 0=last byte 1=more bytes */
-#define VINO_CTRL_I2C_TRANS_BUSY (1<<4) /* 0=trans done 1=trans busy */
-#define VINO_CTRL_I2C_ACK (1<<5) /* 0=ack received 1=ack not */
-#define VINO_CTRL_I2C_BUS_ERROR (1<<7) /* 0=no bus err 1=bus err */
module_init(wdt_init);
module_exit(wdt_exit);
+MODULE_AUTHOR("Alan Cox");
+MODULE_DESCRIPTION("Driver for ISA ICS watchdog cards (WDT500/501)");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
MODULE_AUTHOR("Phil Blundell <pb@nexus.co.uk>");
MODULE_DESCRIPTION("21285 watchdog driver");
+MODULE_LICENSE("GPL");
MODULE_PARM(soft_margin,"i");
MODULE_PARM_DESC(soft_margin,"Watchdog timeout in seconds");
module_init(nwwatchdog_init);
module_exit(nwwatchdog_exit);
+
+MODULE_LICENSE("GPL");
module_init(wdtpci_init);
module_exit(wdtpci_cleanup);
+
+MODULE_AUTHOR("JP Nollmann, Alan Cox");
+MODULE_DESCRIPTION("Driver for the ICS PCI watchdog cards");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
if [ "$CONFIG_BLK_DEV_IDEDISK" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool ' PROMISE DC4030 support (EXPERIMENTAL)' CONFIG_BLK_DEV_PDC4030
fi
- bool ' QDI QD6580 support' CONFIG_BLK_DEV_QD6580
+ bool ' QDI QD65xx support' CONFIG_BLK_DEV_QD65XX
bool ' UMC-8672 support' CONFIG_BLK_DEV_UMC8672
fi
fi
ide-obj-$(CONFIG_BLK_DEV_PDC4030) += pdc4030.o
ide-obj-$(CONFIG_BLK_DEV_PDC_ADMA) += pdcadma.o
ide-obj-$(CONFIG_BLK_DEV_PIIX) += piix.o
-ide-obj-$(CONFIG_BLK_DEV_QD6580) += qd6580.o
+ide-obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
ide-obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
ide-obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o
ide-obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o
/*
- * linux/drivers/ide/ide-floppy.c Version 0.9.sv Jan 6 2001
+ * linux/drivers/ide/ide-floppy.c Version 0.97.sv Jan 14 2001
*
* Copyright (C) 1996 - 1999 Gadi Oxman <gadio@netvision.net.il>
+ * Copyright (C) 2000 - 2001 Paul Bristow <paul@paulbristow.net>
*/
/*
* The driver currently doesn't have any fancy features, just the bare
* minimum read/write support.
*
+ * This driver supports the following IDE floppy drives:
+ *
+ * LS-120 SuperDisk
+ * Iomega Zip 100/250
+ * Iomega PC Card Clik!/PocketZip
+ *
* Many thanks to Lode Leroy <Lode.Leroy@www.ibase.be>, who tested so many
* ALPHA patches to this driver on an EASYSTOR LS-120 ATAPI floppy drive.
*
* mode page. Implemented four IOCTLs in order to
* implement formatting. IOCTls begin with 0x4600,
* 0x46 is 'F' as in Format.
+ * Jan 9 01 Userland option to select format verify.
+ * Added PC_SUPPRESS_ERROR flag - some idefloppy drives
+ * do not implement IDEFLOPPY_CAPABILITIES_PAGE, and
+ * return a sense error. Suppress error reporting in
+ * this particular case in order to avoid spurious
+ * errors in syslog. The culprit is
+ * idefloppy_get_capability_page(), so move it to
+ * idefloppy_begin_format() so that it's not used
+ * unless absolutely necessary.
+ * If drive does not support format progress indication
+ * monitor the dsc bit in the status register.
+ * Also, O_NDELAY on open will allow the device to be
+ * opened without a disk available. This can be used to
+ * open an unformatted disk, or get the device capacity.
* Ver 0.91 Dec 11 99 Added IOMEGA Clik! drive support by
* <paul@paulbristow.net>
* Ver 0.92 Oct 22 00 Paul Bristow became official maintainer for this
* Ver 0.96 Jan 7 01 Actually in line with release version of 2.4.0
* including set_bit patch from Rusty Russel
* Ver 0.97 Jul 22 01 Merge 0.91-0.96 onto 0.9.sv for ac series
+ * Ver 0.97.sv Aug 3 01 Backported from 2.4.7-ac3
*/
-#define IDEFLOPPY_VERSION "0.97"
+#define IDEFLOPPY_VERSION "0.97.sv"
#include <linux/config.h>
#include <linux/module.h>
#define PC_DMA_ERROR 4 /* 1 when encountered problem during DMA */
#define PC_WRITING 5 /* Data direction */
+#define PC_SUPPRESS_ERROR 6 /* Suppress error reporting */
+
/*
* Removable Block Access Capabilities Page
*/
* a legitimate error code was received.
*/
if (!test_bit (PC_ABORT, &pc->flags)) {
- printk (KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
+ if (!test_bit (PC_SUPPRESS_ERROR, &pc->flags)) {
+ ;
+ printk( KERN_ERR "ide-floppy: %s: I/O error, pc = %2x, key = %2x, asc = %2x, ascq = %2x\n",
drive->name, pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
+ }
pc->error = IDEFLOPPY_ERROR_GENERAL; /* Giving up */
}
floppy->failed_pc=NULL;
pc->request_transfer = 255;
}
-static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l)
+static void idefloppy_create_format_unit_cmd (idefloppy_pc_t *pc, int b, int l,
+ int flags)
{
idefloppy_init_pc (pc);
pc->c[0] = IDEFLOPPY_FORMAT_UNIT_CMD;
pc->c[1] = 0x17;
memset(pc->buffer, 0, 12);
- pc->buffer[1] = 0xA2; /* Format list header, byte 1: FOV/DCRT/IMM */
+ pc->buffer[1] = 0xA2;
+ /* Default format list header, byte 1: FOV/DCRT/IMM bits set */
+
+ if (flags & 1) /* Verify bit on... */
+ pc->buffer[1] ^= 0x20; /* ... turn off DCRT bit */
pc->buffer[3] = 8;
put_unaligned(htonl(b), (unsigned int *)(&pc->buffer[4]));
floppy->srfp=0;
idefloppy_create_mode_sense_cmd (&pc, IDEFLOPPY_CAPABILITIES_PAGE,
MODE_SENSE_CURRENT);
+
+ set_bit(PC_SUPPRESS_ERROR, &pc.flags);
if (idefloppy_queue_pc_tail (drive,&pc)) {
return 1;
}
+
header = (idefloppy_mode_parameter_header_t *) pc.buffer;
page= (idefloppy_capabilities_page_t *)(header+1);
floppy->srfp=page->srfp;
if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags))
{
(void) idefloppy_get_flexible_disk_page (drive);
- (void) idefloppy_get_capability_page (drive);
}
drive->part[0].nr_sects = floppy->blocks * floppy->bs_factor;
** struct idefloppy_format_command {
** int nblocks;
** int blocksize;
+** int flags;
** } ;
+**
+** flags is a bitmask, currently, the only defined flag is:
+**
+** 0x01 - verify media after format.
*/
static int idefloppy_begin_format(ide_drive_t *drive,
{
int blocks;
int length;
+ int flags;
idefloppy_pc_t pc;
if (get_user(blocks, arg)
- || get_user(length, arg+1))
+ || get_user(length, arg+1)
+ || get_user(flags, arg+2))
{
return (-EFAULT);
}
- idefloppy_create_format_unit_cmd(&pc, blocks, length);
+ (void) idefloppy_get_capability_page (drive); /* Get the SFRP bit */
+ idefloppy_create_format_unit_cmd(&pc, blocks, length, flags);
if (idefloppy_queue_pc_tail (drive, &pc))
{
return (-EIO);
** Userland gives a pointer to an int. The int is set to a progresss
** indicator 0-65536, with 65536=100%.
**
-** If the drive does not support format progress indication, we just return
-** a 65536, screw it.
+** If the drive does not support format progress indication, we just check
+** the dsc bit, and return either 0 or 65536.
*/
static int idefloppy_get_format_progress(ide_drive_t *drive,
{
progress_indication=floppy->progress_indication;
}
+ /* Else assume format_unit has finished, and we're
+ ** at 0x10000 */
}
+ else
+ {
+ idefloppy_status_reg_t status;
+ unsigned long flags;
+ __save_flags(flags);
+ __cli();
+ status.all=GET_STAT();
+ __restore_flags(flags);
+
+ progress_indication= !status.b.dsc ? 0:0x10000;
+ }
if (put_user(progress_indication, arg))
return (-EFAULT);
{
idefloppy_floppy_t *floppy = drive->driver_data;
- set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
-
if (drive->usage > 1)
{
/* Don't format if someone is using the disk */
}
else
{
- int rc=idefloppy_begin_format(drive, inode,
+ int rc;
+
+ set_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
+ &floppy->flags);
+
+ rc=idefloppy_begin_format(drive, inode,
file,
(int *)arg);
MOD_INC_USE_COUNT;
if (drive->usage == 1) {
-
clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
/* Just in case */
(void) idefloppy_queue_pc_tail (drive, &pc);
}
- if (idefloppy_get_capacity (drive)) {
+ if (idefloppy_get_capacity (drive)
+ && (filp->f_flags & O_NDELAY) == 0
+ /*
+ ** Allow O_NDELAY to open a drive without a disk, or with
+ ** an unreadable disk, so that we can get the format
+ ** capacity of the drive or begin the format - Sam
+ */
+ ) {
drive->usage--;
MOD_DEC_USE_COUNT;
return -EIO;
for (i = 0; i < 1 << PARTN_BITS; i++)
max_sectors[major][minor + i] = 64;
}
+ /*
+ * Guess what? The IOMEGA Clik! drive also needs the
+ * above fix. It makes nasty clicking noises without
+ * it, so please don't remove this.
+ */
+ if (strcmp(drive->id->model, "IOMEGA Clik! 40 CZ ATAPI") == 0)
+ {
+ for (i = 0; i < 1 << PARTN_BITS; i++)
+ max_sectors[major][minor + i] = 64;
+ set_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags);
+ }
/*
* Guess what? The IOMEGA Clik! drive also needs the
case ide_cmd640: name = "cmd640"; break;
case ide_dtc2278: name = "dtc2278"; break;
case ide_ali14xx: name = "ali14xx"; break;
- case ide_qd6580: name = "qd6580"; break;
+ case ide_qd65xx: name = "qd65xx"; break;
case ide_umc8672: name = "umc8672"; break;
case ide_ht6560b: name = "ht6560b"; break;
case ide_pdc4030: name = "pdc4030"; break;
* "ide0=ht6560b" : probe/support HT6560B interface
* "ide0=cmd640_vlb" : *REQUIRED* for VLB cards with the CMD640 chip
* (not for PCI -- automatically detected)
- * "ide0=qd6580" : probe/support qd6580 interface
+ * "ide0=qd65xx" : probe/support qd65xx interface
* "ide0=ali14xx" : probe/support ali14xx chipsets (ALI M1439, M1443, M1445)
* "ide0=umc8672" : probe/support umc8672 chipsets
* "idex=dc4030" : probe/support Promise DC4030VL interface
const char *ide_words[] = {
"noprobe", "serialize", "autotune", "noautotune", "reset", "dma", "ata66",
"minus8", "minus9", "minus10",
- "four", "qd6580", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
+ "four", "qd65xx", "ht6560b", "cmd640_vlb", "dtc2278", "umc8672", "ali14xx", "dc4030", NULL };
hw = s[3] - '0';
hwif = &ide_hwifs[hw];
i = match_parm(&s[4], ide_words, vals, 3);
goto done;
}
#endif /* CONFIG_BLK_DEV_HT6560B */
-#if CONFIG_BLK_DEV_QD6580
- case -12: /* "qd6580" */
+#if CONFIG_BLK_DEV_QD65XX
+ case -12: /* "qd65xx" */
{
- extern void init_qd6580 (void);
- init_qd6580();
+ extern void init_qd65xx (void);
+ init_qd65xx();
goto done;
}
-#endif /* CONFIG_BLK_DEV_QD6580 */
+#endif /* CONFIG_BLK_DEV_QD65XX */
#ifdef CONFIG_BLK_DEV_4DRIVES
case -11: /* "four" drives on one set of ports */
{
*
* Copyright 2000 MontaVista Software Inc.
* Author: MontaVista Software, Inc.
- * stevel@mvista.com or support@mvista.com
+ * stevel@mvista.com or source@mvista.com
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
void __init ide_init_it8172 (ide_hwif_t *hwif);
-/*
- * Based on settings done by AMI BIOS
- * (might be usefull if drive is not registered in CMOS for any reason).
- */
static void it8172_tune_drive (ide_drive_t *drive, byte pio)
{
unsigned long flags;
u16 master_data;
- byte slave_data;
+ u32 slave_data;
int is_slave = (&HWIF(drive)->drives[1] == drive);
- int master_port = HWIF(drive)->index ? 0x42 : 0x40;
- int slave_port = 0x44;
- /* ISP RTC */
- byte timings[][2] = { { 0, 0 },
- { 0, 0 },
- { 1, 0 },
- { 2, 1 },
- { 2, 3 }, };
-
+ int master_port = 0x40;
+ int slave_port = 0x44;
+
pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
pci_read_config_word(HWIF(drive)->pci_dev, master_port, &master_data);
+ pci_read_config_dword(HWIF(drive)->pci_dev, slave_port, &slave_data);
+
+ /*
+ * FIX! The DIOR/DIOW pulse width and recovery times in port 0x44
+ * are being left at the default values of 8 PCI clocks (242 nsec
+ * for a 33 MHz clock). These can be safely shortened at higher
+ * PIO modes.
+ */
+
if (is_slave) {
- master_data = master_data | 0x4000;
+ master_data |= 0x4000;
if (pio > 1)
- /* enable PPE, IE and TIME */
- master_data = master_data | 0x0070;
- pci_read_config_byte(HWIF(drive)->pci_dev, slave_port, &slave_data);
- slave_data = slave_data & (HWIF(drive)->index ? 0x0f : 0xf0);
- slave_data = slave_data |
- ((timings[pio][0] << 2) | (timings[pio][1]
- << (HWIF(drive)->index ? 4 : 0)));
+ /* enable PPE and IE */
+ master_data |= 0x0060;
} else {
- master_data = master_data & 0xccf8;
+ master_data &= 0xc060;
if (pio > 1)
- /* enable PPE, IE and TIME */
- master_data = master_data | 0x0007;
- master_data = master_data | (timings[pio][0] << 12) |
- (timings[pio][1] << 8);
+ /* enable PPE and IE */
+ master_data |= 0x0006;
}
+
save_flags(flags);
cli();
pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data);
- if (is_slave)
- pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data);
restore_flags(flags);
}
pci_read_config_byte(dev, 0x48, ®48);
pci_read_config_byte(dev, 0x4a, ®4a);
+ /*
+ * Setting the DMA cycle time to 2 or 3 PCI clocks (60 and 91 nsec
+ * at 33 MHz PCI clock) seems to cause BadCRC errors during DMA
+ * transfers on some drives, even though both numbers meet the minimum
+ * ATAPI-4 spec of 73 and 54 nsec for UDMA 1 and 2 respectively.
+ * So the faster times are just commented out here. The good news is
+ * that the slower cycle time has very little affect on transfer
+ * performance.
+ */
+
switch(speed) {
case XFER_UDMA_4:
- case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break;
+ case XFER_UDMA_2: //u_speed = 2 << (drive->dn * 4); break;
case XFER_UDMA_5:
case XFER_UDMA_3:
- case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break;
+ case XFER_UDMA_1: //u_speed = 1 << (drive->dn * 4); break;
case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break;
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
}
if (speed >= XFER_UDMA_0) {
- if (!(reg48 & u_flag))
- pci_write_config_byte(dev, 0x48, reg48|u_flag);
- if (!(reg4a & u_speed)) {
- pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
- pci_write_config_byte(dev, 0x4a, reg4a|u_speed);
- }
- }
- if (speed < XFER_UDMA_0) {
- if (reg48 & u_flag)
- pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
- if (reg4a & a_speed)
- pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
+ pci_write_config_byte(dev, 0x48, reg48 | u_flag);
+ reg4a &= ~a_speed;
+ pci_write_config_byte(dev, 0x4a, reg4a | u_speed);
+ } else {
+ pci_write_config_byte(dev, 0x48, reg48 & ~u_flag);
+ pci_write_config_byte(dev, 0x4a, reg4a & ~a_speed);
}
it8172_tune_drive(drive, it8172_dma_2_pio(speed));
-#if IT8172_DEBUG
- printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
-#endif
if (!drive->init_speed)
drive->init_speed = speed;
err = ide_config_drive_speed(drive, speed);
/* Other cases are done by generic IDE-DMA code. */
return ide_dmaproc(func, drive);
}
+
#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_IT8172_TUNING) */
+
unsigned int __init pci_init_it8172 (struct pci_dev *dev, const char *name)
{
unsigned char progif;
switch(dev->device) {
case PCI_DEVICE_ID_PROMISE_20268:
+ case PCI_DEVICE_ID_PROMISE_20268R:
p += sprintf(p, "\n PDC20268 TX2 Chipset.\n");
invalid_data_set = 1;
break;
+++ /dev/null
-/*
- * linux/drivers/ide/qd6580.c Version 0.04 June 4, 2000
- *
- * Copyright (C) 1996-2000 Linus Torvalds & author (see below)
- */
-
-/*
- * Version 0.03 Cleaned auto-tune, added probe
- * Version 0.04 Added second channel tuning
- *
- * QDI QD6580 EIDE controller fast support
- *
- * To activate controller support use kernel parameter "ide0=qd6580"
- * To enable tuning use kernel parameter "ide0=autotune"
- * To enable tuning second channel (not really tested),
- * use parameter "ide1=autotune"
- */
-
-/*
- * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
- * Samuel Thibault <samuel.thibault@fnac.net>
- */
-
-#undef REALLY_SLOW_IO /* most systems can safely undef this */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ide.h>
-#include <linux/init.h>
-
-#include <asm/io.h>
-
-#include "ide_modes.h"
-
-/*
- * I/O ports are 0xb0-0xb3
- * or 0x30-0x33
- * -- this is a dual IDE interface with I/O chips
- *
- * More research on qd6580 being done by willmore@cig.mot.com (David)
- * More Information given by Petr Sourcek (petr@ryston.cz)
- * http://www.ryston.cz/petr/vlb
- */
-
-/*
- * 0xb0: Timer1
- *
- *
- * 0xb1: Config
- *
- * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170
- * (? Strange: the Dos driver uses it, and then forces baseport to 0x1f0 ?)
- * bit 1: qd baseport: 1 = 0xb0 ; 0 = 0x30
- * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
- * bit 3: 1 for qd6580
- * upper nibble is either 1010 or 0101, or else it isn't a qd6580
- *
- *
- * 0xb2: Timer2
- *
- *
- * 0xb3: Control
- *
- * bits 0-3 must always be set 1
- * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
- * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
- * 0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
- * channel 1 for hdc & hdd
- * bit 1 : 1 = only disks on primary port
- * 0 = disks & ATAPI devices on primary port
- * bit 2-4 : always 0
- * bit 5 : status, but of what ?
- * bit 6 : always set 1 by dos driver
- * bit 7 : set 1 for non-ATAPI devices (read-ahead and post-write buffer ?)
- */
-
-/* truncates a in [b,c] */
-#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
-
-typedef struct ide_hd_timings_s {
- int active_time; /* Active pulse (ns) minimum */
- int recovery_time; /* Recovery pulse (ns) minimum */
-} ide_hd_timings_t;
-
-static int basePort; /* base port address (0x30 or 0xb0) */
-static byte config; /* config register of qd6580 */
-static byte control; /* control register of qd6580 */
-
-static int bus_clock; /* Vesa local bus clock (ns) */
-static int tuned=0; /* to remember whether we've already been tuned */
-static int snd_tuned=0; /* to remember whether we've already been tuned */
-static int nb_disks_prim=0; /* number of disk drives on primary port */
-
-/*
- * write_reg
- *
- * writes the specified byte on the specified register
- */
-
-static void write_reg ( byte content, byte reg )
-{
- unsigned long flags;
-
- save_flags(flags); /* all CPUs */
- cli(); /* all CPUs */
- outb_p(content,reg);
- inb(0x3f6);
- restore_flags(flags); /* all CPUs */
-}
-
-/*
- * tune_drive
- *
- * Finds timings for the specified drive, returns it in struct t
- */
-
-static void tune_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
-{
- ide_pio_data_t d;
-
- t->active_time = 175;
- t->recovery_time = 415; /* worst cases values from the dos driver */
-
- if (!drive->present) { /* not present : free to give any timing */
- t->active_time = 0;
- t->recovery_time = 0;
- return;
- }
-
- pio = ide_get_best_pio_mode(drive, pio, 255, &d);
- pio = IDE_MIN(pio,4);
-
- switch (pio) {
- case 0: break;
- case 3:
- if (d.cycle_time >= 110) {
- t->active_time = 86;
- t->recovery_time = d.cycle_time-102;
- } else {
- printk("%s: Strange recovery time !\n",drive->name);
- return;
- }
- break;
- case 4:
- if (d.cycle_time >= 69) {
- t->active_time = 70;
- t->recovery_time = d.cycle_time-61;
- } else {
- printk("%s: Strange recovery time !\n",drive->name);
- return;
- }
- break;
- default:
- if (d.cycle_time >= 180) {
- t->active_time = 110;
- t->recovery_time = d.cycle_time - 120;
- } else {
- t->active_time = ide_pio_timings[pio].active_time;
- t->recovery_time = d.cycle_time
- -t->active_time;
- }
- }
- printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
-
- if (drive->media == ide_disk)
- nb_disks_prim++;
- else {
-/* need to disable read-ahead FIFO and post-write buffer for ATAPI drives*/
- write_reg(0x5f,basePort+0x03);
- printk("%s: Warning: please try to connect this drive to secondary IDE port\nto improve data transfer rate on primary IDE port.\n",drive->name);
- }
-}
-
-/*
- * tune_snd_drive
- *
- * Finds timings for the specified drive, using second channel rules
- */
-
-static void tune_snd_drive ( ide_drive_t *drive, byte pio, ide_hd_timings_t *t )
-{
- ide_pio_data_t d;
-
- t->active_time = 175;
- t->recovery_time = 415;
-
- if (!drive->present) { /* not present : free to give any timing */
- t->active_time = 0;
- t->recovery_time = 0;
- return;
- }
-
- pio = ide_get_best_pio_mode(drive, pio, 255, &d);
-
- if ((pio) && (d.cycle_time >= 180)) {
- t->active_time = 115;
- t->recovery_time = d.cycle_time - 115;
- }
- printk("%s: PIO mode%d, tim1=%dns tim2=%dns\n", drive->name, pio, t->active_time, t->recovery_time);
-
- if ((drive->media == ide_disk) && (nb_disks_prim<2)) {
-/* a disk drive on secondary port while there's room on primary, which is the
- * only one that has read-ahead fifo and post-write buffer ? What a waste !*/
- printk("%s: Warning: please try to connect this drive to primary IDE port\nto improve data transfer rate.\n",drive->name);
- }
-}
-
-/*
- * compute_timing
- *
- * computes the timing value where
- * lower nibble is active time, in count of VLB clocks, 17-(from 2 to 17)
- * upper nibble is recovery time, in count of VLB clocks, 15-(from 2 to 15)
- */
-
-static byte compute_timing ( char name[6], ide_hd_timings_t *t )
-{
- byte active_cycle;
- byte recovery_cycle;
- byte parameter;
-
- active_cycle = 17-IDE_IN(t->active_time / bus_clock + 1, 2, 17);
- recovery_cycle = 15-IDE_IN(t->recovery_time / bus_clock + 1, 2, 15);
-
- parameter = active_cycle | (recovery_cycle<<4);
-
- printk("%s: tim1=%dns tim2=%dns => %#x\n", name, t[0].active_time, t[0].recovery_time, parameter);
- return(parameter);
-}
-
-/*
- * tune_ide
- *
- * Tunes the whole hwif, ie tunes each drives, and in case we have to share,
- * takes the worse timings to tune qd6580
- */
-
-static void tune_ide ( ide_hwif_t *hwif, byte pio )
-{
- unsigned long flags;
- ide_hd_timings_t t[2]={{0,0},{0,0}};
- int bus_speed = ide_system_bus_speed ();
-
- bus_clock = 1000 / bus_speed;
-
- save_flags(flags); /* all CPUs */
- cli(); /* all CPUs */
- outb( (bus_clock<30) ? 0x0 : 0x0a, basePort + 0x02);
- outb( 0x40 | ((control & 0x02) ? 0x9f:0x1f), basePort+0x03);
- restore_flags(flags);
-
- tune_drive (&hwif->drives[0], pio, &t[0]);
- tune_drive (&hwif->drives[1], pio, &t[1]);
-
- if (control & 0x01) { /* only primary port enabled, can tune separately */
- write_reg(compute_timing (hwif->drives[0].name, &t[0]),basePort);
- write_reg(compute_timing (hwif->drives[1].name, &t[1]),basePort+0x02);
- } else { /* both ports enabled, we have to share */
-
- t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time);
- t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
- write_reg(compute_timing (hwif->name, &t[0]),basePort);
- }
-}
-
-/*
- * tune_snd_ide
- *
- * Tunes the whole secondary hwif, ie tunes each drives, and takes the worse
- * timings to tune qd6580
- */
-
-static void tune_snd_ide ( ide_hwif_t *hwif, byte pio )
-{
- ide_hd_timings_t t[2]={{0,0},{0,0}};
-
- tune_snd_drive (&hwif->drives[0], pio, &t[0]);
- tune_snd_drive (&hwif->drives[1], pio, &t[1]);
-
- t[0].active_time = IDE_MAX(t[0].active_time, t[1].active_time);
- t[0].recovery_time = IDE_MAX(t[0].recovery_time,t[1].recovery_time);
-
- write_reg(compute_timing (hwif->name, &t[0]),basePort+0x02);
-}
-
-/*
- * tune_qd6580
- *
- * tunes the hwif if not tuned
- */
-
-static void tune_qd6580 (ide_drive_t *drive, byte pio)
-{
- if (! tuned) {
- tune_ide(HWIF(drive), pio);
- tuned = 1;
- }
-}
-
-/*
- * tune_snd_qd6580
- *
- * tunes the second hwif if not tuned
- */
-
-static void tune_snd_qd6580 (ide_drive_t *drive, byte pio)
-{
- if (! snd_tuned) {
- tune_snd_ide(HWIF(drive), pio);
- snd_tuned = 1;
- }
-}
-
-/*
- * testreg
- *
- * tests if the given port is a register
- */
-
-static int __init testreg(int port)
-{
- byte savereg;
- byte readreg;
- unsigned long flags;
-
- save_flags(flags); /* all CPUs */
- cli(); /* all CPUs */
- savereg = inb(port);
- outb_p(0x15,port); /* safe value */
- readreg = inb_p(port);
- outb(savereg,port);
- restore_flags(flags); /* all CPUs */
-
- if (savereg == 0x15) {
- printk("Outch ! the probe for qd6580 isn't reliable !\n");
- printk("Please contact maintainers to tell about your hardware\n");
- printk("Assuming qd6580 is not present.\n");
- return 0;
- }
-
- return (readreg == 0x15);
-}
-
-/*
- * trybase:
- *
- * tries to find a qd6580 at the given base and save it if found
- */
-
-static int __init trybase (int base)
-{
- unsigned long flags;
-
- save_flags(flags); /* all CPUs */
- cli(); /* all CPUs */
- config = inb(base+0x01);
- control = inb(base+0x03);
- restore_flags(flags); /* all CPUs */
-
- if (((config & 0xf0) != 0x50) && ((config & 0xf0) != 0xa0)) return(0);
- if (! ( ((config & 0x02) == 0x0) == (base == 0x30) ) ) return (0);
-
- /* Seems to be OK, let's use it */
-
- basePort = base;
- return(testreg(base));
-}
-
-/*
- * probe:
- *
- * probes qd6580 at 0xb0 (the default) or 0x30
- */
-
-static int __init probe (void)
-{
- return (trybase(0xb0) ? 1 : trybase(0x30));
-}
-
-/*
- * init_qd6580:
- *
- * called at the very beginning of initialization ; should just probe and link
- */
-
-void __init init_qd6580 (void)
-{
- if (! probe()) {
- printk("qd6580: not found\n");
- return;
- }
-
- printk("qd6580: base=%#x, config=%#x, control=%#x\n", basePort, config, control);
-
- ide_hwifs[0].chipset = ide_qd6580;
- ide_hwifs[0].tuneproc = &tune_qd6580;
- if (!(control & 0x01)) {
- ide_hwifs[1].chipset = ide_qd6580;
- ide_hwifs[1].tuneproc = &tune_snd_qd6580;
- ide_hwifs[0].mate = &ide_hwifs[1];
- ide_hwifs[1].mate = &ide_hwifs[0];
- ide_hwifs[1].channel = 1;
- }
-}
--- /dev/null
+/*
+ * linux/drivers/ide/qd65xx.c Version 0.06 Aug 3, 2000
+ *
+ * Copyright (C) 1996-2000 Linus Torvalds & author (see below)
+ */
+
+/*
+ * Version 0.03 Cleaned auto-tune, added probe
+ * Version 0.04 Added second channel tuning
+ * Version 0.05 Enhanced tuning ; added qd6500 support
+ * Version 0.06 added dos driver's list
+ *
+ * QDI QD6500/QD6580 EIDE controller fast support
+ *
+ * Please set local bus speed using kernel parameter idebus
+ * for example, "idebus=33" stands for 33Mhz VLbus
+ * To activate controller support, use "ide0=qd65xx"
+ * To enable tuning, use "ide0=autotune"
+ * To enable second channel tuning (qd6580 only), use "ide1=autotune"
+ */
+
+/*
+ * Rewritten from the work of Colten Edwards <pje120@cs.usask.ca> by
+ * Samuel Thibault <samuel.thibault@fnac.net>
+ */
+
+#undef REALLY_SLOW_IO /* most systems can safely undef this */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/blkdev.h>
+#include <linux/hdreg.h>
+#include <linux/ide.h>
+#include <linux/init.h>
+#include <asm/io.h>
+
+#include "ide_modes.h"
+#include "qd65xx.h"
+
+/*
+ * I/O ports are 0x30-0x31 (and 0x32-0x33 for qd6580)
+ * or 0xb0-0xb1 (and 0xb2-0xb3 for qd6580)
+ * -- qd6500 is a single IDE interface
+ * -- qd6580 is a dual IDE interface
+ *
+ * More research on qd6580 being done by willmore@cig.mot.com (David)
+ * More Information given by Petr Soucek (petr@ryston.cz)
+ * http://www.ryston.cz/petr/vlb
+ */
+
+/*
+ * base: Timer1
+ *
+ *
+ * base+0x01: Config (R/O)
+ *
+ * bit 0: ide baseport: 1 = 0x1f0 ; 0 = 0x170 (only useful for qd6500)
+ * bit 1: qd65xx baseport: 1 = 0xb0 ; 0 = 0x30
+ * bit 2: ID3: bus speed: 1 = <=33MHz ; 0 = >33MHz
+ * bit 3: qd6500: 1 = disabled, 0 = enabled
+ * qd6580: 1
+ * upper nibble:
+ * qd6500: 1100
+ * qd6580: either 1010 or 0101
+ *
+ * base+0x02: Timer2 (qd6580 only)
+ *
+ *
+ * base+0x03: Control (qd6580 only)
+ *
+ * bits 0-3 must always be set 1
+ * bit 4 must be set 1, but is set 0 by dos driver while measuring vlb clock
+ * bit 0 : 1 = Only primary port enabled : channel 0 for hda, channel 1 for hdb
+ * 0 = Primary and Secondary ports enabled : channel 0 for hda & hdb
+ * channel 1 for hdc & hdd
+ * bit 1 : 1 = only disks on primary port
+ * 0 = disks & ATAPI devices on primary port
+ * bit 2-4 : always 0
+ * bit 5 : status, but of what ?
+ * bit 6 : always set 1 by dos driver
+ * bit 7 : set 1 for non-ATAPI devices on primary port
+ * (maybe read-ahead and post-write buffer ?)
+ */
+
+static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
+
+static void qd_write_reg (byte content, byte reg)
+{
+ unsigned long flags;
+
+ save_flags(flags); /* all CPUs */
+ cli(); /* all CPUs */
+ outb(content,reg);
+ restore_flags(flags); /* all CPUs */
+}
+
+byte __init qd_read_reg (byte reg)
+{
+ unsigned long flags;
+ byte read;
+
+ save_flags(flags); /* all CPUs */
+ cli(); /* all CPUs */
+ read = inb(reg);
+ restore_flags(flags); /* all CPUs */
+ return read;
+}
+
+/*
+ * qd_select:
+ *
+ * This routine is invoked from ide.c to prepare for access to a given drive.
+ */
+
+static void qd_select (ide_drive_t *drive)
+{
+ byte index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
+ (QD_TIMREG(drive) & 0x02);
+
+ if (timings[index] != QD_TIMING(drive))
+ qd_write_reg(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+}
+
+/*
+ * qd6500_compute_timing
+ *
+ * computes the timing value where
+ * lower nibble represents active time, in count of VLB clocks
+ * upper nibble represents recovery time, in count of VLB clocks
+ */
+
+static byte qd6500_compute_timing (ide_hwif_t *hwif, int active_time, int recovery_time)
+{
+ byte active_cycle,recovery_cycle;
+
+ if (system_bus_clock()<=33) {
+ active_cycle = 9 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 9);
+ recovery_cycle = 15 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 0, 15);
+ } else {
+ active_cycle = 8 - IDE_IN(active_time * system_bus_clock() / 1000 + 1, 1, 8);
+ recovery_cycle = 18 - IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 3, 18);
+ }
+
+ return((recovery_cycle<<4) | 0x08 | active_cycle);
+}
+
+/*
+ * qd6580_compute_timing
+ *
+ * idem for qd6580
+ */
+
+static byte qd6580_compute_timing (int active_time, int recovery_time)
+{
+ byte active_cycle = 17-IDE_IN(active_time * system_bus_clock() / 1000 + 1, 2, 17);
+ byte recovery_cycle = 15-IDE_IN(recovery_time * system_bus_clock() / 1000 + 1, 2, 15);
+
+ return((recovery_cycle<<4) | active_cycle);
+}
+
+/*
+ * qd_find_disk_type
+ *
+ * tries to find timing from dos driver's table
+ */
+
+static int qd_find_disk_type (ide_drive_t *drive,
+ int *active_time, int *recovery_time)
+{
+ struct qd65xx_timing_s *p;
+ char model[40];
+
+ if (!*drive->id->model) return 0;
+
+ strncpy(model,drive->id->model,40);
+ ide_fixstring(model,40,1); /* byte-swap */
+
+ for (p = qd65xx_timing ; p->offset != -1 ; p++) {
+ if (!strncmp(p->model, model+p->offset,4)) {
+ printk(KERN_DEBUG "%s: listed !\n",drive->name);
+ *active_time = p->active;
+ *recovery_time = p->recovery;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * qd_timing_ok:
+ *
+ * check whether timings don't conflict
+ */
+
+static int qd_timing_ok (ide_drive_t drives[])
+{
+ return (IDE_IMPLY(drives[0].present && drives[1].present,
+ IDE_IMPLY(QD_TIMREG(drives) == QD_TIMREG(drives+1),
+ QD_TIMING(drives) == QD_TIMING(drives+1))));
+ /* if same timing register, must be same timing */
+}
+
+/*
+ * qd_set_timing:
+ *
+ * records the timing, and enables selectproc as needed
+ */
+
+static void qd_set_timing (ide_drive_t *drive, byte timing)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+
+ drive->drive_data &= 0xff00;
+ drive->drive_data |= timing;
+ if (qd_timing_ok(hwif->drives)) {
+ qd_select(drive); /* selects once */
+ hwif->selectproc = NULL;
+ } else
+ hwif->selectproc = &qd_select;
+
+ printk(KERN_DEBUG "%s: %#x\n",drive->name,timing);
+}
+
+/*
+ * qd6500_tune_drive
+ */
+
+static void qd6500_tune_drive (ide_drive_t *drive, byte pio)
+{
+ int active_time = 175;
+ int recovery_time = 415; /* worst case values from the dos driver */
+
+ if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)
+ && drive->id->tPIO && (drive->id->field_valid & 0x02)
+ && drive->id->eide_pio >= 240) {
+
+ printk(KERN_INFO "%s: PIO mode%d\n", drive->name,
+ drive->id->tPIO);
+ active_time = 110;
+ recovery_time = drive->id->eide_pio - 120;
+ }
+
+ qd_set_timing(drive,qd6500_compute_timing(HWIF(drive),active_time,recovery_time));
+}
+
+/*
+ * qd6580_tune_drive
+ */
+
+static void qd6580_tune_drive (ide_drive_t *drive, byte pio)
+{
+ ide_pio_data_t d;
+ int base = HWIF(drive)->select_data;
+ int active_time = 175;
+ int recovery_time = 415; /* worst case values from the dos driver */
+
+ if (drive->id && !qd_find_disk_type(drive,&active_time,&recovery_time)) {
+ pio = ide_get_best_pio_mode(drive, pio, 255, &d);
+ pio = IDE_MIN(pio,4);
+
+ switch (pio) {
+ case 0: break;
+ case 3:
+ if (d.cycle_time >= 110) {
+ active_time = 86;
+ recovery_time = d.cycle_time-102;
+ } else
+ printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
+ break;
+ case 4:
+ if (d.cycle_time >= 69) {
+ active_time = 70;
+ recovery_time = d.cycle_time-61;
+ } else
+ printk(KERN_WARNING "%s: Strange recovery time !\n",drive->name);
+ break;
+ default:
+ if (d.cycle_time >= 180) {
+ active_time = 110;
+ recovery_time = d.cycle_time - 120;
+ } else {
+ active_time = ide_pio_timings[pio].active_time;
+ recovery_time = d.cycle_time
+ -active_time;
+ }
+ }
+ printk(KERN_INFO "%s: PIO mode%d\n",drive->name,pio);
+ }
+
+ if (!HWIF(drive)->channel && drive->media != ide_disk) {
+ qd_write_reg(0x5f,QD_CONTROL_PORT);
+ printk(KERN_WARNING "%s: ATAPI: disabled read-ahead FIFO and post-write buffer on %s.\n",drive->name,HWIF(drive)->name);
+ }
+
+ qd_set_timing(drive,qd6580_compute_timing(active_time,recovery_time));
+}
+
+/*
+ * qd_testreg
+ *
+ * tests if the given port is a register
+ */
+
+static int __init qd_testreg(int port)
+{
+ byte savereg;
+ byte readreg;
+ unsigned long flags;
+
+ save_flags(flags); /* all CPUs */
+ cli(); /* all CPUs */
+ savereg = inb_p(port);
+ outb_p(QD_TESTVAL,port); /* safe value */
+ readreg = inb_p(port);
+ outb(savereg,port);
+ restore_flags(flags); /* all CPUs */
+
+ if (savereg == QD_TESTVAL) {
+ printk(KERN_ERR "Outch ! the probe for qd65xx isn't reliable !\n");
+ printk(KERN_ERR "Please contact maintainers to tell about your hardware\n");
+ printk(KERN_ERR "Assuming qd65xx is not present.\n");
+ return 1;
+ }
+
+ return (readreg != QD_TESTVAL);
+}
+
+/*
+ * probe:
+ *
+ * looks at the specified baseport, and if qd found, registers & initialises it
+ * return 1 if another qd may be probed
+ */
+
+int __init probe (int base)
+{
+ byte config;
+ byte index;
+
+ config = qd_read_reg(QD_CONFIG_PORT);
+
+ if (! ((config & QD_CONFIG_BASEPORT) >> 1 == (base == 0xb0)) ) return 1;
+
+ index = ! (config & QD_CONFIG_IDE_BASEPORT);
+
+ if ((config & 0xf0) == QD_CONFIG_QD6500) {
+ ide_hwif_t *hwif = &ide_hwifs[index];
+
+ if (qd_testreg(base)) return 1; /* bad register */
+
+ /* qd6500 found */
+
+ printk(KERN_NOTICE "%s: qd6500 at %#x\n",
+ ide_hwifs[index].name, base);
+
+ printk(KERN_DEBUG "qd6500: config=%#x, ID3=%u\n",
+ config, QD_ID3);
+
+ if (config & QD_CONFIG_DISABLED) {
+ printk(KERN_WARNING "qd6500 is disabled !\n");
+ return 1;
+ }
+
+ hwif->chipset = ide_qd65xx;
+ hwif->select_data = base;
+ hwif->config_data = config;
+ hwif->drives[0].drive_data =
+ hwif->drives[1].drive_data = QD6500_DEF_DATA;
+ hwif->drives[0].io_32bit =
+ hwif->drives[1].io_32bit = 1;
+ hwif->tuneproc = &qd6500_tune_drive;
+ return 1;
+ }
+
+ if (((config & 0xf0) == QD_CONFIG_QD6580_A) || ((config & 0xf0) == QD_CONFIG_QD6580_B)) {
+
+ byte control;
+
+ if (qd_testreg(base) || qd_testreg(base+0x02)) return 1;
+ /* bad registers */
+
+ /* qd6580 found */
+
+ control = qd_read_reg(QD_CONTROL_PORT);
+
+ printk(KERN_NOTICE "qd6580 at %#x\n", base);
+ printk(KERN_DEBUG "qd6580: config=%#x, control=%#x, ID3=%u\n",
+ config, control, QD_ID3);
+
+ if (control & QD_CONTR_SEC_DISABLED) {
+ ide_hwif_t *hwif = &ide_hwifs[index];
+
+ /* secondary disabled */
+ printk(KERN_INFO "%s: qd6580: single IDE board\n",
+ ide_hwifs[index].name);
+
+ hwif->chipset = ide_qd65xx;
+ hwif->select_data = base;
+ hwif->config_data = config | (control <<8);
+ hwif->drives[0].drive_data =
+ hwif->drives[1].drive_data = QD6580_DEF_DATA;
+ hwif->drives[0].io_32bit =
+ hwif->drives[1].io_32bit = 1;
+ hwif->tuneproc = &qd6580_tune_drive;
+
+ qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+ return 1;
+ } else {
+ int i,j;
+ /* secondary enabled */
+ printk(KERN_INFO "%s&%s: qd6580: dual IDE board\n",
+ ide_hwifs[0].name,ide_hwifs[1].name);
+
+ for (i=0;i<2;i++) {
+
+ ide_hwifs[i].chipset = ide_qd65xx;
+ ide_hwifs[i].mate = &ide_hwifs[i^1];
+ ide_hwifs[i].channel = i;
+
+ ide_hwifs[i].select_data = base;
+ ide_hwifs[i].config_data = config | (control <<8);
+ ide_hwifs[i].tuneproc = &qd6580_tune_drive;
+
+ for (j=0;j<2;j++) {
+ ide_hwifs[i].drives[j].drive_data = QD6580_DEF_DATA;
+ ide_hwifs[i].drives[j].io_32bit = 1;
+ }
+ }
+
+ qd_write_reg(QD_DEF_CONTR,QD_CONTROL_PORT);
+
+ return 0; /* no other qd65xx possible */
+ }
+ }
+ /* no qd65xx found */
+ return 1;
+}
+
+/*
+ * init_qd65xx:
+ *
+ * called at the very beginning of initialization ; should just probe and link
+ */
+
+void __init init_qd65xx (void)
+{
+ if (probe(0x30)) probe(0xb0);
+}
--- /dev/null
+/*
+ * linux/drivers/ide/qd65xx.h
+ *
+ * Copyright (c) 2000 Linus Torvalds & authors
+ */
+
+/*
+ * Authors: Petr Soucek <petr@ryston.cz>
+ * Samuel Thibault <samuel.thibault@fnac.net>
+ */
+
+/* truncates a in [b,c] */
+#define IDE_IN(a,b,c) ( ((a)<(b)) ? (b) : ( (a)>(c) ? (c) : (a)) )
+
+#define IDE_IMPLY(a,b) ((!(a)) || (b))
+
+#define QD_TIM1_PORT (base)
+#define QD_CONFIG_PORT (base+0x01)
+#define QD_TIM2_PORT (base+0x02)
+#define QD_CONTROL_PORT (base+0x03)
+
+#define QD_CONFIG_IDE_BASEPORT 0x01
+#define QD_CONFIG_BASEPORT 0x02
+#define QD_CONFIG_ID3 0x04
+#define QD_CONFIG_DISABLED 0x08
+#define QD_CONFIG_QD6500 0xc0
+#define QD_CONFIG_QD6580_A 0xa0
+#define QD_CONFIG_QD6580_B 0x50
+
+#define QD_CONTR_SEC_DISABLED 0x01
+
+#define QD_ID3 (config & QD_CONFIG_ID3)
+
+#define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff)
+#define QD_CONTROL(hwif) (((hwif)->config_data & 0xff00) >> 8)
+
+#define QD_TIMING(drive) (byte)(((drive)->drive_data) & 0x00ff)
+#define QD_TIMREG(drive) (byte)((((drive)->drive_data) & 0xff00) >> 8)
+
+#define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08))
+#define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00))
+#define QD_DEF_CONTR (0x40 | ((control & 0x02) ? 0x9f : 0x1f))
+
+#define QD_TESTVAL 0x19 /* safe value */
+
+/* Drive specific timing taken from DOS driver v3.7 */
+
+struct qd65xx_timing_s {
+ char offset; /* ofset from the beginning of Model Number" */
+ char model[4]; /* 4 chars from Model number, no conversion */
+ short active; /* active time */
+ short recovery; /* recovery time */
+} qd65xx_timing [] = {
+ { 30, "2040", 110, 225 }, /* Conner CP30204 */
+ { 30, "2045", 135, 225 }, /* Conner CP30254 */
+ { 30, "1040", 155, 325 }, /* Conner CP30104 */
+ { 30, "1047", 135, 265 }, /* Conner CP30174 */
+ { 30, "5344", 135, 225 }, /* Conner CP3544 */
+ { 30, "01 4", 175, 405 }, /* Conner CP-3104 */
+ { 27, "C030", 175, 375 }, /* Conner CP3000 */
+ { 8, "PL42", 110, 295 }, /* Quantum LP240 */
+ { 8, "PL21", 110, 315 }, /* Quantum LP120 */
+ { 8, "PL25", 175, 385 }, /* Quantum LP52 */
+ { 4, "PA24", 110, 285 }, /* WD Piranha SP4200 */
+ { 6, "2200", 110, 260 }, /* WD Caviar AC2200 */
+ { 6, "3204", 110, 235 }, /* WD Caviar AC2340 */
+ { 6, "1202", 110, 265 }, /* WD Caviar AC2120 */
+ { 0, "DS3-", 135, 315 }, /* Teac SD340 */
+ { 8, "KM32", 175, 355 }, /* Toshiba MK234 */
+ { 2, "53A1", 175, 355 }, /* Seagate ST351A */
+ { 2, "4108", 175, 295 }, /* Seagate ST1480A */
+ { 2, "1344", 175, 335 }, /* Seagate ST3144A */
+ { 6, "7 12", 110, 225 }, /* Maxtor 7213A */
+ { 30, "02F4", 145, 295 }, /* Conner 3204F */
+ { 2, "1302", 175, 335 }, /* Seagate ST3120A */
+ { 2, "2334", 145, 265 }, /* Seagate ST3243A */
+ { 2, "2338", 145, 275 }, /* Seagate ST3283A */
+ { 2, "3309", 145, 275 }, /* Seagate ST3390A */
+ { 2, "5305", 145, 275 }, /* Seagate ST3550A */
+ { 2, "4100", 175, 295 }, /* Seagate ST1400A */
+ { 2, "4110", 175, 295 }, /* Seagate ST1401A */
+ { 2, "6300", 135, 265 }, /* Seagate ST3600A */
+ { 2, "5300", 135, 265 }, /* Seagate ST3500A */
+ { 6, "7 31", 135, 225 }, /* Maxtor 7131 AT */
+ { 6, "7 43", 115, 265 }, /* Maxtor 7345 AT */
+ { 6, "7 42", 110, 255 }, /* Maxtor 7245 AT */
+ { 6, "3 04", 135, 265 }, /* Maxtor 340 AT */
+ { 6, "61 0", 135, 285 }, /* WD AC160 */
+ { 6, "1107", 135, 235 }, /* WD AC1170 */
+ { 6, "2101", 110, 220 }, /* WD AC1210 */
+ { 6, "4202", 135, 245 }, /* WD AC2420 */
+ { 6, "41 0", 175, 355 }, /* WD Caviar 140 */
+ { 6, "82 0", 175, 355 }, /* WD Caviar 280 */
+ { 8, "PL01", 175, 375 }, /* Quantum LP105 */
+ { 8, "PL25", 110, 295 }, /* Quantum LP525 */
+ { 10, "4S 2", 175, 385 }, /* Quantum ELS42 */
+ { 10, "8S 5", 175, 385 }, /* Quantum ELS85 */
+ { 10, "1S72", 175, 385 }, /* Quantum ELS127 */
+ { 10, "1S07", 175, 385 }, /* Quantum ELS170 */
+ { 8, "ZE42", 135, 295 }, /* Quantum EZ240 */
+ { 8, "ZE21", 175, 385 }, /* Quantum EZ127 */
+ { 8, "ZE58", 175, 385 }, /* Quantum EZ85 */
+ { 8, "ZE24", 175, 385 }, /* Quantum EZ42 */
+ { 27, "C036", 155, 325 }, /* Conner CP30064 */
+ { 27, "C038", 155, 325 }, /* Conner CP30084 */
+ { 6, "2205", 110, 255 }, /* WDC AC2250 */
+ { 2, " CHA", 140, 415 }, /* WDC AH series; WDC AH260, WDC */
+ { 2, " CLA", 140, 415 }, /* WDC AL series: WDC AL2120, 2170, */
+ { 4, "UC41", 140, 415 }, /* WDC CU140 */
+ { 6, "1207", 130, 275 }, /* WDC AC2170 */
+ { 6, "2107", 130, 275 }, /* WDC AC1270 */
+ { 6, "5204", 130, 275 }, /* WDC AC2540 */
+ { 30, "3004", 110, 235 }, /* Conner CP30340 */
+ { 30, "0345", 135, 255 }, /* Conner CP30544 */
+ { 12, "12A3", 175, 320 }, /* MAXTOR LXT-213A */
+ { 12, "43A0", 145, 240 }, /* MAXTOR LXT-340A */
+ { 6, "7 21", 180, 290 }, /* Maxtor 7120 AT */
+ { 6, "7 71", 135, 240 }, /* Maxtor 7170 AT */
+ { 12, "45\0000", 110, 205 }, /* MAXTOR MXT-540 */
+ { 8, "PL11", 180, 290 }, /* QUANTUM LP110A */
+ { 8, "OG21", 150, 275 }, /* QUANTUM GO120 */
+ { 12, "42A5", 175, 320 }, /* MAXTOR LXT-245A */
+ { 2, "2309", 175, 295 }, /* ST3290A */
+ { 2, "3358", 180, 310 }, /* ST3385A */
+ { 2, "6355", 180, 310 }, /* ST3655A */
+ { 2, "1900", 175, 270 }, /* ST9100A */
+ { 2, "1954", 175, 270 }, /* ST9145A */
+ { 2, "1909", 175, 270 }, /* ST9190AG */
+ { 2, "2953", 175, 270 }, /* ST9235A */
+ { 2, "1359", 175, 270 }, /* ST3195A */
+ { 24, "3R11", 175, 290 }, /* ALPS ELECTRIC Co.,LTD, DR311C */
+ { 0, "2M26", 175, 215 }, /* M262XT-0Ah */
+ { 4, "2253", 175, 300 }, /* HP C2235A */
+ { 4, "-32A", 145, 245 }, /* H3133-A2 */
+ { 30, "0326", 150, 270 }, /* Samsung Electronics 120MB */
+ { 30, "3044", 110, 195 }, /* Conner CFA340A */
+ { 30, "43A0", 110, 195 }, /* Conner CFA340A */
+ { -1, " ", 175, 415 } /* unknown disk name */
+};
{ 4, "Mode 2" },
{ 3, "Mode 3" },
{ 2, "Mode 4" },
- { 0, "Undefined" }
+ { 0, "Mode 5" }
};
static __inline__ char * find_udma_mode (byte cycle_time)
};
static char * cycle_time [] = {
- "Undefined", "2 CLCK",
+ "2 CLK", "2 CLK",
"3 CLK", "4 CLK",
"5 CLK", "6 CLK",
"7 CLK", "8 CLK"
printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);
#endif /* SIS5513_DEBUG_DRIVE_INFO */
- return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on :
((id->dma_ultra >> 8) & 7) ? ide_dma_on :
((id->dma_mword >> 8) & 7) ? ide_dma_on :
((id->dma_1word >> 8) & 7) ? ide_dma_on :
}
dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
- if (id->dma_ultra & 0x001F) {
+ if (id->dma_ultra & 0x003F) {
/* Force if Capable UltraDMA */
dma_func = config_chipset_for_dma(drive, 1);
if ((id->field_valid & 2) &&
extern char *ide_xfer_verbose (byte xfer_rate);
-#ifdef CONFIG_ARCH_NETWINDER
/*
* Convert a PIO mode and cycle time to the required on/off
* times for the interface. This has protection against run-away
hwif->tuneproc = tune_sl82c105;
}
-#else
-
-unsigned int pci_init_sl82c105(struct pci_dev *dev, const char *msg)
-{
- return ide_special_settings(dev, msg);
-}
-
-void dma_init_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-{
- ide_setup_dma(hwif, dma_base, 8);
-}
-
-void __init ide_init_sl82c105(ide_hwif_t *hwif)
-{
- struct pci_dev *dev = hwif->pci_dev;
- unsigned short t16;
- unsigned int t32;
- pci_read_config_word(dev, PCI_COMMAND, &t16);
- printk("SL82C105 command word: %x\n",t16);
- t16 |= PCI_COMMAND_IO;
- pci_write_config_word(dev, PCI_COMMAND, t16);
- /* IDE timing */
- pci_read_config_dword(dev, 0x44, &t32);
- printk("IDE timing: %08x, resetting to PIO0 timing\n",t32);
- pci_write_config_dword(dev, 0x44, 0x03e4);
-#ifndef CONFIG_MBX
- pci_read_config_dword(dev, 0x40, &t32);
- printk("IDE control/status register: %08x\n",t32);
- pci_write_config_dword(dev, 0x40, 0x10ff08a1);
-#endif /* CONFIG_MBX */
-}
-#endif
-
/*
- * $Id: via82cxxx.c,v 3.26 2001/08/17 12:03:00 vojtech Exp $
+ * $Id: via82cxxx.c,v 3.28 2001/09/01 21:10:00 vojtech Exp $
*
* Copyright (c) 2000-2001 Vojtech Pavlik
*
/*
* VIA IDE driver for Linux. Supports
*
- * vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
+ * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b,
* vt82c686, vt82c686a, vt82c686b, vt8231, vt8233
*
* southbridges, which can be found in
*
- * VIA Apollo VP, VPX, VPX/97, VP2, VP2/97, VP3, MVP3, MVP4, P6, Pro,
- * Pro Plus, Pro 133, Pro 133A, ProMedia PM601, ProSavage PM133, PLE133,
- * Pro 266, KX133, KT133, ProSavage KM133, KT133A, KT266
- * PC-Chips VXPro, VXPro+, TXPro-III, TXPro-AGP, ViaGra, BXToo, BXTel
- * AMD 640, 640 AGP, 750 IronGate
- * ETEQ 6618, 6628, 6638
+ * VIA Apollo Master, VP, VP2, VP2/97, VP3, VPX, VPX/97, MVP3, MVP4, P6, Pro,
+ * ProII, ProPlus, Pro133, Pro133+, Pro133A, Pro133A Dual, Pro133T, Pro133Z,
+ * PLE133, PLE133T, Pro266, Pro266T, ProP4X266, PM601, PM133, PN133, PL133T,
+ * PX266, PM266, KX133, KT133, KT133A, KLE133, KT266, KX266, KM133, KM133A,
+ * KL133, KN133, KM266
+ * PC-Chips VXPro, VXPro+, VXTwo, TXPro-III, TXPro-AGP, AGPPro, ViaGra, BXToo,
+ * BXTel, BXpert
+ * AMD 640, 640 AGP, 750 IronGate, 760, 760MP
+ * ETEQ 6618, 6628, 6629, 6638
* Micron Samurai
*
* chipsets. Supports
unsigned char rev_max;
unsigned short flags;
} via_isa_bridges[] = {
+#ifdef FUTURE_BRIDGES
+ { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_100 },
+ { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_100 },
+ { "vt8233c", PCI_DEVICE_ID_VIA_8233C, 0x30, 0x4f, VIA_UDMA_100 },
+#endif
{ "vt8233", PCI_DEVICE_ID_VIA_8233_0, 0x00, 0x2f, VIA_UDMA_100 },
{ "vt8231", PCI_DEVICE_ID_VIA_8231, 0x00, 0x2f, VIA_UDMA_100 },
{ "vt82c686b", PCI_DEVICE_ID_VIA_82C686, 0x40, 0x4f, VIA_UDMA_100 },
{ "vt82c686", PCI_DEVICE_ID_VIA_82C686, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
{ "vt82c596b", PCI_DEVICE_ID_VIA_82C596, 0x10, 0x2f, VIA_UDMA_66 },
{ "vt82c596a", PCI_DEVICE_ID_VIA_82C596, 0x00, 0x0f, VIA_UDMA_33 | VIA_BAD_CLK66 },
- { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x47, 0x4f, VIA_UDMA_33 | VIA_SET_FIFO },
+ { "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x40, 0x46, VIA_UDMA_33 | VIA_SET_FIFO | VIA_BAD_PREQ },
{ "vt82c586b", PCI_DEVICE_ID_VIA_82C586_0, 0x30, 0x3f, VIA_UDMA_33 | VIA_SET_FIFO },
{ "vt82c586a", PCI_DEVICE_ID_VIA_82C586_0, 0x20, 0x2f, VIA_UDMA_33 | VIA_SET_FIFO },
{ "vt82c586", PCI_DEVICE_ID_VIA_82C586_0, 0x00, 0x0f, VIA_UDMA_NONE | VIA_SET_FIFO },
+ { "vt82c576", PCI_DEVICE_ID_VIA_82C576, 0x00, 0x2f, VIA_UDMA_NONE | VIA_SET_FIFO },
{ NULL }
};
via_print("----------VIA BusMastering IDE Configuration----------------");
- via_print("Driver Version: 3.26");
+ via_print("Driver Version: 3.27");
via_print("South Bridge: VIA %s", via_config->name);
pci_read_config_byte(isa_dev, PCI_REVISION_ID, &t);
#define DEFINE_MULTIPLEXER(Function) \
void highlevel_##Function(struct hpsb_host *host) \
{ \
- struct list_head *entry; \
+ struct list_head *entry,*next; \
void (*funcptr)(struct hpsb_host*); \
read_lock(&hl_drivers_lock); \
entry = hl_drivers.next; \
while (entry != &hl_drivers) { \
+ next = entry->next; \
funcptr = list_entry(entry, struct hpsb_highlevel, hl_list) \
->op->Function; \
if (funcptr) funcptr(host); \
- entry = entry->next; \
+ entry = next; \
} \
read_unlock(&hl_drivers_lock); \
}
}
if (ackcode != ACK_PENDING || !packet->expect_response) {
- packet->state = complete;
+ packet->state = completed;
up(&packet->state_change);
up(&packet->state_change);
run_task_queue(&packet->complete_tq);
break;
}
- packet->state = complete;
+ packet->state = completed;
up(&packet->state_change);
run_task_queue(&packet->complete_tq);
}
list_for_each(lh, &llist) {
packet = list_entry(lh, struct hpsb_packet, list);
- packet->state = complete;
+ packet->state = completed;
packet->ack_code = ACKX_ABORTED;
up(&packet->state_change);
run_task_queue(&packet->complete_tq);
list_for_each(lh, &expiredlist) {
packet = list_entry(lh, struct hpsb_packet, list);
- packet->state = complete;
+ packet->state = completed;
packet->ack_code = ACKX_TIMEOUT;
up(&packet->state_change);
run_task_queue(&packet->complete_tq);
/* Okay, this is core internal and a no care for hosts.
* queued = queued for sending
* pending = sent, waiting for response
- * complete = processing completed, successful or not
+ * completed = processing completed, successful or not
* incoming = incoming packet
*/
enum {
- unused, queued, pending, complete, incoming
+ unused, queued, pending, completed, incoming
} __attribute__((packed)) state;
/* These are core internal. */
-/* $Id: isar.c,v 1.17.6.3 2001/06/09 15:14:17 kai Exp $
+/* $Id: isar.c,v 1.17.6.4 2001/08/17 12:34:26 kai Exp $
*
* isar.c ISAR (Siemens PSB 7110) specific routines
*
#define DBG_LOADFIRM 0
#define DUMP_MBOXFRAME 2
-#define MIN(a,b) ((a<b)?a:b)
-
#define DLE 0x10
#define ETX 0x03
ret = 1;goto reterror;
}
while (left>0) {
- noc = MIN(126, left);
+ noc = left;
+ if (noc > 126)
+ noc = 126;
nom = 2*noc;
mp = msg;
*mp++ = sadr / 256;
-/* $Id: icn.c,v 1.65.6.6 2001/07/13 09:20:12 kai Exp $
+/* $Id: icn.c,v 1.65.6.7 2001/08/17 12:34:27 kai Exp $
* ISDN low-level module for the ICN active ISDN-Card.
*
#undef MAP_DEBUG
static char
-*revision = "$Revision: 1.65.6.6 $";
+*revision = "$Revision: 1.65.6.7 $";
static int icn_addcard(int, char *, char *);
restore_flags(flags);
while (left) {
if (sbfree) { /* If there is a free buffer... */
- cnt = MIN(256, left);
+ cnt = left;
+ if (cnt > 256)
+ cnt = 256;
if (copy_from_user(codebuf, p, cnt)) {
icn_maprelease_channel(card, 0);
return -EFAULT;
icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
{
int mch = card->secondhalf ? 2 : 0;
- int avail;
int pp;
int i;
int count;
ocount = 1;
xcount = loop = 0;
while (len) {
- avail = cmd_free;
- count = MIN(avail, len);
+ count = cmd_free;
+ if (count > len)
+ count = len;
if (user)
copy_from_user(msg, buf, count);
else
-/* $Id: icn.h,v 1.30.6.3 2001/04/20 02:42:01 keil Exp $
+/* $Id: icn.h,v 1.30.6.4 2001/08/17 12:34:27 kai Exp $
* ISDN lowlevel-module for the ICN active ISDN-Card.
*
#define CID (card->interface.id)
-#define MIN(a,b) ((a<b)?a:b)
-#define MAX(a,b) ((a>b)?a:b)
-
#endif /* defined(__KERNEL__) || defined(__DEBUGVAR__) */
#endif /* icn_h */
-/* $Id: isdn_audio.c,v 1.21 2000/06/20 18:01:55 keil Exp $
+/* $Id: isdn_audio.c,v 1.21.6.1 2001/08/17 12:34:25 kai Exp $
* Linux ISDN subsystem, audio conversion and compression (linklevel).
*
#include "isdn_audio.h"
#include "isdn_common.h"
-char *isdn_audio_revision = "$Revision: 1.21 $";
+char *isdn_audio_revision = "$Revision: 1.21.6.1 $";
/*
* Misc. lookup-tables.
int c;
while (len) {
- c = MIN(len, (DTMF_NPOINTS - s->idx));
+ c = DTMF_NPOINTS - s->idx;
+ if (c > len)
+ c = len;
if (c <= 0)
break;
for (i = 0; i < c; i++) {
struct frame_buf *frame = NULL;
unsigned char unacked;
int flen; /* fragment frame length including all headers */
- int totlen; /* non-fragmented frame length */
int free;
int count,
cp_len;
ulong msg;
if (frame->skb)
- totlen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
+ flen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
else
- totlen = FRAME_HDR_LEN + PREHDR_LEN;
+ flen = FRAME_HDR_LEN + PREHDR_LEN;
- flen = MIN(totlen, free);
+ if (flen > free)
+ flen = free;
msg = frame->msg;
} else {
/* Type 1 frame */
- totlen = 2 + (frame->skb->len - frame->copied);
+ flen = 2 + (frame->skb->len - frame->copied);
- flen = MIN(totlen, free);
+ if (flen > free)
+ flen = free;
/* TT */
tt = ((ushort) (flen - 2)) | 0x8000U; /* Type 1 */
}
if (frame->skb) {
- cp_len = MIN(frame->skb->len - frame->copied,
- flen - count);
+ cp_len = frame->skb->len - frame->copied;
+ if (cp_len > flen - count)
+ cp_len = flen - count;
memcpy_topcbit(dev, frame->skb->data + frame->copied,
cp_len);
struct frame_buf * next;
};
-#define MIN(a,b) ((a<b)?a:b)
-
extern int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum,
struct sk_buff *skb, unsigned short hdr_len);
#define NVRAM_SIZE 8192
-static long long nvram_llseek(struct file *file, loff_t offset, int origin)
+static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
{
switch (origin) {
case 1:
int md_thread(void * arg)
{
mdk_thread_t *thread = arg;
- struct completion *event;
md_lock_kernel();
return 0;
}
rrdev = find_rdev(mddev, rdev);
- if (rrdev->faulty)
+ if (!rrdev || rrdev->faulty)
return 0;
if (mddev->pers->error_handler == NULL
|| mddev->pers->error_handler(mddev,rdev) <= 0) {
if (mddev2 == mddev)
continue;
if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
- printk(KERN_INFO "md: serializing resync, md%d shares one or more physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));
+ printk(KERN_INFO "md: delaying resync of md%d until md%d has finished resync (they share one or more physical units)\n", mdidx(mddev), mdidx(mddev2));
serialize = 1;
break;
}
if (last_check + window > j)
continue;
+
+ last_check = j;
- run_task_queue(&tq_disk); //??
+ run_task_queue(&tq_disk);
+ repeat:
if (jiffies >= mark[last_mark] + SYNC_MARK_STEP ) {
/* step marks */
int next = (last_mark+1) % SYNC_MARKS;
* about not overloading the IO subsystem. (things like an
* e2fsck being done on the RAID array should execute fast)
*/
-repeat:
if (md_need_resched(current))
schedule();
!is_mddev_idle(mddev)) {
current->state = TASK_INTERRUPTIBLE;
md_schedule_timeout(HZ/4);
- if (!md_signal_pending(current))
- goto repeat;
+ goto repeat;
}
} else
current->nice = -20;
ainfo.md_minor =minor;
ainfo.not_persistent = 1;
- ainfo.state = MD_SB_CLEAN;
+ ainfo.state = (1 << MD_SB_CLEAN);
ainfo.active_disks = 0;
ainfo.working_disks = 0;
ainfo.failed_disks = 0;
int i;
PRINTK("raid5_error called\n");
- conf->resync_parity = 0;
+
for (i = 0, disk = conf->disks; i < conf->raid_disks; i++, disk++) {
if (disk->dev == dev && disk->operational) {
disk->operational = 0;
"raid5: Disk failure on spare %s\n",
partition_name (dev));
if (!conf->spare->operational) {
- MD_BUG();
+ /* probably a SET_DISK_FAULTY ioctl */
return -EIO;
}
disk->operational = 0;
sb->working_disks--;
sb->failed_disks++;
+ mddev->sb_dirty = 1;
+ md_wakeup_thread(conf->thread);
+
return 0;
}
}
spin_unlock_irq(&conf->device_lock);
}
}
- if (syncing) {
- md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
- clear_bit(STRIPE_SYNCING, &sh->state);
- syncing = 0;
- }
+ }
+ if (failed > 1 && syncing) {
+ md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
+ clear_bit(STRIPE_SYNCING, &sh->state);
+ syncing = 0;
}
/* might be able to return some write requests if the parity block
}
}
if (!test_bit(STRIPE_INSYNC, &sh->state)) {
+ struct disk_info *spare;
if (failed==0)
failed_num = sh->pd_idx;
/* should be able to compute the missing block and write it to spare */
set_bit(STRIPE_INSYNC, &sh->state);
if (conf->disks[failed_num].operational)
md_sync_acct(conf->disks[failed_num].dev, bh->b_size>>9);
- else if (conf->spare)
- md_sync_acct(conf->spare->dev, bh->b_size>>9);
+ else if ((spare=conf->spare))
+ md_sync_acct(spare->dev, bh->b_size>>9);
}
}
for (i=disks; i-- ;)
if (action[i]) {
struct buffer_head *bh = sh->bh_cache[i];
+ struct disk_info *spare = conf->spare;
int skip = 0;
if (action[i] == READ+1)
bh->b_end_io = raid5_end_read_request;
bh->b_end_io = raid5_end_write_request;
if (conf->disks[i].operational)
bh->b_dev = conf->disks[i].dev;
- else if (conf->spare && action[i] == WRITE+1)
- bh->b_dev = conf->spare->dev;
+ else if (spare && action[i] == WRITE+1)
+ bh->b_dev = spare->dev;
else skip=1;
if (!skip) {
PRINTK("for %ld schedule op %d on disc %d\n", sh->sector, action[i]-1, i);
--- /dev/null
+/*
+ * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
+ * Copyright (C) 2001 Ralf Baechle (ralf@gnu.org)
+ */
+
+#define VINO_BASE 0x00080000 /* In EISA address space */
+
+#define VINO_REVID 0x0000
+#define VINO_CTRL 0x0008
+#define VINO_INTSTAT 0x0010 /* Interrupt status */
+#define VINO_I2C_CTRL 0x0018
+#define VINO_I2C_DATA 0x0020
+#define VINO_A_ALPHA 0x0028 /* Channel A ... */
+#define VINO_A_CLIPS 0x0030 /* Clipping start */
+#define VINO_A_CLIPE 0x0038 /* Clipping end */
+#define VINO_A_FRAMERT 0x0040 /* Framerate */
+#define VINO_A_FLDCNT 0x0048 /* Field counter */
+#define VINO_A_LNSZ 0x0050
+#define VINO_A_LNCNT 0x0058
+#define VINO_A_PGIX 0x0060 /* Page index */
+#define VINO_A_DESC_PTR 0x0068 /* Ptr to next four descriptors */
+#define VINO_A_DESC_TLB_PTR 0x0070 /* Ptr to start of descriptor table */
+#define VINO_A_DESC_DATA0 0x0078 /* Descriptor data 0 */
+#define VINO_A_DESC_DATA1 0x0080 /* ... */
+#define VINO_A_DESC_DATA2 0x0088
+#define VINO_A_DESC_DATA3 0x0090
+#define VINO_A_FIFO_THRESHOLD 0x0098 /* FIFO threshold */
+#define VINO_A_FIFO_RP 0x00a0
+#define VINO_A_FIFO_WP 0x00a8
+#define VINO_B_ALPHA 0x00b0 /* Channel B ... */
+#define VINO_B_CLIPS 0x00b8
+#define VINO_B_CLIPE 0x00c0
+#define VINO_B_FRAMERT 0x00c8
+#define VINO_B_FLDCNT 0x00d0
+#define VINO_B_LNSZ 0x00d8
+#define VINO_B_LNCNT 0x00e0
+#define VINO_B_PGIX 0x00e8
+#define VINO_B_DESC_PTR 0x00f0
+#define VINO_B_DESC_TLB_PTR 0x00f8
+#define VINO_B_DESC_DATA0 0x0100
+#define VINO_B_DESC_DATA1 0x0108
+#define VINO_B_DESC_DATA2 0x0110
+#define VINO_B_DESC_DATA3 0x0118
+#define VINO_B_FIFO_THRESHOLD 0x0120
+#define VINO_B_FIFO_RP 0x0128
+#define VINO_B_FIFO_WP 0x0130
+
+/* Bits in the VINO_REVID register */
+
+#define VINO_REVID_REV_MASK 0x000f /* bits 0:3 */
+#define VINO_REVID_ID_MASK 0x00f0 /* bits 4:7 */
+
+/* Bits in the VINO_CTRL register */
+
+#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
+#define VINO_CTRL_A_FIELD_TRANS_INT (1<<1) /* Field transferred int */
+#define VINO_CTRL_A_FIFO_OF_INT (1<<2) /* FIFO overflow int */
+#define VINO_CTRL_A_END_DESC_TBL_INT (1<<3) /* End of desc table int */
+#define VINO_CTRL_B_FIELD_TRANS_INT (1<<4) /* Field transferred int */
+#define VINO_CTRL_B_FIFO_OF_INT (1<<5) /* FIFO overflow int */
+#define VINO_CTRL_B_END_DESC_TLB_INT (1<<6) /* End of desc table int */
+#define VINO_CTRL_A_DMA_ENBL (1<<7)
+#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
+#define VINO_CTRL_A_SYNC_ENBL (1<<9)
+#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
+#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
+#define VINO_CTRL_A_LUMA_ONLY (1<<12)
+#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
+#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
+#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
+#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
+#define VINO_CTRL_B_DMA_ENBL (1<<19)
+#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
+#define VINO_CTRL_B_SYNC_ENBL (1<<21)
+#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
+#define VINO_CTRL_B_RGB (1<<22) /* 1=RGB 0=YUV */
+#define VINO_CTRL_B_LUMA_ONLY (1<<23)
+#define VINO_CTRL_B_DEC_ENBL (1<<24) /* Decimation */
+#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 25:28 */
+#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
+#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
+
+/* Bits in the Interrupt and Status register */
+
+#define VINO_INTSTAT_A_FIELD_TRANS (1<<0) /* Field transferred int */
+#define VINO_INTSTAT_A_FIFO_OF (1<<1) /* FIFO overflow int */
+#define VINO_INTSTAT_A_END_DESC_TBL (1<<2) /* End of desc table int */
+#define VINO_INTSTAT_B_FIELD_TRANS (1<<3) /* Field transferred int */
+#define VINO_INTSTAT_B_FIFO_OF (1<<4) /* FIFO overflow int */
+#define VINO_INTSTAT_B_END_DESC_TBL (1<<5) /* End of desc table int */
+
+/* Bits in the Clipping Start register */
+
+#define VINO_CLIPS_START 0x3ff /* bits 0:9 */
+#define VINO_CLIPS_ODD_MASK 0x7fc00 /* bits 10:18 */
+#define VINO_CLIPS_EVEN_MASK 0xff80000 /* bits 19:27 */
+
+/* Bits in the Clipping End register */
+
+#define VINO_CLIPE_END 0x3ff /* bits 0:9 */
+#define VINO_CLIPE_ODD_MASK 0x7fc00 /* bits 10:18 */
+#define VINO_CLIPE_EVEN_MASK 0xff80000 /* bits 19:27 */
+
+/* Bits in the Frame Rate register */
+
+#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
+#define VINO_FRAMERT_RT_MASK 0x1ffe /* bits 1:12 */
+
+/* Bits in the VINO_I2C_CTRL */
+
+#define VINO_CTRL_I2C_IDLE (1<<0) /* write: 0=force idle
+ * read: 0=idle 1=not idle */
+#define VINO_CTRL_I2C_DIR (1<<1) /* 0=read 1=write */
+#define VINO_CTRL_I2C_MORE_BYTES (1<<2) /* 0=last byte 1=more bytes */
+#define VINO_CTRL_I2C_TRANS_BUSY (1<<4) /* 0=trans done 1=trans busy */
+#define VINO_CTRL_I2C_ACK (1<<5) /* 0=ack received 1=ack not */
+#define VINO_CTRL_I2C_BUS_ERROR (1<<7) /* 0=no bus err 1=bus err */
#EXTRA_CFLAGS += -DDEBUG
#EXTRA_CFLAGS += -DMPT_DEBUG
#EXTRA_CFLAGS += -DMPT_DEBUG_MSG_FRAME
-#EXTRA_CFLAGS += -DMPT_DEBUG_SPINLOCK
+#
# driver/module specifics...
+#
# For mptbase:
#CFLAGS_mptbase.o += -DMPT_DEBUG_HANDSHAKE
#CFLAGS_mptbase.o += -DMPT_DEBUG_IRQ
+#
# For {mptscsih, mptctl}:
#CFLAGS_mptscsih.o += -DMPT_SCSI_USE_NEW_EH
-#CFLAGS_mptscsih.o += -DMPT_SCSI_CACHE_AUTOSENSE
+#CFLAGS_mptscsih.o += -DMPT_DEBUG_SCANDV
#CFLAGS_mptscsih.o += -DMPT_DEBUG_SG
#CFLAGS_mptctl.o += -DMPT_DEBUG_SG
+#
# For mptlan:
#CFLAGS_mptlan.o += -DMPT_LAN_IO_DEBUG
+#
# For isense:
# EXP...
* (yes I wrote some of the orig. code back in 1991!)
* (mailto:Steve.Ralston@lsil.com)
*
- * $Id: isense.c,v 1.28 2001/01/14 23:11:09 sralston Exp $
+ * $Id: isense.c,v 1.28.14.1 2001/08/24 20:07:04 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
#endif
#define MODULEAUTHOR "Steven J. Ralston"
-#define COPYRIGHT "Copyright (c) 2000 " MODULEAUTHOR
+#define COPYRIGHT "Copyright (c) 2001 " MODULEAUTHOR
#include "mptbase.h"
#include "isense.h"
* in the IOCLogInfo field of a MPI Default Reply Message.
*
* CREATION DATE: 6/02/2000
- * ID: $Id: fc_log.h,v 4.2 2001/03/01 18:28:59 fibre Exp $
+ * ID: $Id: fc_log.h,v 4.5 2001/06/07 19:18:00 sschremm Exp $
*/
{
MPI_IOCLOGINFO_FC_INIT_BASE = 0x20000000,
MPI_IOCLOGINFO_FC_INIT_ERROR_OUT_OF_ORDER_FRAME = 0x20000001, /* received an out of order frame - unsupported */
- MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* bad start of frame primative */
- MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* bad end of frame primative */
- MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Receiver hardware detected overrun */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_START_OF_FRAME = 0x20000002, /* Bad Rx Frame, bad start of frame primative */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_BAD_END_OF_FRAME = 0x20000003, /* Bad Rx Frame, bad end of frame primative */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_OVER_RUN = 0x20000004, /* Bad Rx Frame, overrun */
MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OTHER = 0x20000005, /* Other errors caught by IOC which require retries */
MPI_IOCLOGINFO_FC_INIT_ERROR_SUBPROC_DEAD = 0x20000006, /* Main processor could not initialize sub-processor */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_OVERRUN = 0x20000007, /* Scatter Gather overrun */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_BAD_STATUS = 0x20000008, /* Receiver detected context mismatch via invalid header */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_RX_UNEXPECTED_FRAME= 0x20000009, /* CtxMgr detected unsupported frame type */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_LINK_FAILURE = 0x2000000A, /* Link failure occurred */
+ MPI_IOCLOGINFO_FC_INIT_ERROR_TX_TIMEOUT = 0x2000000B, /* Transmitter timeout error */
MPI_IOCLOGINFO_FC_TARGET_BASE = 0x21000000,
MPI_IOCLOGINFO_FC_TARGET_NO_PDISC = 0x21000001, /* not sent because we are waiting for a PDISC from the initiator */
MPI_IOCLOGINFO_FC_LINK_LOOP_INIT_TIMEOUT = 0x24000001, /* Loop initialization timed out */
MPI_IOCLOGINFO_FC_LINK_ALREADY_INITIALIZED = 0x24000002, /* Another system controller already initialized the loop */
MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED = 0x24000003, /* Not synchronized to signal or still negotiating (possible cable problem) */
+ MPI_IOCLOGINFO_FC_LINK_CRC_ERROR = 0x24000004, /* CRC check detected error on received frame */
MPI_IOCLOGINFO_FC_CTX_BASE = 0x25000000,
- MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid. */
+ MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET = 0x26000000, /* The lower 24 bits give the byte offset of the field in the request message that is invalid */
MPI_IOCLOGINFO_FC_INVALID_FIELD_MAX_OFFSET = 0x26ffffff,
MPI_IOCLOGINFO_FC_STATE_CHANGE = 0x27000000 /* The lower 24 bits give additional information concerning state change */
* Title: MPI Message independent structures and definitions
* Creation Date: July 27, 2000
*
- * MPI Version: 01.01.06
+ * MPI Version: 01.01.07
*
* Version History
* ---------------
* Obsoleted MPI_IOCSTATUS_TARGET_FC_ defines.
* 02-27-01 01.01.06 Removed MPI_HOST_INDEX_REGISTER define.
* Added function codes for RAID.
+ * 04-09-01 01.01.07 Added alternate define for MPI_DOORBELL_ACTIVE,
+ * MPI_DOORBELL_USED, to better match the spec.
* --------------------------------------------------------------------------
*/
/* S y s t e m D o o r b e l l */
#define MPI_DOORBELL_OFFSET (0x00000000)
-#define MPI_DOORBELL_ACTIVE (0x08000000)
+#define MPI_DOORBELL_ACTIVE (0x08000000) /* DoorbellUsed */
+#define MPI_DOORBELL_USED (MPI_DOORBELL_ACTIVE)
#define MPI_DOORBELL_ACTIVE_SHIFT (27)
#define MPI_DOORBELL_WHO_INIT_MASK (0x07000000)
#define MPI_DOORBELL_WHO_INIT_SHIFT (24)
/****************************************************************************/
#define MPI_IOCLOGINFO_TYPE_MASK (0xF0000000)
-#define MPI_IOCLOGINFO_TYPE_NONE (0x00)
-#define MPI_IOCLOGINFO_TYPE_SCSI (0x01)
-#define MPI_IOCLOGINFO_TYPE_FC (0x02)
+#define MPI_IOCLOGINFO_TYPE_NONE (0x0)
+#define MPI_IOCLOGINFO_TYPE_SCSI (0x1)
+#define MPI_IOCLOGINFO_TYPE_FC (0x2)
#define MPI_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF)
* Title: MPI Config message, structures, and Pages
* Creation Date: July 27, 2000
*
- * MPI Version: 01.01.09
+ * MPI Version: 01.01.11
*
* Version History
* ---------------
* MPI_CONFIG_PAGETYPE_RAID_VOLUME.
* Added definitions and structures for IOC Page 2 and
* RAID Volume Page 2.
+ * 03-27-01 01.01.10 Added CONFIG_PAGE_FC_PORT_8 and CONFIG_PAGE_FC_PORT_9.
+ * CONFIG_PAGE_FC_PORT_3 now supports persistent by DID.
+ * Added VendorId and ProductRevLevel fields to
+ * RAIDVOL2_IM_PHYS_ID struct.
+ * Modified values for MPI_FCPORTPAGE0_FLAGS_ATTACH_
+ * defines to make them compatible to MPI version 1.0.
+ * Added structure offset comments.
+ * 04-09-01 01.01.11 Added some new defines for the PageAddress field and
+ * removed some obsolete ones.
+ * Added IO Unit Page 3.
+ * Modified defines for Scsi Port Page 2.
+ * Modified RAID Volume Pages.
* --------------------------------------------------------------------------
*/
typedef struct _CONFIG_PAGE_HEADER
{
- U8 PageVersion;
- U8 PageLength;
- U8 PageNumber;
- U8 PageType;
+ U8 PageVersion; /* 00h */
+ U8 PageLength; /* 01h */
+ U8 PageNumber; /* 02h */
+ U8 PageType; /* 03h */
} fCONFIG_PAGE_HEADER, MPI_POINTER PTR_CONFIG_PAGE_HEADER,
ConfigPageHeader_t, MPI_POINTER pConfigPageHeader_t;
****************************************************************************/
#define MPI_SCSI_PORT_PGAD_PORT_MASK (0x000000FF)
+#define MPI_SCSI_DEVICE_FORM_MASK (0xF0000000)
+#define MPI_SCSI_DEVICE_FORM_TARGETID (0x00000000)
+#define MPI_SCSI_DEVICE_FORM_RAID_PHYS_DEV_NUM (0x10000000)
#define MPI_SCSI_DEVICE_TARGET_ID_MASK (0x000000FF)
#define MPI_SCSI_DEVICE_TARGET_ID_SHIFT (0)
#define MPI_SCSI_DEVICE_BUS_MASK (0x0000FF00)
#define MPI_SCSI_DEVICE_BUS_SHIFT (8)
-
-#define MPI_SCSI_LUN_TARGET_ID_MASK (0x000000FF)
-#define MPI_SCSI_LUN_TARGET_ID_SHIFT (0)
-#define MPI_SCSI_LUN_BUS_MASK (0x0000FF00)
-#define MPI_SCSI_LUN_BUS_SHIFT (8)
-#define MPI_SCSI_LUN_LUN_MASK (0x00FF0000)
-#define MPI_SCSI_LUN_LUN_SHIFT (16)
+#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_MASK (0x000000FF)
+#define MPI_SCSI_DEVICE_VOLUME_TARG_ID_SHIFT (0)
+#define MPI_SCSI_DEVICE_VOLUME_BUS_MASK (0x0000FF00)
+#define MPI_SCSI_DEVICE_VOLUME_BUS_SHIFT (8)
+#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_MASK (0x00FF0000)
+#define MPI_SCSI_DEVICE_PHYS_DISK_NUM_SHIFT (16)
#define MPI_FC_PORT_PGAD_PORT_MASK (0xF0000000)
#define MPI_FC_PORT_PGAD_PORT_SHIFT (28)
/****************************************************************************/
typedef struct _MSG_CONFIG
{
- U8 Action;
- U8 Reserved;
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- U8 Reserved2[8];
- fCONFIG_PAGE_HEADER Header;
- U32 PageAddress;
- SGE_IO_UNION PageBufferSGE;
+ U8 Action; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 Reserved2[8]; /* 0Ch */
+ fCONFIG_PAGE_HEADER Header; /* 14h */
+ U32 PageAddress; /* 18h */
+ SGE_IO_UNION PageBufferSGE; /* 1Ch */
} MSG_CONFIG, MPI_POINTER PTR_MSG_CONFIG,
Config_t, MPI_POINTER pConfig_t;
/* Action field values */
/****************************************************************************/
#define MPI_CONFIG_ACTION_PAGE_HEADER (0x00)
-/*#define MPI_CONFIG_ACTION_PAGE_READ (0x01) *//* obsolete */
#define MPI_CONFIG_ACTION_PAGE_READ_CURRENT (0x01)
-/*#define MPI_CONFIG_ACTION_PAGE_WRITE (0x02) *//* obsolete */
#define MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT (0x02)
#define MPI_CONFIG_ACTION_PAGE_DEFAULT (0x03)
-/*#define MPI_CONFIG_ACTION_PAGE_WRITE_COMMIT (0x04) */ /* obsolete */
#define MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM (0x04)
#define MPI_CONFIG_ACTION_PAGE_READ_DEFAULT (0x05)
#define MPI_CONFIG_ACTION_PAGE_READ_NVRAM (0x06)
/* Config Reply Message */
typedef struct _MSG_CONFIG_REPLY
{
- U8 Action;
- U8 Reserved;
- U8 MsgLength;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- U8 Reserved2[2];
- U16 IOCStatus;
- U32 IOCLogInfo;
- fCONFIG_PAGE_HEADER Header;
+ U8 Action; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 Reserved2[2]; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ fCONFIG_PAGE_HEADER Header; /* 14h */
} MSG_CONFIG_REPLY, MPI_POINTER PTR_MSG_CONFIG_REPLY,
ConfigReply_t, MPI_POINTER pConfigReply_t;
typedef struct _CONFIG_PAGE_MANUFACTURING_0
{
- fCONFIG_PAGE_HEADER Header;
- U8 ChipName[16];
- U8 ChipRevision[8];
- U8 BoardName[16];
- U8 BoardAssembly[16];
- U8 BoardTracerNumber[16];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U8 ChipName[16]; /* 04h */
+ U8 ChipRevision[8]; /* 14h */
+ U8 BoardName[16]; /* 1Ch */
+ U8 BoardAssembly[16]; /* 2Ch */
+ U8 BoardTracerNumber[16]; /* 3Ch */
} fCONFIG_PAGE_MANUFACTURING_0, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_0,
ManufacturingPage0_t, MPI_POINTER pManufacturingPage0_t;
typedef struct _CONFIG_PAGE_MANUFACTURING_1
{
- fCONFIG_PAGE_HEADER Header;
- U8 VPD[256];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U8 VPD[256]; /* 04h */
} fCONFIG_PAGE_MANUFACTURING_1, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_1,
ManufacturingPage1_t, MPI_POINTER pManufacturingPage1_t;
typedef struct _MPI_CHIP_REVISION_ID
{
- U16 DeviceID;
- U8 PCIRevisionID;
- U8 Reserved;
+ U16 DeviceID; /* 00h */
+ U8 PCIRevisionID; /* 02h */
+ U8 Reserved; /* 03h */
} MPI_CHIP_REVISION_ID, MPI_POINTER PTR_MPI_CHIP_REVISION_ID,
MpiChipRevisionId_t, MPI_POINTER pMpiChipRevisionId_t;
typedef struct _CONFIG_PAGE_MANUFACTURING_2
{
- fCONFIG_PAGE_HEADER Header;
- MPI_CHIP_REVISION_ID ChipId;
- U32 HwSettings[1];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ MPI_CHIP_REVISION_ID ChipId; /* 04h */
+ U32 HwSettings[1]; /* 08h */
} fCONFIG_PAGE_MANUFACTURING_2, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_2,
ManufacturingPage2_t, MPI_POINTER pManufacturingPage2_t;
typedef struct _CONFIG_PAGE_MANUFACTURING_3
{
- fCONFIG_PAGE_HEADER Header;
- MPI_CHIP_REVISION_ID ChipId;
- U32 Info[1];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ MPI_CHIP_REVISION_ID ChipId; /* 04h */
+ U32 Info[1]; /* 08h */
} fCONFIG_PAGE_MANUFACTURING_3, MPI_POINTER PTR_CONFIG_PAGE_MANUFACTURING_3,
ManufacturingPage3_t, MPI_POINTER pManufacturingPage3_t;
typedef struct _CONFIG_PAGE_IO_UNIT_0
{
- fCONFIG_PAGE_HEADER Header;
- U64 UniqueValue;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U64 UniqueValue; /* 04h */
} fCONFIG_PAGE_IO_UNIT_0, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_0,
IOUnitPage0_t, MPI_POINTER pIOUnitPage0_t;
typedef struct _CONFIG_PAGE_IO_UNIT_1
{
- fCONFIG_PAGE_HEADER Header;
- U32 Flags;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Flags; /* 04h */
} fCONFIG_PAGE_IO_UNIT_1, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_1,
IOUnitPage1_t, MPI_POINTER pIOUnitPage1_t;
typedef struct _MPI_ADAPTER_INFO
{
- U8 PciBusNumber;
- U8 PciDeviceAndFunctionNumber;
- U16 AdapterFlags;
+ U8 PciBusNumber; /* 00h */
+ U8 PciDeviceAndFunctionNumber; /* 01h */
+ U16 AdapterFlags; /* 02h */
} MPI_ADAPTER_INFO, MPI_POINTER PTR_MPI_ADAPTER_INFO,
MpiAdapterInfo_t, MPI_POINTER pMpiAdapterInfo_t;
typedef struct _CONFIG_PAGE_IO_UNIT_2
{
- fCONFIG_PAGE_HEADER Header;
- U32 Flags;
- U32 BiosVersion;
- MPI_ADAPTER_INFO AdapterOrder[4];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Flags; /* 04h */
+ U32 BiosVersion; /* 08h */
+ MPI_ADAPTER_INFO AdapterOrder[4]; /* 0Ch */
} fCONFIG_PAGE_IO_UNIT_2, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_2,
IOUnitPage2_t, MPI_POINTER pIOUnitPage2_t;
#define MPI_IOUNITPAGE2_FLAGS_DONT_HOOK_INT_40 (0x00000010)
+typedef struct _CONFIG_PAGE_IO_UNIT_3
+{
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 VolumeSettings; /* 04h */
+ U8 InfoOffset0; /* 08h */
+ U8 InfoSize0; /* 09h */
+ U8 InfoOffset1; /* 0Ah */
+ U8 InfoSize1; /* 0Bh */
+ U8 InquirySize; /* 0Ch */
+ U8 Reserved; /* 0Dh */
+ U16 Reserved2; /* 0Eh */
+ U8 InquiryData[56]; /* 10h */
+} fCONFIG_PAGE_IO_UNIT_3, MPI_POINTER PTR_CONFIG_PAGE_IO_UNIT_3,
+ IOUnitPage3_t, MPI_POINTER pIOUnitPage3_t;
+
+#define MPI_IOUNITPAGE3_PAGEVERSION (0x00)
+
+
/****************************************************************************/
/* IOC Config Pages */
/****************************************************************************/
typedef struct _CONFIG_PAGE_IOC_0
{
- fCONFIG_PAGE_HEADER Header;
- U32 TotalNVStore;
- U32 FreeNVStore;
- U16 VendorID;
- U16 DeviceID;
- U8 RevisionID;
- U8 Reserved[3];
- U32 ClassCode;
- U16 SubsystemVendorID;
- U16 SubsystemID;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 TotalNVStore; /* 04h */
+ U32 FreeNVStore; /* 08h */
+ U16 VendorID; /* 0Ch */
+ U16 DeviceID; /* 0Eh */
+ U8 RevisionID; /* 10h */
+ U8 Reserved[3]; /* 11h */
+ U32 ClassCode; /* 14h */
+ U16 SubsystemVendorID; /* 18h */
+ U16 SubsystemID; /* 1Ah */
} fCONFIG_PAGE_IOC_0, MPI_POINTER PTR_CONFIG_PAGE_IOC_0,
IOCPage0_t, MPI_POINTER pIOCPage0_t;
#define MPI_IOCPAGE0_PAGEVERSION (0x01)
+
typedef struct _CONFIG_PAGE_IOC_1
{
- fCONFIG_PAGE_HEADER Header;
- U32 Flags;
- U32 CoalescingTimeout;
- U8 CoalescingDepth;
- U8 Reserved[3];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Flags; /* 04h */
+ U32 CoalescingTimeout; /* 08h */
+ U8 CoalescingDepth; /* 0Ch */
+ U8 Reserved[3]; /* 0Dh */
} fCONFIG_PAGE_IOC_1, MPI_POINTER PTR_CONFIG_PAGE_IOC_1,
IOCPage1_t, MPI_POINTER pIOCPage1_t;
#define MPI_IOCPAGE1_REPLY_COALESCING (0x00000001)
+
typedef struct _CONFIG_PAGE_IOC_2_RAID_VOL
{
- U8 VolumeTargetID;
- U8 VolumeBus;
- U16 Reserved;
- U8 VolumeVersionMinor;
- U8 VolumeVersionMajor;
- U8 VolumeRaidType;
- U8 Reserved1;
+ U8 VolumeTargetID; /* 00h */
+ U8 VolumeBus; /* 01h */
+ U16 Reserved; /* 02h */
+ U8 VolumeVersionMinor; /* 04h */
+ U8 VolumeVersionMajor; /* 05h */
+ U8 VolumeRaidType; /* 06h */
+ U8 Reserved1; /* 07h */
} fCONFIG_PAGE_IOC_2_RAID_VOL, MPI_POINTER PTR_CONFIG_PAGE_IOC_2_RAID_VOL,
ConfigPageIoc2RaidVol_t, MPI_POINTER pConfigPageIoc2RaidVol_t;
typedef struct _CONFIG_PAGE_IOC_2
{
- fCONFIG_PAGE_HEADER Header;
- U32 CapabilitiesFlags;
- U8 NumActiveVolumes;
- U8 MaxVolumes;
- U16 Reserved;
- fCONFIG_PAGE_IOC_2_RAID_VOL RaidVolume[1];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 CapabilitiesFlags; /* 04h */
+ U8 NumActiveVolumes; /* 08h */
+ U8 MaxVolumes; /* 09h */
+ U16 Reserved; /* 0Ah */
+ fCONFIG_PAGE_IOC_2_RAID_VOL RaidVolume[1]; /* 0Ch */
} fCONFIG_PAGE_IOC_2, MPI_POINTER PTR_CONFIG_PAGE_IOC_2,
IOCPage2_t, MPI_POINTER pIOCPage2_t;
typedef struct _CONFIG_PAGE_SCSI_PORT_0
{
- fCONFIG_PAGE_HEADER Header;
- U32 Capabilities;
- U32 PhysicalInterface;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Capabilities; /* 04h */
+ U32 PhysicalInterface; /* 08h */
} fCONFIG_PAGE_SCSI_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_0,
SCSIPortPage0_t, MPI_POINTER pSCSIPortPage0_t;
#define MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE (0x02)
#define MPI_SCSIPORTPAGE0_PHY_SIGNAL_LVD (0x03)
+
typedef struct _CONFIG_PAGE_SCSI_PORT_1
{
- fCONFIG_PAGE_HEADER Header;
- U32 Configuration;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Configuration; /* 04h */
} fCONFIG_PAGE_SCSI_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_1,
SCSIPortPage1_t, MPI_POINTER pSCSIPortPage1_t;
#define MPI_SCSIPORTPAGE1_CFG_PORT_SCSI_ID_MASK (0x000000FF)
#define MPI_SCSIPORTPAGE1_CFG_PORT_RESPONSE_ID_MASK (0xFFFF0000)
+
typedef struct _MPI_DEVICE_INFO
{
- U8 Timeout;
- U8 SyncFactor;
- U16 DeviceFlags;
+ U8 Timeout; /* 00h */
+ U8 SyncFactor; /* 01h */
+ U16 DeviceFlags; /* 02h */
} MPI_DEVICE_INFO, MPI_POINTER PTR_MPI_DEVICE_INFO,
MpiDeviceInfo_t, MPI_POINTER pMpiDeviceInfo_t;
typedef struct _CONFIG_PAGE_SCSI_PORT_2
{
- fCONFIG_PAGE_HEADER Header;
- U32 PortFlags;
- U32 PortSettings;
- MPI_DEVICE_INFO DeviceSettings[16];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 PortFlags; /* 04h */
+ U32 PortSettings; /* 08h */
+ MPI_DEVICE_INFO DeviceSettings[16]; /* 0Ch */
} fCONFIG_PAGE_SCSI_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_PORT_2,
SCSIPortPage2_t, MPI_POINTER pSCSIPortPage2_t;
#define MPI_SCSIPORTPAGE2_PORT_SPINUP_DELAY_MASK (0x00000F00)
#define MPI_SCSIPORTPAGE2_PORT_MASK_NEGO_MASTER_SETTINGS (0x00003000)
#define MPI_SCSIPORTPAGE2_PORT_NEGO_MASTER_SETTINGS (0x00000000)
-#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS (0x00000001)
-#define MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS (0x00000003)
+#define MPI_SCSIPORTPAGE2_PORT_NONE_MASTER_SETTINGS (0x00001000)
+#define MPI_SCSIPORTPAGE2_PORT_ALL_MASTER_SETTINGS (0x00003000)
-#define MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE (0x00000001)
-#define MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE (0x00000002)
-#define MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE (0x00000004)
-#define MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE (0x00000008)
-#define MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE (0x00000010)
-#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE (0x00000020)
+#define MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE (0x0001)
+#define MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE (0x0002)
+#define MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE (0x0004)
+#define MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE (0x0008)
+#define MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE (0x0010)
+#define MPI_SCSIPORTPAGE2_DEVICE_BOOT_CHOICE (0x0020)
/****************************************************************************/
typedef struct _CONFIG_PAGE_SCSI_DEVICE_0
{
- fCONFIG_PAGE_HEADER Header;
- U32 NegotiatedParameters;
- U32 Information;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 NegotiatedParameters; /* 04h */
+ U32 Information; /* 08h */
} fCONFIG_PAGE_SCSI_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_0,
SCSIDevicePage0_t, MPI_POINTER pSCSIDevicePage0_t;
#define MPI_SCSIDEVPAGE0_INFO_PARAMS_NEGOTIATED (0x00000001)
+
typedef struct _CONFIG_PAGE_SCSI_DEVICE_1
{
- fCONFIG_PAGE_HEADER Header;
- U32 RequestedParameters;
- U32 DomainValidation;
- U32 Configuration;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 RequestedParameters; /* 04h */
+ U32 Reserved; /* 08h */
+ U32 Configuration; /* 0Ch */
} fCONFIG_PAGE_SCSI_DEVICE_1, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_1,
SCSIDevicePage1_t, MPI_POINTER pSCSIDevicePage1_t;
-#define MPI_SCSIDEVPAGE1_PAGEVERSION (0x01)
+#define MPI_SCSIDEVPAGE1_PAGEVERSION (0x02)
#define MPI_SCSIDEVPAGE1_RP_IU (0x00000001)
#define MPI_SCSIDEVPAGE1_RP_DT (0x00000002)
#define MPI_SCSIDEVPAGE1_CONF_PPR_ALLOWED (0x00000001)
+
+typedef struct _CONFIG_PAGE_SCSI_DEVICE_2
+{
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 DomainValidation; /* 04h */
+ U32 ParityPipeSelect; /* 08h */
+ U32 DataPipeSelect; /* 0Ch */
+} fCONFIG_PAGE_SCSI_DEVICE_2, MPI_POINTER PTR_CONFIG_PAGE_SCSI_DEVICE_2,
+ SCSIDevicePage2_t, MPI_POINTER pSCSIDevicePage2_t;
+
+#define MPI_SCSIDEVPAGE2_PAGEVERSION (0x00)
+
+#define MPI_SCSIDEVPAGE2_DV_ISI_ENABLE (0x00000010)
+#define MPI_SCSIDEVPAGE2_DV_SECONDARY_DRIVER_ENABLE (0x00000020)
+#define MPI_SCSIDEVPAGE2_DV_SLEW_RATE_CTRL (0x00000380)
+#define MPI_SCSIDEVPAGE2_DV_PRIM_DRIVE_STR_CTRL (0x00001C00)
+#define MPI_SCSIDEVPAGE2_DV_SECOND_DRIVE_STR_CTRL (0x0000E000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKH_ST (0x10000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKS_ST (0x20000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKH_DT (0x40000000)
+#define MPI_SCSIDEVPAGE2_DV_XCLKS_DT (0x80000000)
+
+#define MPI_SCSIDEVPAGE2_PPS_PPS_MASK (0x00000003)
+
+#define MPI_SCSIDEVPAGE2_DPS_BIT_0_PL_SELECT_MASK (0x00000003)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_1_PL_SELECT_MASK (0x0000000C)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_2_PL_SELECT_MASK (0x00000030)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_3_PL_SELECT_MASK (0x000000C0)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_4_PL_SELECT_MASK (0x00000300)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_5_PL_SELECT_MASK (0x00000C00)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_6_PL_SELECT_MASK (0x00003000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_7_PL_SELECT_MASK (0x0000C000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_8_PL_SELECT_MASK (0x00030000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_9_PL_SELECT_MASK (0x000C0000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_10_PL_SELECT_MASK (0x00300000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_11_PL_SELECT_MASK (0x00C00000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_12_PL_SELECT_MASK (0x03000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_13_PL_SELECT_MASK (0x0C000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_14_PL_SELECT_MASK (0x30000000)
+#define MPI_SCSIDEVPAGE2_DPS_BIT_15_PL_SELECT_MASK (0xC0000000)
+
+
/****************************************************************************/
/* FC Port Config Pages */
/****************************************************************************/
typedef struct _CONFIG_PAGE_FC_PORT_0
{
- fCONFIG_PAGE_HEADER Header;
- U32 Flags;
- U8 MPIPortNumber;
- U8 LinkType;
- U8 PortState;
- U8 Reserved;
- U32 PortIdentifier;
- U64 WWNN;
- U64 WWPN;
- U32 SupportedServiceClass;
- U32 SupportedSpeeds;
- U32 CurrentSpeed;
- U32 MaxFrameSize;
- U64 FabricWWNN;
- U64 FabricWWPN;
- U32 DiscoveredPortsCount;
- U32 MaxInitiators;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Flags; /* 04h */
+ U8 MPIPortNumber; /* 08h */
+ U8 LinkType; /* 09h */
+ U8 PortState; /* 0Ah */
+ U8 Reserved; /* 0Bh */
+ U32 PortIdentifier; /* 0Ch */
+ U64 WWNN; /* 10h */
+ U64 WWPN; /* 18h */
+ U32 SupportedServiceClass; /* 20h */
+ U32 SupportedSpeeds; /* 24h */
+ U32 CurrentSpeed; /* 28h */
+ U32 MaxFrameSize; /* 2Ch */
+ U64 FabricWWNN; /* 30h */
+ U64 FabricWWPN; /* 38h */
+ U32 DiscoveredPortsCount; /* 40h */
+ U32 MaxInitiators; /* 44h */
} fCONFIG_PAGE_FC_PORT_0, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_0,
FCPortPage0_t, MPI_POINTER pFCPortPage0_t;
#define MPI_FCPORTPAGE0_FLAGS_ALIAS_WWN_SUPPORTED (0x00000020)
#define MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID (0x00000030)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK (0x00000700)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT (0x00000000)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP (0x00000100)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT (0x00000200)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP (0x00000300)
-#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT (0x00000700)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK (0x00000F00)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT (0x00000000)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT (0x00000100)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP (0x00000200)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT (0x00000400)
+#define MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP (0x00000800)
#define MPI_FCPORTPAGE0_LTYPE_RESERVED (0x00)
#define MPI_FCPORTPAGE0_LTYPE_OTHER (0x01)
typedef struct _CONFIG_PAGE_FC_PORT_1
{
- fCONFIG_PAGE_HEADER Header;
- U32 Flags;
- U64 NoSEEPROMWWNN;
- U64 NoSEEPROMWWPN;
- U8 HardALPA;
- U8 LinkConfig;
- U8 TopologyConfig;
- U8 Reserved;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Flags; /* 04h */
+ U64 NoSEEPROMWWNN; /* 08h */
+ U64 NoSEEPROMWWPN; /* 10h */
+ U8 HardALPA; /* 18h */
+ U8 LinkConfig; /* 19h */
+ U8 TopologyConfig; /* 1Ah */
+ U8 Reserved; /* 1Bh */
} fCONFIG_PAGE_FC_PORT_1, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_1,
FCPortPage1_t, MPI_POINTER pFCPortPage1_t;
typedef struct _CONFIG_PAGE_FC_PORT_2
{
- fCONFIG_PAGE_HEADER Header;
- U8 NumberActive;
- U8 ALPA[126];
- U8 Reserved;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U8 NumberActive; /* 04h */
+ U8 ALPA[126]; /* 05h */
+ U8 Reserved; /* 83h */
} fCONFIG_PAGE_FC_PORT_2, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_2,
FCPortPage2_t, MPI_POINTER pFCPortPage2_t;
#define MPI_FCPORTPAGE2_PAGEVERSION (0x00)
+typedef struct _WWN_FORMAT
+{
+ U64 WWNN; /* 00h */
+ U64 WWPN; /* 08h */
+} WWN_FORMAT, MPI_POINTER PTR_WWN_FORMAT,
+ WWNFormat, MPI_POINTER pWWNFormat;
+
+typedef union _FC_PORT_PERSISTENT_PHYSICAL_ID
+{
+ WWN_FORMAT WWN;
+ U32 Did;
+} FC_PORT_PERSISTENT_PHYSICAL_ID, MPI_POINTER PTR_FC_PORT_PERSISTENT_PHYSICAL_ID,
+ PersistentPhysicalId_t, MPI_POINTER pPersistentPhysicalId_t;
+
typedef struct _FC_PORT_PERSISTENT
{
- U64 WWNN;
- U64 WWPN;
- U8 TargetID;
- U8 Bus;
- U16 Flags;
+ FC_PORT_PERSISTENT_PHYSICAL_ID PhysicalIdentifier; /* 00h */
+ U8 TargetID; /* 10h */
+ U8 Bus; /* 11h */
+ U16 Flags; /* 12h */
} FC_PORT_PERSISTENT, MPI_POINTER PTR_FC_PORT_PERSISTENT,
PersistentData_t, MPI_POINTER pPersistentData_t;
#define MPI_PERSISTENT_FLAGS_SCAN_ID (0x0002)
#define MPI_PERSISTENT_FLAGS_SCAN_LUNS (0x0004)
#define MPI_PERSISTENT_FLAGS_BOOT_DEVICE (0x0008)
+#define MPI_PERSISTENT_FLAGS_BY_DID (0x0080)
typedef struct _CONFIG_PAGE_FC_PORT_3
{
- fCONFIG_PAGE_HEADER Header;
- FC_PORT_PERSISTENT Entry[1];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ FC_PORT_PERSISTENT Entry[1]; /* 04h */
} fCONFIG_PAGE_FC_PORT_3, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_3,
FCPortPage3_t, MPI_POINTER pFCPortPage3_t;
-#define MPI_FCPORTPAGE3_PAGEVERSION (0x00)
+#define MPI_FCPORTPAGE3_PAGEVERSION (0x01)
typedef struct _CONFIG_PAGE_FC_PORT_4
{
- fCONFIG_PAGE_HEADER Header;
- U32 PortFlags;
- U32 PortSettings;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 PortFlags; /* 04h */
+ U32 PortSettings; /* 08h */
} fCONFIG_PAGE_FC_PORT_4, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_4,
FCPortPage4_t, MPI_POINTER pFCPortPage4_t;
typedef struct _CONFIG_PAGE_FC_PORT_5_ALIAS_INFO
{
- U8 Flags;
- U8 AliasAlpa;
- U16 Reserved;
- U64 AliasWWNN;
- U64 AliasWWPN;
+ U8 Flags; /* 00h */
+ U8 AliasAlpa; /* 01h */
+ U16 Reserved; /* 02h */
+ U64 AliasWWNN; /* 04h */
+ U64 AliasWWPN; /* 0Ch */
} fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5_ALIAS_INFO,
FcPortPage5AliasInfo_t, MPI_POINTER pFcPortPage5AliasInfo_t;
typedef struct _CONFIG_PAGE_FC_PORT_5
{
- fCONFIG_PAGE_HEADER Header;
- fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO AliasInfo[1];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ fCONFIG_PAGE_FC_PORT_5_ALIAS_INFO AliasInfo[1]; /* 04h */
} fCONFIG_PAGE_FC_PORT_5, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_5,
FCPortPage5_t, MPI_POINTER pFCPortPage5_t;
typedef struct _CONFIG_PAGE_FC_PORT_6
{
- fCONFIG_PAGE_HEADER Header;
- U32 Reserved;
- U64 TimeSinceReset;
- U64 TxFrames;
- U64 RxFrames;
- U64 TxWords;
- U64 RxWords;
- U64 LipCount;
- U64 NosCount;
- U64 ErrorFrames;
- U64 DumpedFrames;
- U64 LinkFailureCount;
- U64 LossOfSyncCount;
- U64 LossOfSignalCount;
- U64 PrimativeSeqErrCount;
- U64 InvalidTxWordCount;
- U64 InvalidCrcCount;
- U64 FcpInitiatorIoCount;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Reserved; /* 04h */
+ U64 TimeSinceReset; /* 08h */
+ U64 TxFrames; /* 10h */
+ U64 RxFrames; /* 18h */
+ U64 TxWords; /* 20h */
+ U64 RxWords; /* 28h */
+ U64 LipCount; /* 30h */
+ U64 NosCount; /* 38h */
+ U64 ErrorFrames; /* 40h */
+ U64 DumpedFrames; /* 48h */
+ U64 LinkFailureCount; /* 50h */
+ U64 LossOfSyncCount; /* 58h */
+ U64 LossOfSignalCount; /* 60h */
+ U64 PrimativeSeqErrCount; /* 68h */
+ U64 InvalidTxWordCount; /* 70h */
+ U64 InvalidCrcCount; /* 78h */
+ U64 FcpInitiatorIoCount; /* 80h */
} fCONFIG_PAGE_FC_PORT_6, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_6,
FCPortPage6_t, MPI_POINTER pFCPortPage6_t;
typedef struct _CONFIG_PAGE_FC_PORT_7
{
- fCONFIG_PAGE_HEADER Header;
- U32 Reserved;
- U8 PortSymbolicName[256];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Reserved; /* 04h */
+ U8 PortSymbolicName[256]; /* 08h */
} fCONFIG_PAGE_FC_PORT_7, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_7,
FCPortPage7_t, MPI_POINTER pFCPortPage7_t;
#define MPI_FCPORTPAGE7_PAGEVERSION (0x00)
+typedef struct _CONFIG_PAGE_FC_PORT_8
+{
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 BitVector[8]; /* 04h */
+} fCONFIG_PAGE_FC_PORT_8, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_8,
+ FCPortPage8_t, MPI_POINTER pFCPortPage8_t;
+
+#define MPI_FCPORTPAGE8_PAGEVERSION (0x00)
+
+
+typedef struct _CONFIG_PAGE_FC_PORT_9
+{
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 Reserved; /* 04h */
+ U64 GlobalWWPN; /* 08h */
+ U64 GlobalWWNN; /* 10h */
+ U32 UnitType; /* 18h */
+ U32 PhysicalPortNumber; /* 1Ch */
+ U32 NumAttachedNodes; /* 20h */
+ U16 IPVersion; /* 24h */
+ U16 UDPPortNumber; /* 26h */
+ U8 IPAddress[16]; /* 28h */
+ U16 Reserved1; /* 38h */
+ U16 TopologyDiscoveryFlags; /* 3Ah */
+} fCONFIG_PAGE_FC_PORT_9, MPI_POINTER PTR_CONFIG_PAGE_FC_PORT_9,
+ FCPortPage9_t, MPI_POINTER pFCPortPage9_t;
+
+#define MPI_FCPORTPAGE9_PAGEVERSION (0x00)
+
+
/****************************************************************************/
/* FC Device Config Pages */
/****************************************************************************/
typedef struct _CONFIG_PAGE_FC_DEVICE_0
{
- fCONFIG_PAGE_HEADER Header;
- U64 WWNN;
- U64 WWPN;
- U32 PortIdentifier;
- U8 Protocol;
- U8 Flags;
- U16 BBCredit;
- U16 MaxRxFrameSize;
- U8 Reserved1;
- U8 PortNumber;
- U8 FcPhLowestVersion;
- U8 FcPhHighestVersion;
- U8 CurrentTargetID;
- U8 CurrentBus;
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U64 WWNN; /* 04h */
+ U64 WWPN; /* 0Ch */
+ U32 PortIdentifier; /* 14h */
+ U8 Protocol; /* 18h */
+ U8 Flags; /* 19h */
+ U16 BBCredit; /* 1Ah */
+ U16 MaxRxFrameSize; /* 1Ch */
+ U8 Reserved1; /* 1Eh */
+ U8 PortNumber; /* 1Fh */
+ U8 FcPhLowestVersion; /* 20h */
+ U8 FcPhHighestVersion; /* 21h */
+ U8 CurrentTargetID; /* 22h */
+ U8 CurrentBus; /* 23h */
} fCONFIG_PAGE_FC_DEVICE_0, MPI_POINTER PTR_CONFIG_PAGE_FC_DEVICE_0,
FCDevicePage0_t, MPI_POINTER pFCDevicePage0_t;
/* RAID Volume Config Pages */
/****************************************************************************/
-typedef struct _RAIDVOL2_EM_PHYS_ID
-{
- U8 TargetID;
- U8 Bus;
- U8 IocNumber;
- U8 PhysDiskNumber;
- U8 Reserved[8];
- U8 PhysicalDiskIdentifier[16];
- U8 ProductId[16];
- U8 InfoOffset0;
- U8 InfoSize0;
- U8 InfoOffset1;
- U8 InfoSize1;
- U8 Info[32];
-} RAIDVOL2_EM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_EM_PHYS_ID,
- RaidVol2EmPhysicalID_t, MPI_POINTER pRaidVol2EmPhysicalID_t;
-
-typedef struct _RAIDVOL2_EM_DISK_INFO
-{
- U32 DiskStatus;
- U32 DeviceSettings;
- U16 ErrorCount;
- U16 Reserved;
- U8 ErrorCdbByte;
- U8 ErrorSenseKey;
- U8 ErrorASC;
- U8 ErrorASCQ;
- U16 SmartCount;
- U8 SmartASC;
- U8 SmartASCQ;
-} RAIDVOL2_EM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_EM_DISK_INFO,
- RaidVol2EmDiskInfo_t, MPI_POINTER pRaidVol2EmDiskInfo_t;
-
-/* RAID Volume 2 EM Physical Disk DiskStatus flags */
-
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_PRIMARY (0x00000001)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_SECONDARY (0x00000002)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_HOT_SPARE (0x00000004)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_OUT_OF_SYNC (0x00000008)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_OFFLINE (0x00000010)
-#define MPI_RAIDVOLPAGE2_PHYS_DISK_NOT_RESPONDING (0x00000020)
-
-typedef struct _RAIDVOL2_EM_PHYSICAL_DISK
-{
- RAIDVOL2_EM_PHYS_ID Id;
- RAIDVOL2_EM_DISK_INFO Info;
-} RAIDVOL2_EM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_EM_PHYSICAL_DISK,
- RaidVol2EmPhysicalDisk_t, MPI_POINTER pRaidVol2EmPhysicalDisk_t;
+typedef struct _RAIDVOL2_IM_PHYS_ID
+{
+ U8 TargetID; /* 00h */
+ U8 Bus; /* 01h */
+ U8 IocNumber; /* 02h */
+ U8 PhysDiskNumber; /* 03h */
+ U8 Reserved[8]; /* 04h */
+ U8 PhysicalDiskIdentifier[16]; /* 0Ch */
+ U8 VendorId[8]; /* 1Ch */
+ U8 ProductId[16]; /* 24h */
+ U8 ProductRevLevel[4]; /* 34h */
+ U32 Reserved1; /* 38h */
+ U8 Info[32]; /* 3Ch */
+} RAIDVOL2_IM_PHYS_ID, MPI_POINTER PTR_RAIDVOL2_IM_PHYS_ID,
+ RaidVol2ImPhysicalID_t, MPI_POINTER pRaidVol2ImPhysicalID_t;
+
+typedef struct _RAIDVOL2_IM_DISK_INFO
+{
+ U32 DiskStatus; /* 00h */
+ U32 DeviceSettings; /* 04h */
+ U16 ErrorCount; /* 08h */
+ U16 Reserved; /* 0Ah */
+ U8 ErrorCdbByte; /* 0Ch */
+ U8 ErrorSenseKey; /* 0Dh */
+ U8 ErrorASC; /* 0Eh */
+ U8 ErrorASCQ; /* 0Fh */
+ U16 SmartCount; /* 10h */
+ U8 SmartASC; /* 12h */
+ U8 SmartASCQ; /* 13h */
+} RAIDVOL2_IM_DISK_INFO, MPI_POINTER PTR_RAIDVOL2_IM_DISK_INFO,
+ RaidVol2ImDiskInfo_t, MPI_POINTER pRaidVol2ImDiskInfo_t;
+
+/* RAID Volume 2 IM Physical Disk DiskStatus flags */
+
+#define MPI_RVP2_PHYS_DISK_PRIMARY (0x00000001)
+#define MPI_RVP2_PHYS_DISK_SECONDARY (0x00000002)
+#define MPI_RVP2_PHYS_DISK_HOT_SPARE (0x00000004)
+#define MPI_RVP2_PHYS_DISK_OUT_OF_SYNC (0x00000008)
+#define MPI_RVP2_PHYS_DISK_STATUS_MASK (0x00000F00)
+#define MPI_RVP2_PHYS_DISK_STATUS_ONLINE (0x00000000)
+#define MPI_RVP2_PHYS_DISK_STATUS_MISSING (0x00000100)
+#define MPI_RVP2_PHYS_DISK_STATUS_NOT_COMPATIBLE (0x00000200)
+#define MPI_RVP2_PHYS_DISK_STATUS_FAILED (0x00000300)
+#define MPI_RVP2_PHYS_DISK_STATUS_INITIALIZING (0x00000400)
+#define MPI_RVP2_PHYS_DISK_STATUS_OFFLINE_REQUESTED (0x00000500)
+#define MPI_RVP2_PHYS_DISK_STATUS_OTHER_OFFLINE (0x00000F00)
+
+
+typedef struct _RAIDVOL2_IM_PHYSICAL_DISK
+{
+ RAIDVOL2_IM_PHYS_ID Id; /* 00h */
+ RAIDVOL2_IM_DISK_INFO Info; /* 5Ch */
+} RAIDVOL2_IM_PHYSICAL_DISK, MPI_POINTER PTR_RAIDVOL2_IM_PHYSICAL_DISK,
+ RaidVol2ImPhysicalDisk_t, MPI_POINTER pRaidVol2ImPhysicalDisk_t;
#define MPI_RAIDVOLPAGE2_MAX_DISKS (3)
typedef struct _CONFIG_PAGE_RAID_VOL_2
{
- fCONFIG_PAGE_HEADER Header;
- U32 VolumeStatus;
- U32 VolumeSettings;
- U32 Reserved;
- U64 MaxLba;
- U32 BlockSize;
- U8 InquirySize;
- U8 NumPhysicalDisks;
- U16 Reserved1;
- U8 InquiryData[56];
- RAIDVOL2_EM_PHYSICAL_DISK EMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
+ fCONFIG_PAGE_HEADER Header; /* 00h */
+ U32 VolumeStatus; /* 04h */
+ U32 VolumeSettings; /* 08h */
+ U32 Reserved; /* 0Ch */
+ U64 MaxLba; /* 10h */
+ U32 BlockSize; /* 18h */
+ U8 Reserved1; /* 1Ch */
+ U8 NumPhysicalDisks; /* 1Dh */
+ U16 Reserved2; /* 1Eh */
+ RAIDVOL2_IM_PHYSICAL_DISK IMPhysicalDisk[MPI_RAIDVOLPAGE2_MAX_DISKS];
} fCONFIG_PAGE_RAID_VOL_2, MPI_POINTER PTR_CONFIG_PAGE_RAID_VOL_2,
RaidVolumePage2_t, MPI_POINTER pRaidVolumePage2_t;
#define MPI_RAIDVOLPAGE2_SETTING_WRITE_CACHING_ENABLE (0x00000001)
#define MPI_RAIDVOLPAGE2_SETTING_OFFLINE_ON_SMART (0x00000002)
#define MPI_RAIDVOLPAGE2_SETTING_AUTO_CONFIGURE (0x00000004)
+#define MPI_RAIDVOLPAGE2_SETTING_USE_DEFAULTS (0x80000000)
/****************************************************************************/
typedef struct _CONFIG_PAGE_LAN_0
{
- ConfigPageHeader_t Header;
- U16 TxRxModes;
- U16 Reserved;
- U32 PacketPrePad;
+ ConfigPageHeader_t Header; /* 00h */
+ U16 TxRxModes; /* 04h */
+ U16 Reserved; /* 06h */
+ U32 PacketPrePad; /* 08h */
} fCONFIG_PAGE_LAN_0, MPI_POINTER PTR_CONFIG_PAGE_LAN_0,
LANPage0_t, MPI_POINTER pLANPage0_t;
typedef struct _CONFIG_PAGE_LAN_1
{
- ConfigPageHeader_t Header;
- U16 Reserved;
- U8 CurrentDeviceState;
- U8 Reserved1;
- U32 MinPacketSize;
- U32 MaxPacketSize;
- U32 HardwareAddressLow;
- U32 HardwareAddressHigh;
- U32 MaxWireSpeedLow;
- U32 MaxWireSpeedHigh;
- U32 BucketsRemaining;
- U32 MaxReplySize;
- U32 NegWireSpeedHigh;
- U32 NegWireSpeedLow;
+ ConfigPageHeader_t Header; /* 00h */
+ U16 Reserved; /* 04h */
+ U8 CurrentDeviceState; /* 06h */
+ U8 Reserved1; /* 07h */
+ U32 MinPacketSize; /* 08h */
+ U32 MaxPacketSize; /* 0Ch */
+ U32 HardwareAddressLow; /* 10h */
+ U32 HardwareAddressHigh; /* 14h */
+ U32 MaxWireSpeedLow; /* 18h */
+ U32 MaxWireSpeedHigh; /* 1Ch */
+ U32 BucketsRemaining; /* 20h */
+ U32 MaxReplySize; /* 24h */
+ U32 NegWireSpeedHigh; /* 28h */
+ U32 NegWireSpeedLow; /* 2Ch */
} fCONFIG_PAGE_LAN_1, MPI_POINTER PTR_CONFIG_PAGE_LAN_1,
LANPage1_t, MPI_POINTER pLANPage1_t;
* Title: MPI Fibre Channel messages and structures
* Creation Date: June 12, 2000
*
- * MPI Version: 01.01.05
+ * MPI Version: 01.01.07
*
* Version History
* ---------------
* FC_ABORT_TYPE_EXLINKSEND_REQUEST for FcAbort request.
* Added MPI_FC_PRIM_SEND_FLAGS_STOP_SEND.
* 02-20-01 01.01.05 Started using MPI_POINTER.
+ * 03-27-01 01.01.06 Added Flags field to MSG_LINK_SERVICE_BUFFER_POST_REPLY
+ * and defined MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED.
+ * Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
+ * Added structure offset comments.
+ * 04-09-01 01.01.07 Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
* --------------------------------------------------------------------------
*/
typedef struct _MSG_LINK_SERVICE_RSP_REQUEST
{
U8 RspFlags; /* 00h */
- U8 Reserved; /* 01h */
+ U8 RspLength; /* 01h */
U8 ChainOffset; /* 02h */
U8 Function; /* 03h */
U16 Reserved1; /* 04h */
typedef struct _MSG_FC_ABORT_REQUEST
{
- U8 AbortFlags; /* 00h */
- U8 AbortType; /* 01h */
- U8 ChainOffset; /* 02h */
- U8 Function; /* 03h */
- U16 Reserved1; /* 04h */
- U8 Reserved2; /* 06h */
- U8 MsgFlags; /* 07h */
- U32 MsgContext; /* 08h */
+ U8 AbortFlags; /* 00h */
+ U8 AbortType; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 Reserved2; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
U32 TransactionContextToAbort; /* 0Ch */
} MSG_FC_ABORT_REQUEST, MPI_POINTER PTR_MSG_FC_ABORT_REQUEST,
FcAbortRequest_t, MPI_POINTER pFcAbortRequest_t;
FcPrimitiveSendRequest_t, MPI_POINTER pFcPrimitiveSendRequest_t;
#define MPI_FC_PRIM_SEND_FLAGS_PORT_MASK (0x01)
+#define MPI_FC_PRIM_SEND_FLAGS_RESET_LINK (0x04)
#define MPI_FC_PRIM_SEND_FLAGS_STOP_SEND (0x08)
#define MPI_FC_PRIM_SEND_FLAGS_SEND_ONCE (0x10)
#define MPI_FC_PRIM_SEND_FLAGS_SEND_AROUND (0x20)
Copyright (c) 2000-2001 LSI Logic Corporation.
---------------------------------------
- Header Set Release Version: 01.01.08
- Header Set Release Date: 02-27-01
+ Header Set Release Version: 01.01.10
+ Header Set Release Date: 04-09-01
---------------------------------------
Filename Current version Prior version
---------- --------------- -------------
- mpi.h 01.01.06 01.01.05
- mpi_ioc.h 01.01.05 01.01.04
- mpi_cnfg.h 01.01.09 01.01.08
- mpi_init.h 01.01.03 01.01.03
- mpi_targ.h 01.01.03 01.01.03
- mpi_fc.h 01.01.05 01.01.05
- mpi_lan.h 01.01.02 01.01.02
- mpi_raid.h 01.01.01 none
+ mpi.h 01.01.07 01.01.06
+ mpi_ioc.h 01.01.07 01.01.06
+ mpi_cnfg.h 01.01.11 01.01.10
+ mpi_init.h 01.01.05 01.01.04
+ mpi_targ.h 01.01.04 01.01.04
+ mpi_fc.h 01.01.07 01.01.06
+ mpi_lan.h 01.01.03 01.01.03
+ mpi_raid.h 01.01.02 01.01.02
mpi_type.h 01.01.02 01.01.02
- mpi_history.txt 01.01.08 01.01.07
+ mpi_history.txt 01.01.09 01.01.09
* Date Version Description
* Obsoleted MPI_IOCSTATUS_TARGET_FC_ defines.
* 02-27-01 01.01.06 Removed MPI_HOST_INDEX_REGISTER define.
* Added function codes for RAID.
+ * 04-09-01 01.01.07 Added alternate define for MPI_DOORBELL_ACTIVE,
+ * MPI_DOORBELL_USED, to better match the spec.
* --------------------------------------------------------------------------
mpi_ioc.h
* 02-20-01 01.01.04 Started using MPI_POINTER.
* 02-27-01 01.01.05 Added event for RAID status change and its event data.
* Added IocNumber field to MSG_IOC_FACTS_REPLY.
+ * 03-27-01 01.01.06 Added defines for ProductId field of MPI_FW_HEADER.
+ * Added structure offset comments.
+ * 04-09-01 01.01.07 Added structure EVENT_DATA_EVENT_CHANGE.
* --------------------------------------------------------------------------
mpi_cnfg.h
* MPI_CONFIG_PAGETYPE_RAID_VOLUME.
* Added definitions and structures for IOC Page 2 and
* RAID Volume Page 2.
+ * 03-27-01 01.01.10 Added CONFIG_PAGE_FC_PORT_8 and CONFIG_PAGE_FC_PORT_9.
+ * CONFIG_PAGE_FC_PORT_3 now supports persistent by DID.
+ * Added VendorId and ProductRevLevel fields to
+ * RAIDVOL2_IM_PHYS_ID struct.
+ * Modified values for MPI_FCPORTPAGE0_FLAGS_ATTACH_
+ * defines to make them compatible to MPI version 1.0.
+ * Added structure offset comments.
+ * 04-09-01 01.01.11 Added some new defines for the PageAddress field and
+ * removed some obsolete ones.
+ * Added IO Unit Page 3.
+ * Modified defines for Scsi Port Page 2.
+ * Modified RAID Volume Pages.
* --------------------------------------------------------------------------
mpi_init.h
* 11-02-00 01.01.01 Original release for post 1.0 work
* 12-04-00 01.01.02 Added MPI_SCSIIO_CONTROL_NO_DISCONNECT.
* 02-20-01 01.01.03 Started using MPI_POINTER.
+ * 03-27-01 01.01.04 Added structure offset comments.
+ * 04-10-01 01.01.05 Added new MsgFlag for MSG_SCSI_TASK_MGMT.
* --------------------------------------------------------------------------
mpi_targ.h
* 02-20-01 01.01.03 Started using MPI_POINTER.
* Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
* MPI_TARGET_FCP_CMD_BUFFER.
+ * 03-27-01 01.01.04 Added structure offset comments.
* --------------------------------------------------------------------------
mpi_fc.h
* FC_ABORT_TYPE_EXLINKSEND_REQUEST for FcAbort request.
* Added MPI_FC_PRIM_SEND_FLAGS_STOP_SEND.
* 02-20-01 01.01.05 Started using MPI_POINTER.
+ * 03-27-01 01.01.06 Added Flags field to MSG_LINK_SERVICE_BUFFER_POST_REPLY
+ * and defined MPI_LS_BUF_POST_REPLY_FLAG_NO_RSP_NEEDED.
+ * Added MPI_FC_PRIM_SEND_FLAGS_RESET_LINK define.
+ * Added structure offset comments.
+ * 04-09-01 01.01.07 Added RspLength field to MSG_LINK_SERVICE_RSP_REQUEST.
* --------------------------------------------------------------------------
mpi_lan.h
* to lan private header file
* 11-02-00 01.01.01 Original release for post 1.0 work
* 02-20-01 01.01.02 Started using MPI_POINTER.
+ * 03-27-01 01.01.03 Added structure offset comments.
* --------------------------------------------------------------------------
mpi_raid.h
* 02-27-01 01.01.01 Original release for this file.
+ * 03-27-01 01.01.02 Added structure offset comments.
* --------------------------------------------------------------------------
mpi_type.h
mpi_history.txt Parts list history
-Filename 01.01.08 01.01.07 01.01.06 01.01.05 01.01.04
----------- -------- -------- -------- -------- --------
-mpi.h 01.01.06 01.01.05 01.01.04 01.01.04 01.01.03
-mpi_ioc.h 01.01.05 01.01.04 01.01.03 01.01.03 01.01.03
-mpi_cnfg.h 01.01.09 01.01.08 01.01.07 01.01.06 01.01.05
-mpi_init.h 01.01.03 01.01.03 01.01.02 01.01.02 01.01.02
-mpi_targ.h 01.01.03 01.01.03 01.01.02 01.01.02 01.01.02
-mpi_fc.h 01.01.05 01.01.05 01.01.04 01.01.04 01.01.03
-mpi_lan.h 01.01.02 01.01.02 01.01.01 01.01.01 01.01.01
-mpi_raid.h 01.01.01
-mpi_type.h 01.01.02 01.01.02 01.01.01 01.01.01 01.01.01
+Filename 01.01.10
+---------- --------
+mpi.h 01.01.07
+mpi_ioc.h 01.01.07
+mpi_cnfg.h 01.01.11
+mpi_init.h 01.01.05
+mpi_targ.h 01.01.04
+mpi_fc.h 01.01.07
+mpi_lan.h 01.01.03
+mpi_raid.h 01.01.02
+mpi_type.h 01.01.02
+
+Filename 01.01.09 01.01.08 01.01.07 01.01.06 01.01.05 01.01.04
+---------- -------- -------- -------- -------- -------- --------
+mpi.h 01.01.06 01.01.06 01.01.05 01.01.04 01.01.04 01.01.03
+mpi_ioc.h 01.01.06 01.01.05 01.01.04 01.01.03 01.01.03 01.01.03
+mpi_cnfg.h 01.01.10 01.01.09 01.01.08 01.01.07 01.01.06 01.01.05
+mpi_init.h 01.01.04 01.01.03 01.01.03 01.01.02 01.01.02 01.01.02
+mpi_targ.h 01.01.04 01.01.03 01.01.03 01.01.02 01.01.02 01.01.02
+mpi_fc.h 01.01.06 01.01.05 01.01.05 01.01.04 01.01.04 01.01.03
+mpi_lan.h 01.01.03 01.01.02 01.01.02 01.01.01 01.01.01 01.01.01
+mpi_raid.h 01.01.02 01.01.01
+mpi_type.h 01.01.02 01.01.02 01.01.02 01.01.01 01.01.01 01.01.01
Filename 01.01.03 01.01.02 01.01.01 01.00.07 01.00.06 01.00.05
---------- -------- -------- -------- -------- -------- --------
* Title: MPI initiator mode messages and structures
* Creation Date: June 8, 2000
*
- * MPI Version: 01.01.03
+ * MPI Version: 01.01.05
*
* Version History
* ---------------
* 11-02-00 01.01.01 Original release for post 1.0 work.
* 12-04-00 01.01.02 Added MPI_SCSIIO_CONTROL_NO_DISCONNECT.
* 02-20-01 01.01.03 Started using MPI_POINTER.
+ * 03-27-01 01.01.04 Added structure offset comments.
+ * 04-10-01 01.01.05 Added new MsgFlag for MSG_SCSI_TASK_MGMT.
* --------------------------------------------------------------------------
*/
typedef struct _MSG_SCSI_IO_REQUEST
{
- U8 TargetID;
- U8 Bus;
- U8 ChainOffset;
- U8 Function;
- U8 CDBLength;
- U8 SenseBufferLength;
- U8 Reserved;
- U8 MsgFlags;
- U32 MsgContext;
- U8 LUN[8];
- U32 Control;
- U8 CDB[16];
- U32 DataLength;
- U32 SenseBufferLowAddr;
- SGE_IO_UNION SGL;
+ U8 TargetID; /* 00h */
+ U8 Bus; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 CDBLength; /* 04h */
+ U8 SenseBufferLength; /* 05h */
+ U8 Reserved; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 LUN[8]; /* 0Ch */
+ U32 Control; /* 14h */
+ U8 CDB[16]; /* 18h */
+ U32 DataLength; /* 28h */
+ U32 SenseBufferLowAddr; /* 2Ch */
+ SGE_IO_UNION SGL; /* 30h */
} MSG_SCSI_IO_REQUEST, MPI_POINTER PTR_MSG_SCSI_IO_REQUEST,
SCSIIORequest_t, MPI_POINTER pSCSIIORequest_t;
/* SCSIIO reply structure */
typedef struct _MSG_SCSI_IO_REPLY
{
- U8 TargetID;
- U8 Bus;
- U8 MsgLength;
- U8 Function;
- U8 CDBLength;
- U8 SenseBufferLength;
- U8 Reserved;
- U8 MsgFlags;
- U32 MsgContext;
- U8 SCSIStatus;
- U8 SCSIState;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 TransferCount;
- U32 SenseCount;
- U32 ResponseInfo;
+ U8 TargetID; /* 00h */
+ U8 Bus; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 CDBLength; /* 04h */
+ U8 SenseBufferLength; /* 05h */
+ U8 Reserved; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 SCSIStatus; /* 0Ch */
+ U8 SCSIState; /* 0Dh */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 TransferCount; /* 14h */
+ U32 SenseCount; /* 18h */
+ U32 ResponseInfo; /* 1Ch */
} MSG_SCSI_IO_REPLY, MPI_POINTER PTR_MSG_SCSI_IO_REPLY,
SCSIIOReply_t, MPI_POINTER pSCSIIOReply_t;
typedef struct _MSG_SCSI_TASK_MGMT
{
- U8 TargetID;
- U8 Bus;
- U8 ChainOffset;
- U8 Function;
- U8 Reserved;
- U8 TaskType;
- U8 Reserved1;
- U8 MsgFlags;
- U32 MsgContext;
- U8 LUN[8];
- U32 Reserved2[7];
- U32 TaskMsgContext;
+ U8 TargetID; /* 00h */
+ U8 Bus; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved; /* 04h */
+ U8 TaskType; /* 05h */
+ U8 Reserved1; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 LUN[8]; /* 0Ch */
+ U32 Reserved2[7]; /* 14h */
+ U32 TaskMsgContext; /* 30h */
} MSG_SCSI_TASK_MGMT, MPI_POINTER PTR_SCSI_TASK_MGMT,
SCSITaskMgmt_t, MPI_POINTER pSCSITaskMgmt_t;
/* TaskType values */
-#define MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x00000001)
-#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x00000002)
-#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x00000003)
-#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x00000004)
+#define MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01)
+#define MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02)
+#define MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03)
+#define MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS (0x04)
/* MsgFlags bits */
-#define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION (0x00000002)
+#define MPI_SCSITASKMGMT_MSGFLAGS_TARGET_RESET_OPTION (0x00)
+#define MPI_SCSITASKMGMT_MSGFLAGS_LIP_RESET_OPTION (0x02)
+#define MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION (0x04)
/* SCSI Task Management Reply */
typedef struct _MSG_SCSI_TASK_MGMT_REPLY
{
- U8 TargetID;
- U8 Bus;
- U8 MsgLength;
- U8 Function;
- U8 Reserved;
- U8 TaskType;
- U8 Reserved1;
- U8 MsgFlags;
- U32 MsgContext;
- U8 Reserved2[2];
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 TerminationCount;
+ U8 TargetID; /* 00h */
+ U8 Bus; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved; /* 04h */
+ U8 TaskType; /* 05h */
+ U8 Reserved1; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 Reserved2[2]; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 TerminationCount; /* 14h */
} MSG_SCSI_TASK_MGMT_REPLY, MPI_POINTER PTR_MSG_SCSI_TASK_MGMT_REPLY,
SCSITaskMgmtReply_t, MPI_POINTER pSCSITaskMgmtReply_t;
*
*
* Name: MPI_IOC.H
- * Title: MPI IOC, Port, Event, FW Load, and ToolBox messages
+ * Title: MPI IOC, Port, Event, FW Download, and FW Upload messages
* Creation Date: August 11, 2000
*
- * MPI Version: 01.01.05
+ * MPI Version: 01.01.07
*
* Version History
* ---------------
* 02-20-01 01.01.04 Started using MPI_POINTER.
* 02-27-01 01.01.05 Added event for RAID status change and its event data.
* Added IocNumber field to MSG_IOC_FACTS_REPLY.
+ * 03-27-01 01.01.06 Added defines for ProductId field of MPI_FW_HEADER.
+ * Added structure offset comments.
+ * 04-09-01 01.01.07 Added structure EVENT_DATA_EVENT_CHANGE.
* --------------------------------------------------------------------------
*/
typedef struct _MSG_IOC_INIT
{
- U8 WhoInit;
- U8 Reserved;
- U8 ChainOffset;
- U8 Function;
- U8 Flags;
- U8 MaxDevices;
- U8 MaxBuses;
- U8 MsgFlags;
- U32 MsgContext;
- U16 ReplyFrameSize;
- U8 Reserved1[2];
- U32 HostMfaHighAddr;
- U32 SenseBufferHighAddr;
+ U8 WhoInit; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Flags; /* 04h */
+ U8 MaxDevices; /* 05h */
+ U8 MaxBuses; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 ReplyFrameSize; /* 0Ch */
+ U8 Reserved1[2]; /* 0Eh */
+ U32 HostMfaHighAddr; /* 10h */
+ U32 SenseBufferHighAddr; /* 14h */
} MSG_IOC_INIT, MPI_POINTER PTR_MSG_IOC_INIT,
IOCInit_t, MPI_POINTER pIOCInit_t;
typedef struct _MSG_IOC_INIT_REPLY
{
- U8 WhoInit;
- U8 Reserved;
- U8 MsgLength;
- U8 Function;
- U8 Flags;
- U8 MaxDevices;
- U8 MaxBuses;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
+ U8 WhoInit; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Flags; /* 04h */
+ U8 MaxDevices; /* 05h */
+ U8 MaxBuses; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
} MSG_IOC_INIT_REPLY, MPI_POINTER PTR_MSG_IOC_INIT_REPLY,
IOCInitReply_t, MPI_POINTER pIOCInitReply_t;
typedef struct _MSG_IOC_FACTS
{
- U8 Reserved[2];
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
+ U8 Reserved[2]; /* 00h */
+ U8 ChainOffset; /* 01h */
+ U8 Function; /* 02h */
+ U8 Reserved1[3]; /* 03h */
+ U8 MsgFlags; /* 04h */
+ U32 MsgContext; /* 08h */
} MSG_IOC_FACTS, MPI_POINTER PTR_IOC_FACTS,
IOCFacts_t, MPI_POINTER pIOCFacts_t;
typedef struct _MSG_IOC_FACTS_REPLY
{
- U16 MsgVersion;
- U8 MsgLength;
- U8 Function;
- U16 Reserved;
- U8 IOCNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U8 MaxChainDepth;
- U8 WhoInit;
- U8 BlockSize;
- U8 Flags;
- U16 ReplyQueueDepth;
- U16 RequestFrameSize;
- U16 FWVersion;
- U16 ProductID;
- U32 CurrentHostMfaHighAddr;
- U16 GlobalCredits;
- U8 NumberOfPorts;
- U8 EventState;
- U32 CurrentSenseBufferHighAddr;
- U16 CurReplyFrameSize;
- U8 MaxDevices;
- U8 MaxBuses;
- U32 FWImageSize;
- U32 DataImageSize;
+ U16 MsgVersion; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved; /* 04h */
+ U8 IOCNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U8 MaxChainDepth; /* 14h */
+ U8 WhoInit; /* 15h */
+ U8 BlockSize; /* 16h */
+ U8 Flags; /* 17h */
+ U16 ReplyQueueDepth; /* 18h */
+ U16 RequestFrameSize; /* 1Ah */
+ U16 FWVersion; /* 1Ch */
+ U16 ProductID; /* 1Eh */
+ U32 CurrentHostMfaHighAddr; /* 20h */
+ U16 GlobalCredits; /* 24h */
+ U8 NumberOfPorts; /* 26h */
+ U8 EventState; /* 27h */
+ U32 CurrentSenseBufferHighAddr; /* 28h */
+ U16 CurReplyFrameSize; /* 2Ch */
+ U8 MaxDevices; /* 2Eh */
+ U8 MaxBuses; /* 2Fh */
+ U32 FWImageSize; /* 30h */
+ U32 DataImageSize; /* 34h */
} MSG_IOC_FACTS_REPLY, MPI_POINTER PTR_MSG_IOC_FACTS_REPLY,
IOCFactsReply_t, MPI_POINTER pIOCFactsReply_t;
typedef struct _MSG_PORT_FACTS
{
- U8 Reserved[2];
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[2];
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
+ U8 Reserved[2]; /* 00h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[2]; /* 04h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
} MSG_PORT_FACTS, MPI_POINTER PTR_MSG_PORT_FACTS,
PortFacts_t, MPI_POINTER pPortFacts_t;
typedef struct _MSG_PORT_FACTS_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U16 Reserved1;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U8 Reserved3;
- U8 PortType;
- U16 MaxDevices;
- U16 PortSCSIID;
- U16 ProtocolFlags;
- U16 MaxPostedCmdBuffers;
- U16 MaxPersistentIDs;
- U16 MaxLanBuckets;
- U16 Reserved4;
- U32 Reserved5;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U8 Reserved3; /* 14h */
+ U8 PortType; /* 15h */
+ U16 MaxDevices; /* 16h */
+ U16 PortSCSIID; /* 18h */
+ U16 ProtocolFlags; /* 1Ah */
+ U16 MaxPostedCmdBuffers; /* 1Ch */
+ U16 MaxPersistentIDs; /* 1Eh */
+ U16 MaxLanBuckets; /* 20h */
+ U16 Reserved4; /* 22h */
+ U32 Reserved5; /* 24h */
} MSG_PORT_FACTS_REPLY, MPI_POINTER PTR_MSG_PORT_FACTS_REPLY,
PortFactsReply_t, MPI_POINTER pPortFactsReply_t;
typedef struct _MSG_PORT_ENABLE
{
- U8 Reserved[2];
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[2];
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
+ U8 Reserved[2]; /* 00h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[2]; /* 04h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
} MSG_PORT_ENABLE, MPI_POINTER PTR_MSG_PORT_ENABLE,
PortEnable_t, MPI_POINTER pPortEnable_t;
typedef struct _MSG_PORT_ENABLE_REPLY
{
- U8 Reserved[2];
- U8 MsgLength;
- U8 Function;
- U8 Reserved1[2];
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
+ U8 Reserved[2]; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[2]; /* 04h */
+ U8 PortNumber; /* 05h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
} MSG_PORT_ENABLE_REPLY, MPI_POINTER PTR_MSG_PORT_ENABLE_REPLY,
PortEnableReply_t, MPI_POINTER pPortEnableReply_t;
typedef struct _MSG_EVENT_NOTIFY
{
- U8 Switch;
- U8 Reserved;
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
+ U8 Switch; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
} MSG_EVENT_NOTIFY, MPI_POINTER PTR_MSG_EVENT_NOTIFY,
EventNotification_t, MPI_POINTER pEventNotification_t;
typedef struct _MSG_EVENT_NOTIFY_REPLY
{
- U16 EventDataLength;
- U8 MsgLength;
- U8 Function;
- U8 Reserved1[2];
- U8 AckRequired;
- U8 MsgFlags;
- U32 MsgContext;
- U8 Reserved2[2];
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 Event;
- U32 EventContext;
- U32 Data[1];
+ U16 EventDataLength; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[2]; /* 04h */
+ U8 AckRequired; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 Reserved2[2]; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 Event; /* 14h */
+ U32 EventContext; /* 18h */
+ U32 Data[1]; /* 1Ch */
} MSG_EVENT_NOTIFY_REPLY, MPI_POINTER PTR_MSG_EVENT_NOTIFY_REPLY,
EventNotificationReply_t, MPI_POINTER pEventNotificationReply_t;
typedef struct _MSG_EVENT_ACK
{
- U8 Reserved[2];
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- U32 Event;
- U32 EventContext;
+ U8 Reserved[2]; /* 00h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U32 Event; /* 0Ch */
+ U32 EventContext; /* 10h */
} MSG_EVENT_ACK, MPI_POINTER PTR_MSG_EVENT_ACK,
EventAck_t, MPI_POINTER pEventAck_t;
typedef struct _MSG_EVENT_ACK_REPLY
{
- U8 Reserved[2];
- U8 MsgLength;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
+ U8 Reserved[2]; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
} MSG_EVENT_ACK_REPLY, MPI_POINTER PTR_MSG_EVENT_ACK_REPLY,
EventAckReply_t, MPI_POINTER pEventAckReply_t;
#define MPI_EVENT_NOTIFICATION_ACK_NOT_REQUIRED (0x00)
#define MPI_EVENT_NOTIFICATION_ACK_REQUIRED (0x01)
-/* SCSI Event data for Port, Bus and Device forms) */
+/* EventChange Event data */
+
+typedef struct _EVENT_DATA_EVENT_CHANGE
+{
+ U8 EventState; /* 00h */
+ U8 Reserved; /* 01h */
+ U16 Reserved1; /* 02h */
+} EVENT_DATA_EVENT_CHANGE, MPI_POINTER PTR_EVENT_DATA_EVENT_CHANGE,
+ EventDataEventChange_t, MPI_POINTER pEventDataEventChange_t;
+
+/* SCSI Event data for Port, Bus and Device forms */
typedef struct _EVENT_DATA_SCSI
{
- U8 TargetID;
- U8 BusPort;
- U16 Reserved;
+ U8 TargetID; /* 00h */
+ U8 BusPort; /* 01h */
+ U16 Reserved; /* 02h */
} EVENT_DATA_SCSI, MPI_POINTER PTR_EVENT_DATA_SCSI,
EventDataScsi_t, MPI_POINTER pEventDataScsi_t;
typedef struct _EVENT_DATA_LINK_STATUS
{
- U8 State;
- U8 Reserved;
- U16 Reserved1;
- U8 Reserved2;
- U8 Port;
- U16 Reserved3;
+ U8 State; /* 00h */
+ U8 Reserved; /* 01h */
+ U16 Reserved1; /* 02h */
+ U8 Reserved2; /* 04h */
+ U8 Port; /* 05h */
+ U16 Reserved3; /* 06h */
} EVENT_DATA_LINK_STATUS, MPI_POINTER PTR_EVENT_DATA_LINK_STATUS,
EventDataLinkStatus_t, MPI_POINTER pEventDataLinkStatus_t;
typedef struct _EVENT_DATA_LOOP_STATE
{
- U8 Character4;
- U8 Character3;
- U8 Type;
- U8 Reserved;
- U8 Reserved1;
- U8 Port;
- U16 Reserved2;
+ U8 Character4; /* 00h */
+ U8 Character3; /* 01h */
+ U8 Type; /* 02h */
+ U8 Reserved; /* 03h */
+ U8 Reserved1; /* 04h */
+ U8 Port; /* 05h */
+ U16 Reserved2; /* 06h */
} EVENT_DATA_LOOP_STATE, MPI_POINTER PTR_EVENT_DATA_LOOP_STATE,
EventDataLoopState_t, MPI_POINTER pEventDataLoopState_t;
typedef struct _EVENT_DATA_LOGOUT
{
- U32 NPortID;
- U8 Reserved;
- U8 Port;
- U16 Reserved1;
+ U32 NPortID; /* 00h */
+ U8 Reserved; /* 04h */
+ U8 Port; /* 05h */
+ U16 Reserved1; /* 06h */
} EVENT_DATA_LOGOUT, MPI_POINTER PTR_EVENT_DATA_LOGOUT,
EventDataLogout_t, MPI_POINTER pEventDataLogout_t;
typedef struct _EVENT_DATA_RAID_STATUS_CHANGE
{
- U8 VolumeTargetID;
- U8 VolumeBus;
- U8 ReasonCode;
- U8 PhysDiskNum;
- U8 ASC;
- U8 ASCQ;
- U16 Reserved;
+ U8 VolumeTargetID; /* 00h */
+ U8 VolumeBus; /* 01h */
+ U8 ReasonCode; /* 02h */
+ U8 PhysDiskNum; /* 03h */
+ U8 ASC; /* 04h */
+ U8 ASCQ; /* 05h */
+ U16 Reserved; /* 06h */
} EVENT_DATA_RAID_STATUS_CHANGE, MPI_POINTER PTR_EVENT_DATA_RAID_STATUS_CHANGE,
MpiEventDataRaidStatusChange_t, MPI_POINTER pMpiEventDataRaidStatusChange_t;
typedef struct _MSG_FW_DOWNLOAD
{
- U8 ImageType;
- U8 Reserved;
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- SGE_MPI_UNION SGL;
+ U8 ImageType; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ SGE_MPI_UNION SGL; /* 0Ch */
} MSG_FW_DOWNLOAD, MPI_POINTER PTR_MSG_FW_DOWNLOAD,
FWDownload_t, MPI_POINTER pFWDownload_t;
typedef struct _FWDownloadTCSGE
{
- U8 Reserved;
- U8 ContextSize;
- U8 DetailsLength;
- U8 Flags;
- U32 Reserved1;
- U32 ImageOffset;
- U32 ImageSize;
+ U8 Reserved; /* 00h */
+ U8 ContextSize; /* 01h */
+ U8 DetailsLength; /* 02h */
+ U8 Flags; /* 03h */
+ U32 Reserved1; /* 04h */
+ U32 ImageOffset; /* 08h */
+ U32 ImageSize; /* 0Ch */
} FW_DOWNLOAD_TCSGE, MPI_POINTER PTR_FW_DOWNLOAD_TCSGE,
FWDownloadTCSGE_t, MPI_POINTER pFWDownloadTCSGE_t;
/* Firmware Download reply */
typedef struct _MSG_FW_DOWNLOAD_REPLY
{
- U8 ImageType;
- U8 Reserved;
- U8 MsgLength;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
+ U8 ImageType; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
} MSG_FW_DOWNLOAD_REPLY, MPI_POINTER PTR_MSG_FW_DOWNLOAD_REPLY,
FWDownloadReply_t, MPI_POINTER pFWDownloadReply_t;
typedef struct _MSG_FW_UPLOAD
{
- U8 ImageType;
- U8 Reserved;
- U8 ChainOffset;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- SGE_MPI_UNION SGL;
+ U8 ImageType; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ SGE_MPI_UNION SGL; /* 0Ch */
} MSG_FW_UPLOAD, MPI_POINTER PTR_MSG_FW_UPLOAD,
FWUpload_t, MPI_POINTER pFWUpload_t;
typedef struct _FWUploadTCSGE
{
- U8 Reserved;
- U8 ContextSize;
- U8 DetailsLength;
- U8 Flags;
- U32 Reserved1;
- U32 ImageOffset;
- U32 ImageSize;
+ U8 Reserved; /* 00h */
+ U8 ContextSize; /* 01h */
+ U8 DetailsLength; /* 02h */
+ U8 Flags; /* 03h */
+ U32 Reserved1; /* 04h */
+ U32 ImageOffset; /* 08h */
+ U32 ImageSize; /* 0Ch */
} FW_UPLOAD_TCSGE, MPI_POINTER PTR_FW_UPLOAD_TCSGE,
FWUploadTCSGE_t, MPI_POINTER pFWUploadTCSGE_t;
/* Firmware Upload reply */
typedef struct _MSG_FW_UPLOAD_REPLY
{
- U8 ImageType;
- U8 Reserved;
- U8 MsgLength;
- U8 Function;
- U8 Reserved1[3];
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 ActualImageSize;
+ U8 ImageType; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved1[3]; /* 04h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 ActualImageSize; /* 14h */
} MSG_FW_UPLOAD_REPLY, MPI_POINTER PTR_MSG_FW_UPLOAD_REPLY,
FWUploadReply_t, MPI_POINTER pFWUploadReply_t;
typedef struct _MPI_FW_HEADER
{
- U32 ArmBranchInstruction0;
- U32 Signature0;
- U32 Signature1;
- U32 Signature2;
- U32 ArmBranchInstruction1;
- U32 ArmBranchInstruction2;
- U32 Reserved;
- U32 Checksum;
- U16 VendorId;
- U16 ProductId;
- U16 FwVersion;
- U16 Reserved1;
- U32 SeqCodeVersion;
- U32 ImageSize;
- U32 Reserved2;
- U32 LoadStartAddress;
- U32 IopResetVectorValue;
- U32 IopResetRegAddr;
- U32 VersionNameWhat;
- U8 VersionName[32];
- U32 VendorNameWhat;
- U8 VendorName[32];
+ U32 ArmBranchInstruction0; /* 00h */
+ U32 Signature0; /* 04h */
+ U32 Signature1; /* 08h */
+ U32 Signature2; /* 0Ch */
+ U32 ArmBranchInstruction1; /* 10h */
+ U32 ArmBranchInstruction2; /* 14h */
+ U32 Reserved; /* 18h */
+ U32 Checksum; /* 1Ch */
+ U16 VendorId; /* 20h */
+ U16 ProductId; /* 22h */
+ U16 FwVersion; /* 24h */
+ U16 Reserved1; /* 26h */
+ U32 SeqCodeVersion; /* 28h */
+ U32 ImageSize; /* 2Ch */
+ U32 Reserved2; /* 30h */
+ U32 LoadStartAddress; /* 34h */
+ U32 IopResetVectorValue; /* 38h */
+ U32 IopResetRegAddr; /* 3Ch */
+ U32 VersionNameWhat; /* 40h */
+ U8 VersionName[32]; /* 44h */
+ U32 VendorNameWhat; /* 64h */
+ U8 VendorName[32]; /* 68h */
} MPI_FW_HEADER, MPI_POINTER PTR_MPI_FW_HEADER,
MpiFwHeader_t, MPI_POINTER pMpiFwHeader_t;
-#define MPI_FW_HEADER_WHAT_SIGNATURE (0x29232840)
+#define MPI_FW_HEADER_WHAT_SIGNATURE (0x29232840)
+
+/* defines for using the ProductId field */
+#define MPI_FW_HEADER_PID_TYPE_MASK (0xF000)
+#define MPI_FW_HEADER_PID_TYPE_SCSI (0x0000)
+#define MPI_FW_HEADER_PID_TYPE_FC (0x1000)
+
+#define MPI_FW_HEADER_PID_FW_VENDOR_MASK (0x0F00)
+#define MPI_FW_HEADER_PID_FW_VENDOR_LSI (0x0000)
+
+#define MPI_FW_HEADER_PID_FAMILY_MASK (0x000F)
+#define MPI_FW_HEADER_PID_FAMILY_1030_SCSI (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_909_FC (0x0000)
+#define MPI_FW_HEADER_PID_FAMILY_919_FC (0x0001)
+#define MPI_FW_HEADER_PID_FAMILY_919X_FC (0x0002)
typedef struct _MPI_DATA_HEADER
{
- U32 Signature;
- U16 FunctionNumber;
- U16 Length;
- U32 Checksum;
- U32 LoadStartAddress;
+ U32 Signature; /* 00h */
+ U16 FunctionNumber; /* 04h */
+ U16 Length; /* 06h */
+ U32 Checksum; /* 08h */
+ U32 LoadStartAddress; /* 0Ch */
} MPI_DATA_HEADER, MPI_POINTER PTR_MPI_DATA_HEADER,
MpiDataHeader_t, MPI_POINTER pMpiDataHeader_t;
-#define MPI_DATA_HEADER_SIGNATURE (0x43504147)
+#define MPI_DATA_HEADER_SIGNATURE (0x43504147)
#endif
* Title: MPI LAN messages and structures
* Creation Date: June 30, 2000
*
- * MPI Version: 01.01.02
+ * MPI Version: 01.01.03
*
* Version History
* ---------------
* to lan private header file
* 11-02-00 01.01.01 Original release for post 1.0 work
* 02-20-01 01.01.02 Started using MPI_POINTER.
+ * 03-27-01 01.01.03 Added structure offset comments.
* --------------------------------------------------------------------------
*/
typedef struct _MSG_LAN_SEND_REQUEST
{
- U16 Reserved;
- U8 ChainOffset;
- U8 Function;
- U16 Reserved2;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- SGE_MPI_UNION SG_List[1];
+ U16 Reserved; /* 00h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved2; /* 04h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ SGE_MPI_UNION SG_List[1]; /* 0Ch */
} MSG_LAN_SEND_REQUEST, MPI_POINTER PTR_MSG_LAN_SEND_REQUEST,
LANSendRequest_t, MPI_POINTER pLANSendRequest_t;
typedef struct _MSG_LAN_SEND_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U8 Reserved2;
- U8 NumberOfContexts;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 BufferContext;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved2; /* 04h */
+ U8 NumberOfContexts; /* 05h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved3; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 BufferContext; /* 14h */
} MSG_LAN_SEND_REPLY, MPI_POINTER PTR_MSG_LAN_SEND_REPLY,
LANSendReply_t, MPI_POINTER pLANSendReply_t;
typedef struct _MSG_LAN_RECEIVE_POST_REQUEST
{
- U16 Reserved;
- U8 ChainOffset;
- U8 Function;
- U16 Reserved2;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U32 BucketCount;
- SGE_MPI_UNION SG_List[1];
+ U16 Reserved; /* 00h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved2; /* 04h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U32 BucketCount; /* 0Ch */
+ SGE_MPI_UNION SG_List[1]; /* 10h */
} MSG_LAN_RECEIVE_POST_REQUEST, MPI_POINTER PTR_MSG_LAN_RECEIVE_POST_REQUEST,
LANReceivePostRequest_t, MPI_POINTER pLANReceivePostRequest_t;
typedef struct _MSG_LAN_RECEIVE_POST_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U8 Reserved2;
- U8 NumberOfContexts;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 BucketsRemaining;
- U32 PacketOffset;
- U32 PacketLength;
- U32 BucketContext[1];
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 Reserved2; /* 04h */
+ U8 NumberOfContexts; /* 05h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved3; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 BucketsRemaining; /* 14h */
+ U32 PacketOffset; /* 18h */
+ U32 PacketLength; /* 1Ch */
+ U32 BucketContext[1]; /* 20h */
} MSG_LAN_RECEIVE_POST_REPLY, MPI_POINTER PTR_MSG_LAN_RECEIVE_POST_REPLY,
LANReceivePostReply_t, MPI_POINTER pLANReceivePostReply_t;
typedef struct _MSG_LAN_RESET_REQUEST
{
- U16 Reserved;
- U8 ChainOffset;
- U8 Function;
- U16 Reserved2;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
+ U16 Reserved; /* 00h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved2; /* 04h */
+ U8 PortNumber; /* 05h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
} MSG_LAN_RESET_REQUEST, MPI_POINTER PTR_MSG_LAN_RESET_REQUEST,
LANResetRequest_t, MPI_POINTER pLANResetRequest_t;
typedef struct _MSG_LAN_RESET_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U16 Reserved2;
- U8 PortNumber;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved2; /* 04h */
+ U8 PortNumber; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved3; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
} MSG_LAN_RESET_REPLY, MPI_POINTER PTR_MSG_LAN_RESET_REPLY,
LANResetReply_t, MPI_POINTER pLANResetReply_t;
#define MPI_LAN_DEVICE_STATE_OPERATIONAL (0x01)
+/****************************************************************************/
+/* LAN Loopback defines */
+/****************************************************************************/
+
+#define MPI_LAN_TX_MODES_ENABLE_LOOPBACK_SUPPRESSION (0x01)
+
#endif
* Title: MPI Target mode messages and structures
* Creation Date: June 22, 2000
*
- * MPI Version: 01.01.03
+ * MPI Version: 01.01.04
*
* Version History
* ---------------
* 02-20-01 01.01.03 Started using MPI_POINTER.
* Added structures for MPI_TARGET_SCSI_SPI_CMD_BUFFER and
* MPI_TARGET_FCP_CMD_BUFFER.
+ * 03-27-01 01.01.04 Added structure offset comments.
* --------------------------------------------------------------------------
*/
typedef struct _CMD_BUFFER_DESCRIPTOR
{
- U16 IoIndex;
- U16 Reserved;
- union
+ U16 IoIndex; /* 00h */
+ U16 Reserved; /* 02h */
+ union /* 04h */
{
U32 PhysicalAddress32;
U64 PhysicalAddress64;
typedef struct _MSG_TARGET_CMD_BUFFER_POST_REQUEST
{
- U8 BufferPostFlags;
- U8 BufferCount;
- U8 ChainOffset;
- U8 Function;
- U8 BufferLength;
- U8 Reserved;
- U8 Reserved1;
- U8 MsgFlags;
- U32 MsgContext;
- CMD_BUFFER_DESCRIPTOR Buffer[1];
+ U8 BufferPostFlags; /* 00h */
+ U8 BufferCount; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U8 BufferLength; /* 04h */
+ U8 Reserved; /* 05h */
+ U8 Reserved1; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ CMD_BUFFER_DESCRIPTOR Buffer[1]; /* 0Ch */
} MSG_TARGET_CMD_BUFFER_POST_REQUEST, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REQUEST,
TargetCmdBufferPostRequest_t, MPI_POINTER pTargetCmdBufferPostRequest_t;
typedef struct _MSG_TARGET_CMD_BUFFER_POST_REPLY
{
- U8 BufferPostFlags;
- U8 BufferCount;
- U8 MsgLength;
- U8 Function;
- U8 BufferLength;
- U8 Reserved;
- U8 Reserved1;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved2;
- U16 IOCStatus;
- U32 IOCLogInfo;
+ U8 BufferPostFlags; /* 00h */
+ U8 BufferCount; /* 01h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U8 BufferLength; /* 04h */
+ U8 Reserved; /* 05h */
+ U8 Reserved1; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved2; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
} MSG_TARGET_CMD_BUFFER_POST_REPLY, MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_REPLY,
TargetCmdBufferPostReply_t, MPI_POINTER pTargetCmdBufferPostReply_t;
typedef struct _MSG_PRIORITY_CMD_RECEIVED_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U16 Reserved1;
- U8 Reserved2;
- U8 MsgFlags;
- U32 MsgContext;
- U8 PriorityReason;
- U8 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 ReplyWord;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 Reserved2; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U8 PriorityReason; /* 0Ch */
+ U8 Reserved3; /* 0Dh */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 ReplyWord; /* 14h */
} MSG_PRIORITY_CMD_RECEIVED_REPLY, MPI_POINTER PTR_MSG_PRIORITY_CMD_RECEIVED_REPLY,
PriorityCommandReceivedReply_t, MPI_POINTER pPriorityCommandReceivedReply_t;
typedef struct _MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U16 Reserved1;
- U8 Reserved2;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 ReplyWord;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 Reserved2; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved3; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 ReplyWord; /* 14h */
} MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
MPI_POINTER PTR_MSG_TARGET_CMD_BUFFER_POST_ERROR_REPLY,
TargetCmdBufferPostErrorReply_t, MPI_POINTER pTargetCmdBufferPostErrorReply_t;
typedef struct _MPI_TARGET_FCP_CMD_BUFFER
{
- U8 FcpLun[8];
- U8 FcpCntl[4];
- U8 FcpCdb[16];
- U32 FcpDl;
+ U8 FcpLun[8]; /* 00h */
+ U8 FcpCntl[4]; /* 08h */
+ U8 FcpCdb[16]; /* 0Ch */
+ U32 FcpDl; /* 1Ch */
} MPI_TARGET_FCP_CMD_BUFFER, MPI_POINTER PTR_MPI_TARGET_FCP_CMD_BUFFER,
MpiTargetFcpCmdBuffer, MPI_POINTER pMpiTargetFcpCmdBuffer;
typedef struct _MPI_TARGET_SCSI_SPI_CMD_BUFFER
{
/* SPI L_Q information unit */
- U8 L_QType;
- U8 Reserved;
- U16 Tag;
- U8 LogicalUnitNumber[8];
- U32 DataLength;
+ U8 L_QType; /* 00h */
+ U8 Reserved; /* 01h */
+ U16 Tag; /* 02h */
+ U8 LogicalUnitNumber[8]; /* 04h */
+ U32 DataLength; /* 0Ch */
/* SPI command information unit */
- U8 ReservedFirstByteOfCommandIU;
- U8 TaskAttribute;
- U8 TaskManagementFlags;
- U8 AdditionalCDBLength;
- U8 CDB[16];
+ U8 ReservedFirstByteOfCommandIU; /* 10h */
+ U8 TaskAttribute; /* 11h */
+ U8 TaskManagementFlags; /* 12h */
+ U8 AdditionalCDBLength; /* 13h */
+ U8 CDB[16]; /* 14h */
} MPI_TARGET_SCSI_SPI_CMD_BUFFER,
MPI_POINTER PTR_MPI_TARGET_SCSI_SPI_CMD_BUFFER,
MpiTargetScsiSpiCmdBuffer, MPI_POINTER pMpiTargetScsiSpiCmdBuffer;
typedef struct _MSG_TARGET_ASSIST_REQUEST
{
- U8 StatusCode;
- U8 TargetAssistFlags;
- U8 ChainOffset;
- U8 Function;
- U16 QueueTag;
- U8 Reserved;
- U8 MsgFlags;
- U32 MsgContext;
- U32 ReplyWord;
- U8 LUN[8];
- U32 RelativeOffset;
- U32 DataLength;
- SGE_IO_UNION SGL[1];
+ U8 StatusCode; /* 00h */
+ U8 TargetAssistFlags; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 QueueTag; /* 04h */
+ U8 Reserved; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U32 ReplyWord; /* 0Ch */
+ U8 LUN[8]; /* 10h */
+ U32 RelativeOffset; /* 18h */
+ U32 DataLength; /* 1Ch */
+ SGE_IO_UNION SGL[1]; /* 20h */
} MSG_TARGET_ASSIST_REQUEST, MPI_POINTER PTR_MSG_TARGET_ASSIST_REQUEST,
TargetAssistRequest_t, MPI_POINTER pTargetAssistRequest_t;
typedef struct _MSG_TARGET_ERROR_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U16 Reserved1;
- U8 Reserved2;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 ReplyWord;
- U32 TransferCount;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 Reserved2; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved3; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 ReplyWord; /* 14h */
+ U32 TransferCount; /* 18h */
} MSG_TARGET_ERROR_REPLY, MPI_POINTER PTR_MSG_TARGET_ERROR_REPLY,
TargetErrorReply_t, MPI_POINTER pTargetErrorReply_t;
typedef struct _MSG_TARGET_STATUS_SEND_REQUEST
{
- U8 StatusCode;
- U8 StatusFlags;
- U8 ChainOffset;
- U8 Function;
- U16 QueueTag;
- U8 Reserved;
- U8 MsgFlags;
- U32 MsgContext;
- U32 ReplyWord;
- U8 LUN[8];
- SGE_SIMPLE_UNION StatusDataSGE;
+ U8 StatusCode; /* 00h */
+ U8 StatusFlags; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 QueueTag; /* 04h */
+ U8 Reserved; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U32 ReplyWord; /* 0Ch */
+ U8 LUN[8]; /* 10h */
+ SGE_SIMPLE_UNION StatusDataSGE; /* 18h */
} MSG_TARGET_STATUS_SEND_REQUEST, MPI_POINTER PTR_MSG_TARGET_STATUS_SEND_REQUEST,
TargetStatusSendRequest_t, MPI_POINTER pTargetStatusSendRequest_t;
typedef struct _MSG_TARGET_MODE_ABORT_REQUEST
{
- U8 AbortType;
- U8 Reserved;
- U8 ChainOffset;
- U8 Function;
- U16 Reserved1;
- U8 Reserved2;
- U8 MsgFlags;
- U32 MsgContext;
- U32 ReplyWord;
- U32 MsgContextToAbort;
+ U8 AbortType; /* 00h */
+ U8 Reserved; /* 01h */
+ U8 ChainOffset; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 Reserved2; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U32 ReplyWord; /* 0Ch */
+ U32 MsgContextToAbort; /* 10h */
} MSG_TARGET_MODE_ABORT, MPI_POINTER PTR_MSG_TARGET_MODE_ABORT,
TargetModeAbort_t, MPI_POINTER pTargetModeAbort_t;
typedef struct _MSG_TARGET_MODE_ABORT_REPLY
{
- U16 Reserved;
- U8 MsgLength;
- U8 Function;
- U16 Reserved1;
- U8 Reserved2;
- U8 MsgFlags;
- U32 MsgContext;
- U16 Reserved3;
- U16 IOCStatus;
- U32 IOCLogInfo;
- U32 AbortCount;
+ U16 Reserved; /* 00h */
+ U8 MsgLength; /* 02h */
+ U8 Function; /* 03h */
+ U16 Reserved1; /* 04h */
+ U8 Reserved2; /* 06h */
+ U8 MsgFlags; /* 07h */
+ U32 MsgContext; /* 08h */
+ U16 Reserved3; /* 0Ch */
+ U16 IOCStatus; /* 0Eh */
+ U32 IOCLogInfo; /* 10h */
+ U32 AbortCount; /* 14h */
} MSG_TARGET_MODE_ABORT_REPLY, MPI_POINTER PTR_MSG_TARGET_MODE_ABORT_REPLY,
TargetModeAbortReply_t, MPI_POINTER pTargetModeAbortReply_t;
* Originally By: Steven J. Ralston
* (mailto:Steve.Ralston@lsil.com)
*
- * $Id: mptbase.c,v 1.47 2001/03/22 10:32:23 sralston Exp $
+ * $Id: mptbase.c,v 1.53.4.1 2001/08/24 20:07:05 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
const char **mpt_ScsiOpcodesPtr = NULL;
int mpt_ASCQ_TableSz = 0;
+#define WHOINIT_UNKNOWN 0xAA
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Private data...
static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
/* Event handler lookup table */
static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
+ /* Reset handler lookup table */
+static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
static int FusionInitCalled = 0;
static int mpt_base_index = -1;
static void mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
+static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason);
static int mpt_adapter_install(struct pci_dev *pdev);
static void mpt_detect_929_bound_ports(MPT_ADAPTER *this, struct pci_dev *pdev);
-static void mpt_adapter_disable(MPT_ADAPTER *ioc);
+static void mpt_adapter_disable(MPT_ADAPTER *ioc, int freeup);
static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
+static int MakeIocReady(MPT_ADAPTER *ioc, int force);
static u32 GetIocState(MPT_ADAPTER *ioc, int cooked);
static int GetIocFacts(MPT_ADAPTER *ioc);
-static int GetPortFacts(MPT_ADAPTER *ioc);
+static int GetPortFacts(MPT_ADAPTER *ioc, int portnum);
static int SendIocInit(MPT_ADAPTER *ioc);
static int SendPortEnable(MPT_ADAPTER *ioc, int portnum);
-static int mpt_fc9x9_reset(MPT_ADAPTER *ioc);
-static int KickStart(MPT_ADAPTER *ioc);
+static int mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore);
+static int KickStart(MPT_ADAPTER *ioc, int ignore);
static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type);
static int PrimeIocFifos(MPT_ADAPTER *ioc);
-static int HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply);
-static int WaitForDoorbellAck(MPT_ADAPTER *ioc);
-static int WaitForDoorbellInt(MPT_ADAPTER *ioc);
-static int WaitForDoorbellReply(MPT_ADAPTER *ioc);
+static int HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait);
+static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong);
+static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong);
+static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong);
static int GetLanConfigPages(MPT_ADAPTER *ioc);
static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
static struct proc_dir_entry *procmpt_root_dir = NULL;
int fusion_init(void);
+static void fusion_exit(void);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* 20000207 -sralston
MptEvHandlers[cb_idx] = NULL;
}
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ * mpt_reset_register - Register protocol-specific IOC reset handler.
+ * @cb_idx: previously registered (via mpt_register) callback handle
+ * @reset_func: reset function
+ *
+ * This routine can be called by one or more protocol-specific drivers
+ * if/when they choose to be notified of IOC resets.
+ *
+ * Returns 0 for success.
+ */
+int
+mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
+{
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+ return -1;
+
+ MptResetHandlers[cb_idx] = reset_func;
+ return 0;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
+ * @cb_idx: previously registered callback handle
+ *
+ * Each protocol-specific driver should call this routine
+ * when it does not (or can no longer) handle IOC reset handling,
+ * or when it's module is unloaded.
+ */
+void
+mpt_reset_deregister(int cb_idx)
+{
+ if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
+ return;
+
+ MptResetHandlers[cb_idx] = NULL;
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
iocp = mpt_adapters[iocid];
if (iocp != NULL) {
- u8 *req_as_bytes;
- int i;
+ u8 *req_as_bytes;
+ u32 ioc_raw_state;
+ int i;
+
+ /* YIKES! We already know something is amiss.
+ * Do upfront check on IOC state.
+ */
+ ioc_raw_state = GetIocState(iocp, 0);
+ if ((ioc_raw_state & MPI_DOORBELL_ACTIVE) ||
+ ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL)) {
+ printk(KERN_WARNING MYNAM ": %s: Bad IOC state (%08x) WARNING!\n",
+ iocp->name, ioc_raw_state);
+ if ((r = mpt_do_ioc_recovery(iocp, MPT_HOSTEVENT_IOC_RECOVER)) != 0) {
+ printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
+ r, iocp->name);
+ return r;
+ }
+ }
/*
- * Emulate what mpt_put_msg_frame() does /wrt to sanity
- * setting cb_idx/req_idx. But ONLY if this request
- * is in proper (pre-alloc'd) request buffer range...
+ * Emulate what mpt_put_msg_frame() does /wrt to sanity
+ * setting cb_idx/req_idx. But ONLY if this request
+ * is in proper (pre-alloc'd) request buffer range...
*/
i = MFPTR_2_MPT_INDEX(iocp,(MPT_FRAME_HDR*)req);
if (reqBytes >= 12 && i >= 0 && i < iocp->req_depth) {
mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
}
- /* Make sure there are no doorbells */
+ /* Make sure there are no doorbells */
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
CHIPREG_WRITE32(&iocp->chip->Doorbell,
((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
- /* Wait for IOC doorbell int */
- if ((i = WaitForDoorbellInt(iocp)) < 0) {
- /* FIXME! Recovery action(s)? */
- /*i = unresponsive_ioc(i);*/
+ /* Wait for IOC doorbell int */
+ if ((i = WaitForDoorbellInt(iocp, 2)) < 0) {
return i;
}
CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
- if ((r = WaitForDoorbellAck(iocp)) < 0)
+ if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
return -2;
+ }
- /* Send request via doorbell handshake */
+ /* Send request via doorbell handshake */
req_as_bytes = (u8 *) req;
for (i = 0; i < reqBytes/4; i++) {
u32 word;
(req_as_bytes[(i*4) + 2] << 16) |
(req_as_bytes[(i*4) + 3] << 24));
CHIPREG_WRITE32(&iocp->chip->Doorbell, word);
- if ((r = WaitForDoorbellAck(iocp)) < 0) {
+ if ((r = WaitForDoorbellAck(iocp, 1)) < 0) {
r = -3;
break;
}
}
- /* Make sure there are no doorbells */
- CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
+ if ((r = WaitForDoorbellInt(iocp, 2)) >= 0)
+ r = 0;
+ else
+ r = -4;
+ /* Make sure there are no doorbells */
+ CHIPREG_WRITE32(&iocp->chip->IntStatus, 0);
}
return r;
if ((pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC909) &&
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC929) &&
-#if 0
- /* FIXME! FC919 */
(pdev->device != MPI_MANUFACTPAGE_DEVICEID_FC919) &&
+#if 0
/* FIXME! C103x family */
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030) &&
(pdev->device != MPI_MANUFACTPAGE_DEVID_53C1030_ZC) &&
printk(KERN_INFO MYNAM ": %d MPT adapter%s found, %d installed.\n",
found, (found==1) ? "" : "s", count);
- if (count == 0)
+ if (!found || !count) {
+ fusion_exit();
return -ENODEV;
+ }
#ifdef CONFIG_PROC_FS
if (procmpt_create() != 0)
unsigned long port;
u32 msize;
u32 psize;
- u32 ioc_state;
int i;
int r = -ENODEV;
- int cntdn;
int len;
- int statefault = 0;
ioc = kmalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
if (ioc == NULL) {
ioc->pcidev = pdev;
- /* Find lookup slot. GRRRR... */
+ /* Find lookup slot. */
for (i=0; i < MPT_MAX_ADAPTERS; i++) {
if (mpt_adapters[i] == NULL) {
ioc->id = i; /* Assign adapter unique id (lookup) */
port = psize = 0;
for (i=0; i < DEVICE_COUNT_RESOURCE; i++) {
if (pdev->PCI_BASEADDR_FLAGS(i) & PCI_BASE_ADDRESS_SPACE_IO) {
- /* Get I/O space! */
+ /* Get I/O space! */
port = pdev->PCI_BASEADDR_START(i);
psize = PCI_BASEADDR_SIZE(pdev,i);
} else {
- /* Get memmap */
+ /* Get memmap */
mem_phys = pdev->PCI_BASEADDR_START(i);
msize = PCI_BASEADDR_SIZE(pdev,i);
break;
mem = NULL;
if (! PortIo) {
- /* Get logical ptr for PciMem0 space */
+ /* Get logical ptr for PciMem0 space */
/*mem = ioremap(mem_phys, msize);*/
mem = ioremap(mem_phys, 0x100);
if (mem == NULL) {
ioc->chip_type = FC929;
ioc->prod_name = "LSIFC929";
}
-#if 0
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
- ioc->chip_type = C1030;
+ ioc->chip_type = FC919;
ioc->prod_name = "LSIFC919";
}
+#if 0
else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_53C1030) {
ioc->chip_type = C1030;
ioc->prod_name = "LSI53C1030";
Q_INIT(&ioc->FreeQ, MPT_FRAME_HDR);
spin_lock_init(&ioc->FreeQlock);
- /* Disable all! */
+ /* Disable all! */
CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
- CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
ioc->active = 0;
+ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
ioc->pci_irq = -1;
if (pdev->irq) {
dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
}
- /* tack onto tail of our MPT adapter list */
+ /* tack onto tail of our MPT adapter list */
Q_ADD_TAIL(&MptAdapters, ioc, MPT_ADAPTER);
/* Set lookup ptr. */
if (ioc->chip_type == FC929)
mpt_detect_929_bound_ports(ioc, pdev);
- /* Get current [raw] IOC state */
- ioc_state = GetIocState(ioc, 0);
- dhsprintk((KERN_INFO MYNAM ": %s initial [raw] state=%08x\n", ioc->name, ioc_state));
+ if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP)) != 0) {
+ printk(KERN_WARNING MYNAM ": WARNING - %s did not initialize properly! (%d)\n",
+ ioc->name, r);
+ }
- /*
- * Check to see if IOC got left/stuck in doorbell handshake
- * grip of death. If so, hard reset the IOC.
- */
- if (ioc_state & MPI_DOORBELL_ACTIVE) {
- statefault = 1;
- printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+ return r;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
+ * @ioc: Pointer to MPT adapter structure
+ * @reason: Event word / reason
+ *
+ * This routine performs all the steps necessary to bring the IOC
+ * to a OPERATIONAL state.
+ *
+ * This routine also pre-fetches the LAN MAC address of a Fibre Channel
+ * MPT adapter.
+ *
+ * Returns 0 for success.
+ */
+static int
+mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason)
+{
+ int hard_reset_done = 0;
+ int alt_ioc_ready = 0;
+ int hard;
+ int r;
+ int i;
+ int handlers;
+
+ printk(KERN_INFO MYNAM ": Initiating %s %s\n",
+ ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
+
+ /* Disable reply interrupts */
+ CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
+ ioc->active = 0;
+ /* NOTE: Access to IOC's request FreeQ is now blocked! */
+
+// FIXME? Cleanup all IOC requests here! (or below?)
+// But watch out for event associated request?
+
+ hard = HardReset;
+ if (ioc->alt_ioc && (reason == MPT_HOSTEVENT_IOC_BRINGUP))
+ hard = 0;
+
+ if ((hard_reset_done = MakeIocReady(ioc, hard)) < 0) {
+ printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
ioc->name);
+ return -1;
}
- /*
- * Check to see if IOC is in FAULT state.
- * If so, hard reset the IOC.
- */
- if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
- statefault = 2;
- printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
- ioc->name);
- printk(KERN_WARNING " FAULT code = %04xh\n",
- ioc_state & MPI_DOORBELL_DATA_MASK);
+// NEW!
+#if 0 // Kiss-of-death!?!
+ if (ioc->alt_ioc) {
+// Grrr... Hold off any alt-IOC interrupts (and events) while
+// handshaking to <this> IOC, needed because?
+ /* Disable alt-IOC's reply interrupts for a bit ... */
+ alt_ioc_intmask = CHIPREG_READ32(&ioc->alt_ioc->chip->IntMask);
+ CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
+ ioc->alt_ioc->active = 0;
+ /* NOTE: Access to alt-IOC's request FreeQ is now blocked! */
}
+#endif
- if (HardReset || statefault) {
- if ((r = KickStart(ioc)) != 0) {
- r = -ENODEV;
- goto ioc_up_fail;
- }
+ if (hard_reset_done && ioc->alt_ioc) {
+ if ((r = MakeIocReady(ioc->alt_ioc, 0)) == 0)
+ alt_ioc_ready = 1;
+ else
+ printk(KERN_WARNING MYNAM ": alt-%s: (%d) Not ready WARNING!\n",
+ ioc->alt_ioc->name, r);
+ }
+
+ if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
+ /* Get IOC facts! */
+ if ((r = GetIocFacts(ioc)) != 0)
+ return -2;
+ MptDisplayIocCapabilities(ioc);
}
/*
- * Loop here waiting for IOC to come READY.
+ * Call each currently registered protocol IOC reset handler
+ * with pre-reset indication.
+ * NOTE: If we're doing _IOC_BRINGUP, there can be no
+ * MptResetHandlers[] registered yet.
*/
- i = 0;
- cntdn = HZ * 10;
- while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
- if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
- /*
- * BIOS or previous driver load left IOC in OP state.
- * Reset messaging FIFOs.
- */
- dprintk((KERN_WARNING MYNAM ": %s: Sending IOC msg unit reset!\n", ioc->name));
- if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
- printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
- r = -ENODEV;
- goto ioc_up_fail;
- }
- } else if (ioc_state == MPI_IOC_STATE_RESET) {
- /*
- * Something is wrong. Try to get IOC back
- * to a known state.
- */
- dprintk((KERN_WARNING MYNAM ": %s: Sending IO unit reset!\n", ioc->name));
- if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
- printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
- r = -ENODEV;
- goto ioc_up_fail;
+ if (hard_reset_done) {
+ r = handlers = 0;
+ for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
+ if (MptResetHandlers[i]) {
+ dprintk((KERN_INFO MYNAM ": %s: Calling IOC pre_reset handler #%d\n",
+ ioc->name, i));
+ r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_PRE_RESET);
+ handlers++;
+
+ if (alt_ioc_ready) {
+ dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC pre_reset handler #%d\n",
+ ioc->alt_ioc->name, i));
+ r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
+ handlers++;
+ }
}
}
+ /* FIXME? Examine results here? */
+ }
- i++; cntdn--;
- if (!cntdn) {
- printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
- ioc->name, (i+5)/HZ);
- r = -ETIME;
- goto ioc_up_fail;
- }
+ // May need to check/upload firmware & data here!
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
+ if ((r = SendIocInit(ioc)) != 0)
+ return -3;
+// NEW!
+ if (alt_ioc_ready) {
+ if ((r = SendIocInit(ioc->alt_ioc)) != 0) {
+ alt_ioc_ready = 0;
+ printk(KERN_WARNING MYNAM ": alt-%s: (%d) init failure WARNING!\n",
+ ioc->alt_ioc->name, r);
+ }
}
- if (statefault) {
- printk(KERN_WARNING MYNAM ": %s: Whew! Recovered from %s\n",
- ioc->name, statefault==1 ? "stuck handshake" : "IOC FAULT");
+ /*
+ * Call each currently registered protocol IOC reset handler
+ * with post-reset indication.
+ * NOTE: If we're doing _IOC_BRINGUP, there can be no
+ * MptResetHandlers[] registered yet.
+ */
+ if (hard_reset_done) {
+ r = handlers = 0;
+ for (i=MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
+ if (MptResetHandlers[i]) {
+ dprintk((KERN_INFO MYNAM ": %s: Calling IOC post_reset handler #%d\n",
+ ioc->name, i));
+ r += (*(MptResetHandlers[i]))(ioc, MPT_IOC_POST_RESET);
+ handlers++;
+
+ if (alt_ioc_ready) {
+ dprintk((KERN_INFO MYNAM ": %s: Calling alt-IOC post_reset handler #%d\n",
+ ioc->alt_ioc->name, i));
+ r += (*(MptResetHandlers[i]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
+ handlers++;
+ }
+ }
+ }
+ /* FIXME? Examine results here? */
}
- /* Enable! (reply interrupt) */
- CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
- ioc->active = 1;
-
- /* Get IOC facts! (first time, ioc->facts0 and ioc->pfacts0) */
- if ((r = GetIocFacts(ioc)) != 0)
- goto ioc_up_fail;
-
- /* Does IocFacts.EventState need any looking at / attention here? */
-
- if ((r = SendIocInit(ioc)) != 0)
- goto ioc_up_fail;
-
/*
- * Prime reply & request queues!
- * (mucho alloc's)
+ * Prime reply & request queues!
+ * (mucho alloc's)
*/
if ((r = PrimeIocFifos(ioc)) != 0)
- goto ioc_up_fail;
-
- /* Get IOC facts again! (2nd time, ioc->factsN and ioc->pfactsN) */
- if ((r = GetIocFacts(ioc)) != 0)
- goto ioc_up_fail;
-
- /* Does IocFacts.EventState need any looking at / attention here? */
+ return -4;
+// NEW!
+ if (alt_ioc_ready && ((r = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
+ printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
+ ioc->alt_ioc->name, r);
+ }
- MptDisplayIocCapabilities(ioc);
+// FIXME! Cleanup all IOC (and alt-IOC?) requests here!
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+ if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
+ (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
/*
* Pre-fetch the ports LAN MAC address!
* (LANPage1_t stuff)
#endif
}
+ /* Enable! (reply interrupt) */
+ CHIPREG_WRITE32(&ioc->chip->IntMask, ~(MPI_HIM_RIM));
+ ioc->active = 1;
+
+// NEW!
+#if 0 // Kiss-of-death!?!
+ if (alt_ioc_ready && (r==0)) {
+ /* (re)Enable alt-IOC! (reply interrupt) */
+ dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
+ ioc->alt_ioc->name));
+ CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, ~(MPI_HIM_RIM));
+ ioc->alt_ioc->active = 1;
+ }
+#endif
+
/* NEW! 20010120 -sralston
* Enable MPT base driver management of EventNotification
* and EventAck handling.
*/
- (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
+ if (!ioc->facts.EventState)
+ (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
+// NEW!
+// FIXME!?!
+// if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) {
+// (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
+// }
return 0;
-
-ioc_up_fail:
- //Q_DEL_ITEM(ioc);
- //mpt_adapter_dispose(ioc);
- mpt_adapter_disable(ioc);
- return r;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* mpt_adapter_disable - Disable misbehaving MPT adapter.
* @this: Pointer to MPT adapter structure
+ * @free: Free up alloc'd reply, request, etc.
*/
static void
-mpt_adapter_disable(MPT_ADAPTER *this)
+mpt_adapter_disable(MPT_ADAPTER *this, int freeup)
{
if (this != NULL) {
int sz;
+ /* Disable the FW */
+ if (SendIocReset(this, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET) != 0)
+ (void) KickStart(this, 1);
+
/* Disable adapter interrupts! */
CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
+ this->active = 0;
/* Clear any lingering interrupt */
CHIPREG_WRITE32(&this->chip->IntStatus, 0);
- this->active = 0;
- if (this->reply_alloc != NULL) {
+ if (freeup && this->reply_alloc != NULL) {
sz = (this->reply_sz * this->reply_depth) + 128;
pci_free_consistent(this->pcidev, sz,
this->reply_alloc, this->reply_alloc_dma);
this->alloc_total -= sz;
}
- if (this->req_alloc != NULL) {
+ if (freeup && this->req_alloc != NULL) {
sz = (this->req_sz * this->req_depth) + 128;
/*
* Rounding UP to nearest 4-kB boundary here...
this->alloc_total -= sz;
}
- if (this->sense_buf_pool != NULL) {
+ if (freeup && this->sense_buf_pool != NULL) {
sz = (this->req_depth * 256);
pci_free_consistent(this->pcidev, sz,
this->sense_buf_pool, this->sense_buf_pool_dma);
sz_first = this->alloc_total;
- mpt_adapter_disable(this);
+ mpt_adapter_disable(this, 1);
if (this->pci_irq != -1) {
free_irq(this->pci_irq, this);
printk("%s: ", ioc->prod_name+3);
printk("Capabilities={");
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
+ if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
printk("Initiator");
i++;
}
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+ if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
printk("%sTarget", i ? "," : "");
i++;
}
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+ if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
printk("%sLAN", i ? "," : "");
i++;
}
/*
* This would probably evoke more questions than it's worth
*/
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
+ if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
printk("%sLogBusAddr", i ? "," : "");
i++;
}
printk("}\n");
}
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
+ * @ioc: Pointer to MPT_ADAPTER structure
+ * @kick: Force hard KickStart of IOC
+ *
+ * Returns 0 for already-READY, 1 for hard reset success,
+ * else negative for failure.
+ */
+static int
+MakeIocReady(MPT_ADAPTER *ioc, int force)
+{
+ u32 ioc_state;
+ int statefault = 0;
+ int cntdn;
+ int hard_reset_done = 0;
+ int r;
+ int i;
+
+ /* Get current [raw] IOC state */
+ ioc_state = GetIocState(ioc, 0);
+ dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
+
+ /*
+ * Check to see if IOC got left/stuck in doorbell handshake
+ * grip of death. If so, hard reset the IOC.
+ */
+ if (ioc_state & MPI_DOORBELL_ACTIVE) {
+ statefault = 1;
+ printk(KERN_WARNING MYNAM ": %s: Uh-oh, unexpected doorbell active!\n",
+ ioc->name);
+ }
+
+ /* Is it already READY? */
+ if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
+ return 0;
+
+ /*
+ * Check to see if IOC is in FAULT state.
+ */
+ if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
+ statefault = 2;
+ printk(KERN_WARNING MYNAM ": %s: Uh-oh, IOC is in FAULT state!!!\n",
+ ioc->name);
+ printk(KERN_WARNING " FAULT code = %04xh\n",
+ ioc_state & MPI_DOORBELL_DATA_MASK);
+ }
+
+ /*
+ * Hmmm... Did it get left operational?
+ */
+ if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
+ statefault = 3;
+ dprintk((KERN_WARNING MYNAM ": %s: Hmmm... IOC operational unexpected\n",
+ ioc->name));
+ }
+
+ hard_reset_done = KickStart(ioc, statefault||force);
+ if (hard_reset_done < 0)
+ return -1;
+
+ /*
+ * Loop here waiting for IOC to come READY.
+ */
+ i = 0;
+ cntdn = HZ * 15;
+ while ((ioc_state = GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
+ if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
+ /*
+ * BIOS or previous driver load left IOC in OP state.
+ * Reset messaging FIFOs.
+ */
+ if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET)) != 0) {
+ printk(KERN_ERR MYNAM ": %s: ERROR - IOC msg unit reset failed!\n", ioc->name);
+ return -2;
+ }
+ } else if (ioc_state == MPI_IOC_STATE_RESET) {
+ /*
+ * Something is wrong. Try to get IOC back
+ * to a known state.
+ */
+ if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET)) != 0) {
+ printk(KERN_ERR MYNAM ": %s: ERROR - IO unit reset failed!\n", ioc->name);
+ return -3;
+ }
+ }
+
+ i++; cntdn--;
+ if (!cntdn) {
+ printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
+ ioc->name, (i+5)/HZ);
+ return -ETIME;
+ }
+
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
+ }
+
+ if (statefault < 3) {
+ printk(KERN_WARNING MYNAM ": %s: Whew! Recovered from %s\n",
+ ioc->name,
+ statefault==1 ? "stuck handshake" : "IOC FAULT");
+ }
+
+ return hard_reset_done;
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* GetIocState - Get the current state of a MPT adapter.
int reply_sz;
u32 status;
- /* IOC *must* NOT be in RESET state! */
+ /* IOC *must* NOT be in RESET state! */
if (ioc->last_state == MPI_IOC_STATE_RESET) {
printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
ioc->name,
return -44;
}
- facts = &ioc->facts0;
- /* Nth (2,3,...) time thru? (been here, done that?) */
- if (ioc->facts0.Function == MPI_FUNCTION_IOC_FACTS) {
- facts = &ioc->factsN;
- }
+ facts = &ioc->facts;
- /* Destination (reply area)... */
+ /* Destination (reply area)... */
reply_sz = sizeof(*facts);
memset(facts, 0, reply_sz);
- /* Request area (get_facts on the stack right now!) */
+ /* Request area (get_facts on the stack right now!) */
req_sz = sizeof(get_facts);
memset(&get_facts, 0, req_sz);
get_facts.Function = MPI_FUNCTION_IOC_FACTS;
- /* Assert: All other get_facts fields are zero! */
+ /* Assert: All other get_facts fields are zero! */
- dprintk((KERN_INFO MYNAM ": %s: Sending IocFacts%s request\n",
- ioc->name, facts == &ioc->facts0 ? "0" : "N" ));
+ dprintk((KERN_INFO MYNAM ": %s: Sending get IocFacts request\n", ioc->name));
/* No non-zero fields in the get_facts request are greater than
* 1 byte in size, so we can just fire it off as is.
*/
r = HandShakeReqAndReply(ioc,
req_sz, (u32*)&get_facts,
- reply_sz, (u16*)facts);
+ reply_sz, (u16*)facts, 3);
if (r != 0)
return r;
/*
- * Now byte swap the necessary fields before any further
- * inspection of reply contents.
+ * Now byte swap (GRRR) the necessary fields before any further
+ * inspection of reply contents.
*
- * But need to do some sanity checks on MsgLength (byte) field
- * to make sure we don't zero IOC's req_sz!
+ * But need to do some sanity checks on MsgLength (byte) field
+ * to make sure we don't zero IOC's req_sz!
*/
/* Did we get a valid reply? */
if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
+ /*
+ * If not been here, done that, save off first WhoInit value
+ */
+ if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
+ ioc->FirstWhoInit = facts->WhoInit;
+
facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
facts->MsgContext = le32_to_cpu(facts->MsgContext);
facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
le16_to_cpu(facts->CurReplyFrameSize);
/*
- * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
- * Older MPI-1.00.xx struct had 13 dwords, and enlarged
- * to 14 in MPI-1.01.0x.
+ * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
+ * Older MPI-1.00.xx struct had 13 dwords, and enlarged
+ * to 14 in MPI-1.01.0x.
*/
if (facts->MsgLength >= sizeof(IOCFactsReply_t)/sizeof(u32) && facts->MsgVersion > 0x0100) {
facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
if (facts->RequestFrameSize) {
/*
- * Set values for this IOC's REQUEST queue size & depth...
+ * Set values for this IOC's REQUEST queue size & depth...
*/
ioc->req_sz = MIN(MPT_REQ_SIZE, facts->RequestFrameSize * 4);
dprintk((KERN_INFO MYNAM ": %s: req_sz =%3d, req_depth =%4d\n",
ioc->name, ioc->req_sz, ioc->req_depth));
- /* Get port facts! */
- if ( (r = GetPortFacts(ioc)) != 0 )
+ /* Get port facts! */
+ if ( (r = GetPortFacts(ioc, 0)) != 0 )
return r;
} else {
printk(KERN_ERR MYNAM ": %s: ERROR - Invalid IOC facts reply!\n",
/*
* GetPortFacts - Send PortFacts request to MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
+ * @portnum: Port number
*
* Returns 0 for success, non-zero for failure.
*/
static int
-GetPortFacts(MPT_ADAPTER *ioc)
+GetPortFacts(MPT_ADAPTER *ioc, int portnum)
{
PortFacts_t get_pfacts;
PortFactsReply_t *pfacts;
int req_sz;
int reply_sz;
- /* IOC *must* NOT be in RESET state! */
+ /* IOC *must* NOT be in RESET state! */
if (ioc->last_state == MPI_IOC_STATE_RESET) {
printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
ioc->name,
return -4;
}
- pfacts = &ioc->pfacts0;
- /* Nth (2,3,...) time thru? (been here, done that?) */
- if (ioc->pfacts0.Function == MPI_FUNCTION_PORT_FACTS) {
- pfacts = &ioc->pfactsN;
- }
+ pfacts = &ioc->pfacts[portnum];
- /* Destination (reply area)... */
+ /* Destination (reply area)... */
reply_sz = sizeof(*pfacts);
memset(pfacts, 0, reply_sz);
- /* Request area (get_pfacts on the stack right now!) */
+ /* Request area (get_pfacts on the stack right now!) */
req_sz = sizeof(get_pfacts);
memset(&get_pfacts, 0, req_sz);
get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
- /* Assert: All other get_pfacts fields are zero! */
+ get_pfacts.PortNumber = portnum;
+ /* Assert: All other get_pfacts fields are zero! */
- dprintk((KERN_INFO MYNAM ": %s: Sending PortFacts%s request\n",
- ioc->name, pfacts == &ioc->pfacts0 ? "0" : "N" ));
+ dprintk((KERN_INFO MYNAM ": %s: Sending get PortFacts(%d) request\n",
+ ioc->name, portnum));
/* No non-zero fields in the get_pfacts request are greater than
* 1 byte in size, so we can just fire it off as is.
*/
i = HandShakeReqAndReply(ioc, req_sz, (u32*)&get_pfacts,
- reply_sz, (u16*)pfacts);
+ reply_sz, (u16*)pfacts, 3);
if (i != 0)
return i;
dprintk((KERN_INFO MYNAM ": %s: Sending IOCInit (req @ %p)\n", ioc->name, &ioc_init));
r = HandShakeReqAndReply(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
- sizeof(MPIDefaultReply_t), (u16*)&init_reply);
+ sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10);
if (r != 0)
return r;
ioc->name, portnum, &port_enable));
i = HandShakeReqAndReply(ioc, req_sz, (u32*)&port_enable,
- reply_sz, (u16*)&reply_buf);
+ reply_sz, (u16*)&reply_buf, 65);
if (i != 0)
return i;
/*
* KickStart - Perform hard reset of MPT adapter.
* @ioc: Pointer to MPT_ADAPTER structure
+ * @force: Force hard reset
*
* This routine places MPT adapter in diagnostic mode via the
* WriteSequence register, and then performs a hard reset of adapter
* via the Diagnostic register.
*
- * Returns 0 for success, non-zero for failure.
+ * Returns 0 for soft reset success, 1 for hard reset success,
+ * else a negative value for failure.
*/
static int
-KickStart(MPT_ADAPTER *ioc)
+KickStart(MPT_ADAPTER *ioc, int force)
{
- int r;
+ int hard_reset_done = 0;
u32 ioc_state;
int cnt = 0;
dprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
- if (ioc->chip_type == FC909) {
- r = mpt_fc9x9_reset(ioc);
+ hard_reset_done = mpt_fc9x9_reset(ioc, force);
+#if 0
+ if (ioc->chip_type == FC909 || ioc->chip-type == FC919) {
+ hard_reset_done = mpt_fc9x9_reset(ioc, force);
} else if (ioc->chip_type == FC929) {
unsigned long delta;
dprintk((KERN_INFO MYNAM ": %s: 929 KickStart, last=%ld, delta = %ld\n",
ioc->name, ioc->last_kickstart, delta));
if ((ioc->sod_reset == 0) || (delta >= 10*HZ))
- r = mpt_fc9x9_reset(ioc);
+ hard_reset_done = mpt_fc9x9_reset(ioc, ignore);
else {
dprintk((KERN_INFO MYNAM ": %s: Skipping KickStart (delta=%ld)!\n",
ioc->name, delta));
return 0;
}
- /* TODO! Add FC919!
- } else if (ioc->chip_type == FC919) {
- */
/* TODO! Add C1030!
} else if (ioc->chip_type == C1030) {
*/
ioc->name, ioc->chip_type);
return -5;
}
+#endif
- if (r != 0)
- return -r;
+ if (hard_reset_done < 0)
+ return hard_reset_done;
dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset successful\n",
ioc->name));
if ((ioc_state = GetIocState(ioc, 1)) == MPI_IOC_STATE_READY) {
dprintk((KERN_INFO MYNAM ": %s: KickStart successful! (cnt=%d)\n",
ioc->name, cnt));
- return 0;
+ return hard_reset_done;
}
/* udelay(10000) ? */
current->state = TASK_INTERRUPTIBLE;
* Returns 0 for success, non-zero for failure.
*/
static int
-mpt_fc9x9_reset(MPT_ADAPTER *ioc)
+mpt_fc9x9_reset(MPT_ADAPTER *ioc, int ignore)
{
- u32 diagval;
+ u32 diag0val;
+ int hard_reset_done = 0;
/* Use "Diagnostic reset" method! (only thing available!) */
- /*
- * Extra read to handle 909 B.0 chip problem with reset
- * logic not finishing the RAM access before hard reset hits.
- * (? comment taken from NT SYMMPI source)
- */
- (void) CHIPREG_READ32(&ioc->chip->Fubar);
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+ u32 diag1val = 0;
+ if (ioc->alt_ioc)
+ diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ dprintk((KERN_INFO MYNAM ": %s: DBG1: diag0=%08x, diag1=%08x\n",
+ ioc->name, diag0val, diag1val));
+}
+#endif
+ if (diag0val & MPI_DIAG_DRWE) {
+ dprintk((KERN_INFO MYNAM ": %s: DiagWriteEn bit already set\n",
+ ioc->name));
+ } else {
+ /* Write magic sequence to WriteSequence register */
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#1]\n",
+ ioc->name));
+ }
- /*
- * Write magic sequence to WriteSequence register.
- * But, send 0x0F first to insure a reset to the beginning of the sequence.
- */
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_KEY_VALUE_MASK);
-
- /* Now write magic sequence */
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
- CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
- dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence\n",
- ioc->name));
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+ u32 diag1val = 0;
+ if (ioc->alt_ioc)
+ diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ dprintk((KERN_INFO MYNAM ": %s: DbG2: diag0=%08x, diag1=%08x\n",
+ ioc->name, diag0val, diag1val));
+}
+#endif
+ if (!ignore && (diag0val & MPI_DIAG_RESET_HISTORY)) {
+ dprintk((KERN_INFO MYNAM ": %s: Skipping due to ResetHistory bit set!\n",
+ ioc->name));
+ } else {
+ /*
+ * Now hit the reset bit in the Diagnostic register
+ * (THE BIG HAMMER!)
+ */
+ CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+ hard_reset_done = 1;
+ dprintk((KERN_INFO MYNAM ": %s: Diagnostic reset performed\n",
+ ioc->name));
- /* Now hit the reset bit in the Diagnostic register */
- CHIPREG_WRITE32(&ioc->chip->Diagnostic, MPI_DIAG_RESET_ADAPTER);
+ /* want udelay(100) */
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(1);
- udelay(100);
+ /* Write magic sequence to WriteSequence register */
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
+ CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
+ dprintk((KERN_INFO MYNAM ": %s: Wrote magic DiagWriteEn sequence [spot#2]\n",
+ ioc->name));
+ }
- if ((diagval = CHIPREG_READ32(&ioc->chip->Diagnostic)) &
- (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_DISABLE_ARM)) {
- printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED!\n",
+ /* Clear RESET_HISTORY bit! */
+ CHIPREG_WRITE32(&ioc->chip->Diagnostic, 0x0);
+
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+ u32 diag1val = 0;
+ if (ioc->alt_ioc)
+ diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ dprintk((KERN_INFO MYNAM ": %s: DbG3: diag0=%08x, diag1=%08x\n",
+ ioc->name, diag0val, diag1val));
+}
+#endif
+ if (diag0val & MPI_DIAG_RESET_HISTORY) {
+ printk(KERN_WARNING MYNAM ": %s: WARNING - ResetHistory bit failed to clear!\n",
ioc->name);
- return -9;
}
- /* TODO!
- * Cleanup all event stuff for this IOC;
- * re-issue EventNotification request if needed.
+ diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+#ifdef MPT_DEBUG
+{
+ u32 diag1val = 0;
+ if (ioc->alt_ioc)
+ diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
+ dprintk((KERN_INFO MYNAM ": %s: DbG4: diag0=%08x, diag1=%08x\n",
+ ioc->name, diag0val, diag1val));
+}
+#endif
+ if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
+ printk(KERN_ERR MYNAM ": %s: ERROR - Diagnostic reset FAILED! (%02xh)\n",
+ ioc->name, diag0val);
+ return -3;
+ }
+
+ /*
+ * Reset flag that says we've enabled event notification
*/
- if (ioc->factsN.Function)
- ioc->factsN.EventState = 0;
+ ioc->facts.EventState = 0;
/* NEW! 20010220 -sralston
* Try to avoid redundant resets of the 929.
ioc->alt_ioc->last_kickstart = ioc->last_kickstart;
}
- return 0;
+ return hard_reset_done;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
{
int r;
- printk(KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
- ioc->name, reset_type);
+ dprintk((KERN_WARNING MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
+ ioc->name, reset_type));
CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
- if ((r = WaitForDoorbellAck(ioc)) < 0)
+ if ((r = WaitForDoorbellAck(ioc, 2)) < 0)
return r;
/* TODO!
* Cleanup all event stuff for this IOC; re-issue EventNotification
* request if needed.
*/
- if (ioc->factsN.Function)
- ioc->factsN.EventState = 0;
+ if (ioc->facts.Function)
+ ioc->facts.EventState = 0;
return 0;
}
* @req: Pointer to MPT request frame
* @replyBytes: Expected size of the reply in bytes
* @u16reply: Pointer to area where reply should be written
+ * @maxwait: Max wait time for a reply (in seconds)
*
* NOTES: It is the callers responsibility to byte-swap fields in the
* request which are greater than 1 byte in size. It is also the
* Returns 0 for success, non-zero for failure.
*/
static int
-HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply)
+HandShakeReqAndReply(MPT_ADAPTER *ioc, int reqBytes, u32 *req, int replyBytes, u16 *u16reply, int maxwait)
{
MPIDefaultReply_t *mptReply;
int failcnt = 0;
/*
* Wait for IOC's doorbell handshake int
*/
- if ((t = WaitForDoorbellInt(ioc)) < 0)
+ if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
failcnt++;
dhsprintk((KERN_INFO MYNAM ": %s: HandShake request start, WaitCnt=%d%s\n",
* our handshake request.
*/
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
- if (!failcnt && (t = WaitForDoorbellAck(ioc)) < 0)
+ if (!failcnt && (t = WaitForDoorbellAck(ioc, 2)) < 0)
failcnt++;
if (!failcnt) {
(req_as_bytes[(i*4) + 3] << 24));
CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
- if ((t = WaitForDoorbellAck(ioc)) < 0)
+ if ((t = WaitForDoorbellAck(ioc, 2)) < 0)
failcnt++;
}
/*
* Wait for completion of doorbell handshake reply from the IOC
*/
- if (!failcnt && (t = WaitForDoorbellReply(ioc)) < 0)
+ if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait)) < 0)
failcnt++;
/*
* WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
* in it's IntStatus register.
* @ioc: Pointer to MPT_ADAPTER structure
+ * @howlong: How long to wait (in seconds)
*
- * This routine waits (up to ~30 seconds max) for IOC doorbell
+ * This routine waits (up to ~2 seconds max) for IOC doorbell
* handshake ACKnowledge.
*
* Returns a negative value on failure, else wait loop count.
*/
static int
-WaitForDoorbellAck(MPT_ADAPTER *ioc)
+WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong)
{
- int cntdn = HZ * 30; /* ~30 seconds */
+ int cntdn = HZ * howlong;
int count = 0;
u32 intstat;
* WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
* in it's IntStatus register.
* @ioc: Pointer to MPT_ADAPTER structure
+ * @howlong: How long to wait (in seconds)
*
- * This routine waits (up to ~30 seconds max) for IOC doorbell interrupt.
+ * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
*
* Returns a negative value on failure, else wait loop count.
*/
static int
-WaitForDoorbellInt(MPT_ADAPTER *ioc)
+WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong)
{
- int cntdn = HZ * 30; /* ~30 seconds */
+ int cntdn = HZ * howlong;
int count = 0;
u32 intstat;
/*
* WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
* @ioc: Pointer to MPT_ADAPTER structure
+ * @howlong: How long to wait (in seconds)
*
* This routine polls the IOC for a handshake reply, 16 bits at a time.
* Reply is cached to IOC private area large enough to hold a maximum
* Returns a negative value on failure, else size of reply in WORDS.
*/
static int
-WaitForDoorbellReply(MPT_ADAPTER *ioc)
+WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong)
{
int u16cnt = 0;
int failcnt = 0;
/*
* Get first two u16's so we can look at IOC's intended reply MsgLength
*/
- for (u16cnt=0; !failcnt && u16cnt < 2; u16cnt++) {
- if ((t = WaitForDoorbellInt(ioc)) < 0)
- failcnt++;
- hs_reply[u16cnt] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ u16cnt=0;
+ if ((t = WaitForDoorbellInt(ioc, howlong)) < 0) {
+ failcnt++;
+ } else {
+ hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
+ failcnt++;
+ else {
+ hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
+ CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
+ }
}
dhsprintk((KERN_INFO MYNAM ": %s: First handshake reply word=%08x%s\n",
* reply 16 bits at a time.
*/
for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
- if ((t = WaitForDoorbellInt(ioc)) < 0)
+ if ((t = WaitForDoorbellInt(ioc, 2)) < 0)
failcnt++;
hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
/* don't overflow our IOC hs_reply[] buffer! */
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
}
- if (!failcnt && (t = WaitForDoorbellInt(ioc)) < 0)
+ if (!failcnt && (t = WaitForDoorbellInt(ioc, 2)) < 0)
failcnt++;
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
ioc->name));
i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
- reply_sz, (u16*)&config_reply);
+ reply_sz, (u16*)&config_reply, 3);
pci_unmap_single(ioc->pcidev, page0_dma, data_sz, PCI_DMA_FROMDEVICE);
if (i != 0)
return i;
ioc->name));
i = HandShakeReqAndReply(ioc, req_sz, (u32*)&config_req,
- reply_sz, (u16*)&config_reply);
+ reply_sz, (u16*)&config_reply, 3);
pci_unmap_single(ioc->pcidev, page1_dma, data_sz, PCI_DMA_FROMDEVICE);
if (i != 0)
return i;
return len; \
}
-
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
{
MPT_ADAPTER *ioc;
+ if (!procmpt_root_dir)
+ return 0;
+
/*
* BEWARE: If/when MPT_PROCFS_MPTBASEDIR changes from "mpt"
* (single level) to multi level (e.g. "driver/message/fusion")
if (atomic_read((atomic_t *)&procmpt_root_dir->count) == 0) {
remove_proc_entry(MPT_PROCFS_MPTBASEDIR, 0);
+ procmpt_root_dir = NULL;
return 0;
}
// Too verbose!
// mpt_print_ioc_facts(ioc, out, &more, 0);
- mpt_print_ioc_summary(ioc, out, &more, 0);
+ mpt_print_ioc_summary(ioc, out, &more, 0, 1);
out += more;
if ((out-page) >= count) {
static void
mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
{
- if ((ioc->facts0.FWVersion & 0xF000) == 0xE000)
+ if ((ioc->facts.FWVersion & 0xF000) == 0xE000)
sprintf(buf, " (Exp %02d%02d)",
- (ioc->facts0.FWVersion & 0x0F00) >> 8, /* Month */
- ioc->facts0.FWVersion & 0x001F); /* Day */
+ (ioc->facts.FWVersion & 0x0F00) >> 8, /* Month */
+ ioc->facts.FWVersion & 0x001F); /* Day */
else
buf[0] ='\0';
/* insider hack! */
- if (ioc->facts0.FWVersion & 0x0080) {
+ if (ioc->facts.FWVersion & 0x0080) {
strcat(buf, " [MDBG]");
}
}
* @buffer: Pointer to buffer where IOC summary info should be written
* @size: Pointer to number of bytes we wrote (set by this routine)
* @len: Offset at which to start writing in buffer
+ * @showlan: Display LAN stuff?
*
* This routine writes (english readable) ASCII text, which represents
* a summary of IOC information, to a buffer.
*/
void
-mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len)
+mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
{
char expVer[32];
int y;
-
mpt_get_fw_exp_ver(expVer, ioc);
/*
ioc->name,
ioc->prod_name,
MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
- ioc->facts0.FWVersion,
+ ioc->facts.FWVersion,
expVer,
- ioc->facts0.NumberOfPorts,
+ ioc->facts.NumberOfPorts,
ioc->req_depth);
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+ if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
a[5], a[4], a[3], a[2], a[1], a[0]);
}
+ if (ioc->pci_irq < 100)
+ y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
+
if (!ioc->active)
y += sprintf(buffer+len+y, " (disabled)");
char iocName[16];
int sz;
int y;
-
+ int p;
mpt_get_fw_exp_ver(expVer, ioc);
strcpy(iocName, ioc->name);
y = sprintf(buffer+len, "%s:\n", iocName);
- y += sprintf(buffer+len+y, " ProductID = 0x%04x\n", ioc->facts0.ProductID);
- y += sprintf(buffer+len+y, " PortNumber = %d (of %d)\n",
- ioc->pfacts0.PortNumber+1,
- ioc->facts0.NumberOfPorts);
- if (ioc->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
- u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
- y += sprintf(buffer+len+y, " LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
- a[5], a[4], a[3], a[2], a[1], a[0]);
+ y += sprintf(buffer+len+y, " ProductID = 0x%04x\n", ioc->facts.ProductID);
+ for (p=0; p < ioc->facts.NumberOfPorts; p++) {
+ y += sprintf(buffer+len+y, " PortNumber = %d (of %d)\n",
+ p+1,
+ ioc->facts.NumberOfPorts);
+ if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+ u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
+ y += sprintf(buffer+len+y, " LanAddr = 0x%02x:%02x:%02x:%02x:%02x:%02x\n",
+ a[5], a[4], a[3], a[2], a[1], a[0]);
+ }
}
- y += sprintf(buffer+len+y, " FWVersion = 0x%04x%s\n", ioc->facts0.FWVersion, expVer);
- y += sprintf(buffer+len+y, " MsgVersion = 0x%04x\n", ioc->facts0.MsgVersion);
- y += sprintf(buffer+len+y, " WhoInit = 0x%02x\n", ioc->facts0.WhoInit);
- y += sprintf(buffer+len+y, " EventState = 0x%02x\n", ioc->facts0.EventState);
+ y += sprintf(buffer+len+y, " FWVersion = 0x%04x%s\n", ioc->facts.FWVersion, expVer);
+ y += sprintf(buffer+len+y, " MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
+ y += sprintf(buffer+len+y, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
+ y += sprintf(buffer+len+y, " EventState = 0x%02x\n", ioc->facts.EventState);
y += sprintf(buffer+len+y, " CurrentHostMfaHighAddr = 0x%08x\n",
- ioc->facts0.CurrentHostMfaHighAddr);
+ ioc->facts.CurrentHostMfaHighAddr);
y += sprintf(buffer+len+y, " CurrentSenseBufferHighAddr = 0x%08x\n",
- ioc->facts0.CurrentSenseBufferHighAddr);
- y += sprintf(buffer+len+y, " MaxChainDepth = 0x%02x frames\n", ioc->facts0.MaxChainDepth);
- y += sprintf(buffer+len+y, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts0.BlockSize);
+ ioc->facts.CurrentSenseBufferHighAddr);
+ y += sprintf(buffer+len+y, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
+ y += sprintf(buffer+len+y, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
y += sprintf(buffer+len+y, " RequestFrames @ 0x%p (Dma @ 0x%08x)\n",
ioc->req_alloc, ioc->req_alloc_dma);
y += sprintf(buffer+len+y, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
y += sprintf(buffer+len+y, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
- 4*ioc->facts0.RequestFrameSize,
- ioc->facts0.GlobalCredits);
+ 4*ioc->facts.RequestFrameSize,
+ ioc->facts.GlobalCredits);
y += sprintf(buffer+len+y, " ReplyFrames @ 0x%p (Dma @ 0x%08x)\n",
ioc->reply_alloc, ioc->reply_alloc_dma);
y += sprintf(buffer+len+y, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
y += sprintf(buffer+len+y, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
- ioc->factsN.CurReplyFrameSize,
- ioc->facts0.ReplyQueueDepth);
+ ioc->facts.CurReplyFrameSize,
+ ioc->facts.ReplyQueueDepth);
*size = y;
}
/* CHECKME! What if evState unexpectedly says OFF (0)? */
/* Update EventState field in cached IocFacts */
- if (ioc->factsN.Function) {
- ioc->factsN.EventState = evState;
+ if (ioc->facts.Function) {
+ ioc->facts.EventState = evState;
}
}
break;
case MPI_IOCLOGINFO_FC_LINK_LINK_NOT_ESTABLISHED:
desc = "Not synchronized to signal or still negotiating (possible cable problem)";
break;
+ case MPI_IOCLOGINFO_FC_LINK_CRC_ERROR:
+ desc = "CRC check detected error on received frame";
+ break;
}
printk(KERN_INFO MYNAM ": %s: LogInfo(0x%08x): SubCl={%s}",
EXPORT_SYMBOL(mpt_deregister);
EXPORT_SYMBOL(mpt_event_register);
EXPORT_SYMBOL(mpt_event_deregister);
+EXPORT_SYMBOL(mpt_reset_register);
+EXPORT_SYMBOL(mpt_reset_deregister);
EXPORT_SYMBOL(mpt_get_msg_frame);
EXPORT_SYMBOL(mpt_put_msg_frame);
EXPORT_SYMBOL(mpt_free_msg_frame);
MptCallbacks[i] = NULL;
MptDriverClass[i] = MPTUNKNOWN_DRIVER;
MptEvHandlers[i] = NULL;
+ MptResetHandlers[i] = NULL;
}
/* NEW! 20010120 -sralston
static void fusion_exit(void)
{
MPT_ADAPTER *this;
- int i;
dprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
- /*
- * Paranoia; disable interrupts on all MPT adapters.
- */
- for (i=0; i<MPT_MAX_ADAPTERS; i++) {
- if ((this = mpt_adapters[i]) != NULL) {
- /* Disable adapter interrupts! */
- CHIPREG_WRITE32(&this->chip->IntMask, 0xFFFFFFFF);
- /* Clear any lingering interrupt */
- CHIPREG_WRITE32(&this->chip->IntStatus, 0);
- this->active = 0;
- }
- }
-
/* Whups? 20010120 -sralston
* Moved this *above* removal of all MptAdapters!
*/
* Originally By: Steven J. Ralston
* (mailto:Steve.Ralston@lsil.com)
*
- * $Id: mptbase.h,v 1.38 2001/03/22 10:54:30 sralston Exp $
+ * $Id: mptbase.h,v 1.46.2.2.2.1 2001/08/24 20:07:05 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
#include "lsi/mpi_init.h" /* SCSI Host (initiator) protocol support */
#include "lsi/mpi_lan.h" /* LAN over FC protocol support */
-//#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
-//#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
+#include "lsi/mpi_fc.h" /* Fibre Channel (lowlevel) support */
+#include "lsi/mpi_targ.h" /* SCSI/FCP Target protcol support */
#include "lsi/fc_log.h"
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
#define COPYRIGHT "Copyright (c) 1999-2001 " MODULEAUTHOR
#endif
-#define MPT_LINUX_VERSION_COMMON "1.00.11"
-#define MPT_LINUX_VERSION_EXP "0.09.66-EXP"
-#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-1.00.11"
+#define MPT_LINUX_VERSION_COMMON "1.02.01"
+#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-1.02.01"
#define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \
*/
#define MPT_MAX_ADAPTERS 16
#define MPT_MAX_PROTOCOL_DRIVERS 8
+#define MPT_MAX_FC_DEVICES 255
#define MPT_MISCDEV_BASENAME "mptctl"
#define MPT_MISCDEV_PATHNAME "/dev/" MPT_MISCDEV_BASENAME
struct _MPT_ADAPTER *back;
int id; /* Unique adapter id {0,1,2,...} */
int pci_irq;
- IOCFactsReply_t facts0;
- IOCFactsReply_t factsN;
char name[32]; /* "iocN" */
char *prod_name; /* "LSIFC9x9" */
u32 mem_phys; /* == f4020000 (mmap) */
int active;
int sod_reset;
unsigned long last_kickstart;
- PortFactsReply_t pfacts0;
- PortFactsReply_t pfactsN;
- LANPage0_t lan_cnfg_page0;
- LANPage1_t lan_cnfg_page1;
u8 *reply_alloc; /* Reply frames alloc ptr */
dma_addr_t reply_alloc_dma;
MPT_FRAME_HDR *reply_frames; /* Reply frames - rounded up! */
dma_addr_t req_frames_dma;
int req_depth;
int req_sz;
- spinlock_t FreeQlock;
MPT_Q_TRACKER FreeQ;
+ spinlock_t FreeQlock;
/* Pool of SCSI sense buffers for commands coming from
* the SCSI mid-layer. We have one 256 byte sense buffer
* for each REQ entry.
*/
u8 *sense_buf_pool;
dma_addr_t sense_buf_pool_dma;
- int hs_reply_idx;
- u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
- u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
struct pci_dev *pcidev;
- struct _MPT_ADAPTER *alt_ioc;
/* atomic_t userCnt; */
u8 *memmap;
int mtrr_reg;
struct Scsi_Host *sh;
struct proc_dir_entry *ioc_dentry;
+ struct _MPT_ADAPTER *alt_ioc;
+ int hs_reply_idx;
+ u32 hs_req[MPT_MAX_FRAME_SIZE/sizeof(u32)];
+ u16 hs_reply[MPT_MAX_FRAME_SIZE/sizeof(u16)];
+ IOCFactsReply_t facts;
+ PortFactsReply_t pfacts[2];
+ LANPage0_t lan_cnfg_page0;
+ LANPage1_t lan_cnfg_page1;
+ u8 FirstWhoInit;
+ u8 pad1[3];
} MPT_ADAPTER;
* 0 = not Ok ...
*/
typedef int (*MPT_CALLBACK)(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
+
typedef int (*MPT_EVHANDLER)(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply);
+typedef int (*MPT_RESETHANDLER)(MPT_ADAPTER *ioc, int reset_phase);
+/* reset_phase defs */
+#define MPT_IOC_PRE_RESET 0
+#define MPT_IOC_POST_RESET 1
/*
- * Fibre Channel (SCSI) target device...
+ * Invent MPT host event (super-set of MPI Events)
+ * Fitted to 1030's 64-byte [max] request frame size
*/
-typedef struct _FC_TARGET {
- struct _FC_TARGET *forw;
- struct _FC_TARGET *back;
- int bus_id;
- int target_id;
- int lun_exists[32];
- u8 inquiry_data[36];
- u8 last_sense[256];
-} FC_TARGET;
-
-typedef struct _FCDEV_TRACKER {
- FC_TARGET *head;
- FC_TARGET *tail;
-} FCDEV_TRACKER;
+typedef struct _MPT_HOST_EVENT {
+ EventNotificationReply_t MpiEvent; /* 8 32-bit words! */
+ u32 pad[6];
+ void *next;
+} MPT_HOST_EVENT;
+#define MPT_HOSTEVENT_IOC_BRINGUP 0x91
+#define MPT_HOSTEVENT_IOC_RECOVER 0x92
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
extern void mpt_deregister(int cb_idx);
extern int mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc);
extern void mpt_event_deregister(int cb_idx);
+extern int mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func);
+extern void mpt_reset_deregister(int cb_idx);
extern int mpt_register_ascqops_strings(/*ASCQ_Table_t*/void *ascqTable, int ascqtbl_sz, const char **opsTable);
extern void mpt_deregister_ascqops_strings(void);
extern MPT_FRAME_HDR *mpt_get_msg_frame(int handle, int iocid);
extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
extern MPT_ADAPTER *mpt_adapter_find_first(void);
extern MPT_ADAPTER *mpt_adapter_find_next(MPT_ADAPTER *prev);
-extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len);
+extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
extern void mpt_print_ioc_facts(MPT_ADAPTER *ioc, char *buf, int *size, int len);
/*
* Originally By: Steven J. Ralston, Noah Romer
* (mailto:Steve.Ralston@lsil.com)
*
- * $Id: mptctl.c,v 1.23 2001/03/21 19:42:31 sralston Exp $
+ * $Id: mptctl.c,v 1.25.4.1 2001/08/24 20:07:06 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
return 1;
}
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/*
+ * struct file_operations functionality.
+ * Members:
+ * llseek, write, read, ioctl, open, release
+ */
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
+static loff_t
+mptctl_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+#define no_llseek mptctl_llseek
+#endif
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static ssize_t
mptctl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
SGESimple32_t *sgl;
SGESimple32_t *sgOut, *sgIn;
dma_addr_t sgl_dma;
- struct buflist *buflist;
- struct buflist *bl;
+ struct buflist *buflist = NULL;
+ struct buflist *bl = NULL;
int numfrags = 0;
int maxfrags;
int n = 0;
sgIn = sgl;
bl = buflist;
for (i=0; i < numfrags; i++) {
- nib = (sgIn->FlagsLength & 0xF0000000) >> 28;
+ nib = (le32_to_cpu(sgIn->FlagsLength) & 0xF0000000) >> 28;
/* skip ignore/chain. */
if (nib == 0 || nib == 3) {
;
u8 *kptr;
int len;
- if ((sglbuf[i].FlagsLength >> 24) == 0x30)
+ if ((le32_to_cpu(sglbuf[i].FlagsLength) >> 24) == 0x30)
continue;
dma_addr = le32_to_cpu(sglbuf[i].Address);
int dir;
int n = 0;
- if (sg->FlagsLength & 0x04000000)
+ if (le32_to_cpu(sg->FlagsLength) & 0x04000000)
dir = PCI_DMA_TODEVICE;
else
dir = PCI_DMA_FROMDEVICE;
- nib = (sg->FlagsLength & 0xF0000000) >> 28;
+ nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
while (! (nib & 0x4)) { /* eob */
/* skip ignore/chain. */
if (nib == 0 || nib == 3) {
}
sg++;
bl++;
- nib = (sg->FlagsLength & 0xF0000000) >> 28;
+ nib = (le32_to_cpu(sg->FlagsLength) & 0xF0000000) >> 28;
}
/* we're at eob! */
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-static struct file_operations mptctl_fops = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,51)
- owner: THIS_MODULE,
+#define owner_THIS_MODULE owner: THIS_MODULE,
+#else
+#define owner_THIS_MODULE
#endif
+
+static struct file_operations mptctl_fops = {
+ owner_THIS_MODULE
llseek: no_llseek,
read: mptctl_read,
write: mptctl_write,
return ret;
}
-#if 0 /* { */
-static int
-sparc32_mptfwxfer_ioctl(unsigned int fd, unsigned int cmd,
- unsigned long arg, struct file *filp)
-{
- struct mpt_fw_xfer32 kfw32;
- struct mpt_fw_xfer kfw;
- mm_segment_t old_fs;
- int ret;
-
- dprintk((KERN_INFO MYNAM "::sparc32_mptfwxfer_ioctl() called\n"));
-
- if (copy_from_user(&kfw32, (char *)arg, sizeof(kfw32)))
- return -EFAULT;
-
- /* Verify intended MPT adapter */
- iocnumX = kfw32.iocnum & 0xFF;
- if (((iocnum = mpt_verify_adapter(iocnumX, &iocp)) < 0) ||
- (iocp == NULL)) {
- printk(KERN_ERR MYNAM "::sparc32_mptfwxfer_ioctl @%d - ioc%d not found!\n",
- __LINE__, iocnumX);
- return -ENODEV;
- }
-
- if ((ret = mptctl_syscall_down(iocp, nonblock)) != 0)
- return ret;
-
- kfw.iocnum = iocnum;
- kfw.fwlen = kfw32.fwlen;
- kfw.bufp = (void *)(unsigned long)kfw32.bufp;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_ioctl(fd, MPTFWDOWNLOAD, (unsigned long)&kfw);
- set_fs(old_fs);
-
- up(&mptctl_syscall_sem_ioc[iocp->id]);
-
- return ret;
-}
-#endif /* #if 0 } */
-
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
if (++where && err) goto out_fail;
err = register_ioctl32_conversion(MPTRWPERF_RESET, NULL);
if (++where && err) goto out_fail;
- err = register_ioctl32_conversion(MPTFWDOWNLOAD32,
- sparc32_mptfwxfer_ioctl);
+ err = register_ioctl32_conversion(MPTFWDOWNLOAD32, sparc32_mptfwxfer_ioctl);
if (++where && err) goto out_fail;
#endif /*} linux >= 2.3.x */
#endif /*} sparc */
* Install our handler
*/
++where;
- if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) < 0) {
+ if ((mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER)) <= 0) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
void mptctl_exit(void)
{
+
+#if defined(__sparc__) && defined(__sparc_v9__) /*{*/
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) /*{*/
+ unregister_ioctl32_conversion(MPTRWPERF);
+ unregister_ioctl32_conversion(MPTRWPERF_CHK);
+ unregister_ioctl32_conversion(MPTRWPERF_RESET);
+ unregister_ioctl32_conversion(MPTFWDOWNLOAD32);
+#endif /*} linux >= 2.3.x */
+#endif /*} sparc */
+
misc_deregister(&mptctl_miscdev);
printk(KERN_INFO MYNAM ": /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
* Copyright (c) 2000-2001 LSI Logic Corporation
* Originally By: Noah Romer
*
- * $Id: mptlan.c,v 1.25 2001/03/02 22:12:04 sralston Exp $
+ * $Id: mptlan.c,v 1.32.2.2 2001/07/12 19:43:33 nromer Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Fusion MPT LAN private structures
*/
+struct NAA_Hosed {
+ u16 NAA;
+ u8 ieee[FC_ALEN];
+ struct NAA_Hosed *next;
+};
+
struct BufferControl {
struct sk_buff *skb;
dma_addr_t dma;
static int mpt_lan_send_turbo(struct net_device *dev, u32 tmsg);
static int mpt_lan_send_reply(struct net_device *dev,
LANSendReply_t *pSendRep);
+static int mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
static int mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
static unsigned short mpt_lan_type_trans(struct sk_buff *skb,
struct net_device *dev);
static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
+static struct NAA_Hosed *mpt_bad_naa = NULL;
+rwlock_t bad_naa_lock;
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
* Fusion MPT LAN external data
return FreeReqFrame;
}
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+ struct net_device *dev = mpt_landev[ioc->id];
+ struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
+
+ dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
+ reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+ if (priv->mpt_rxfidx == NULL)
+ return (1);
+
+ if (reset_phase == MPT_IOC_PRE_RESET) {
+ int i;
+ unsigned long flags;
+
+ netif_stop_queue(dev);
+
+ atomic_set(&priv->buckets_out, 0);
+
+ /* Reset Rx Free Tail index and re-populate the queue. */
+ spin_lock_irqsave(&priv->rxfidx_lock, flags);
+ priv->mpt_rxfidx_tail = -1;
+ for (i = 0; i < priv->max_buckets_out; i++)
+ priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
+ spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
+ } else {
+ mpt_lan_post_receive_buckets(dev);
+ netif_wake_queue(dev);
+ }
+
+ return 1;
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int
mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
int i;
- mpt_lan_reset(dev);
+ if (mpt_lan_reset(dev) != 0) {
+ MPT_ADAPTER *mpt_dev = priv->mpt_dev;
+
+ printk (KERN_WARNING MYNAM "/lan_open: lan_reset failed.");
+
+ if (mpt_dev->active)
+ printk ("The ioc is active. Perhaps it needs to be"
+ " reset?\n");
+ else
+ printk ("The ioc in inactive, most likely in the "
+ "process of being reset. Please try again in "
+ "a moment.\n");
+ }
priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL);
if (priv->mpt_txfidx == NULL)
IOC_AND_NETDEV_NAMES_s_s(dev));
if (mpt_event_register(LanCtx, mpt_lan_event_process) != 0) {
- /* FIXME! */
+ printk (KERN_WARNING MYNAM "/lo: Unable to register for Event"
+ " Notifications. This is a bad thing! We're not going "
+ "to go ahead, but I'd be leery of system stability at "
+ "this point.\n");
}
netif_start_queue(dev);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/* Send a LanReset message to the FW. This should result in the FW returning
+ any buckets it still has. */
static int
mpt_lan_reset(struct net_device *dev)
{
dma_addr_t dma;
unsigned long flags;
int ctx;
+ struct NAA_Hosed *nh;
+ u16 cur_naa = 0x1000;
dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
__FUNCTION__, skb));
priv->SendCtl[ctx].len = skb->len;
/* Message Header */
+ pSendReq->Reserved = 0;
pSendReq->Function = MPI_FUNCTION_LAN_SEND;
pSendReq->ChainOffset = 0;
+ pSendReq->Reserved2 = 0;
pSendReq->MsgFlags = 0;
pSendReq->PortNumber = priv->pnum;
// IOC_AND_NETDEV_NAMES_s_s(dev),
// ctx, skb, skb->data));
- pTrans->TransactionDetails[0] = cpu_to_le32((0x1000 << 16) |
+ /* Munge the NAA for Tx packets to QLogic boards, which don't follow
+ RFC 2625. The longer I look at this, the more my opinion of Qlogic
+ drops. */
+ read_lock_irq(&bad_naa_lock);
+ for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) {
+ if ((nh->ieee[0] == skb->mac.raw[0]) &&
+ (nh->ieee[1] == skb->mac.raw[1]) &&
+ (nh->ieee[2] == skb->mac.raw[2]) &&
+ (nh->ieee[3] == skb->mac.raw[3]) &&
+ (nh->ieee[4] == skb->mac.raw[4]) &&
+ (nh->ieee[5] == skb->mac.raw[5])) {
+ cur_naa = nh->NAA;
+ dprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
+ "= %04x.\n", cur_naa));
+ break;
+ }
+ }
+ read_unlock_irq(&bad_naa_lock);
+
+ pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa << 16) |
(skb->mac.raw[0] << 8) |
(skb->mac.raw[1] << 0));
pTrans->TransactionDetails[1] = cpu_to_le32((skb->mac.raw[2] << 24) |
pSimple = (SGESimple64_t *) &pTrans->TransactionDetails[2];
+ /* If we ever decide to send more than one Simple SGE per LANSend, then
+ we will need to make sure that LAST_ELEMENT only gets set on the
+ last one. Otherwise, bad voodoo and evil funkiness will commence. */
pSimple->FlagsLength = cpu_to_le32(
- ((MPI_SGE_FLAGS_END_OF_BUFFER |
+ ((MPI_SGE_FLAGS_LAST_ELEMENT |
+ MPI_SGE_FLAGS_END_OF_BUFFER |
MPI_SGE_FLAGS_SIMPLE_ELEMENT |
+ MPI_SGE_FLAGS_SYSTEM_ADDRESS |
+ MPI_SGE_FLAGS_HOST_TO_IOC |
MPI_SGE_FLAGS_64_BIT_ADDRESSING |
MPI_SGE_FLAGS_END_OF_LIST) << MPI_SGE_FLAGS_SHIFT) |
skb->len);
priv->total_posted = 0;
priv->total_received = 0;
priv->max_buckets_out = max_buckets_out;
- if (mpt_dev->pfacts0.MaxLanBuckets < max_buckets_out)
- priv->max_buckets_out = mpt_dev->pfacts0.MaxLanBuckets;
+ if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
+ priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
dprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
__LINE__,
- mpt_dev->pfacts0.MaxLanBuckets,
+ mpt_dev->pfacts[0].MaxLanBuckets,
max_buckets_out,
priv->max_buckets_out));
show_mptmod_ver(LANAME, LANVER);
- if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) < 0) {
+ /* Init the global r/w lock for the bad_naa list. We want to do this
+ before any boards are initialized and may be used. */
+ rwlock_init(&bad_naa_lock);
+
+ if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
return -EBUSY;
}
dprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
+ if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
+ dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+ } else {
+ printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
+ "handler with mptbase! The world is at an end! "
+ "Everything is fading to black! Goodbye.\n");
+ return -EBUSY;
+ }
+
for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
mpt_landev[j] = NULL;
}
curadapter = mpt_adapter_find_first();
while (curadapter != NULL) {
- for (i = 0; i < curadapter->facts0.NumberOfPorts; i++) {
+ for (i = 0; i < curadapter->facts.NumberOfPorts; i++) {
printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
curadapter->name,
- curadapter->pfacts0.PortNumber,
- curadapter->pfacts0.ProtocolFlags,
- MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts0.ProtocolFlags));
+ curadapter->pfacts[i].PortNumber,
+ curadapter->pfacts[i].ProtocolFlags,
+ MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts[i].ProtocolFlags));
- if (curadapter->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
+ if (curadapter->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
dev = mpt_register_lan_device (curadapter, i);
if (dev != NULL) {
printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
} else {
printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
curadapter->name,
- curadapter->pfacts0.PortNumber);
+ curadapter->pfacts[i].PortNumber);
}
} else {
printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
{
int i;
+ mpt_reset_deregister(LanCtx);
+
for (i = 0; mpt_landev[i] != NULL; i++) {
struct net_device *dev = mpt_landev[i];
{
struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
struct fcllc *fcllc;
+ u16 source_naa = fch->stype, found = 0;
skb->mac.raw = skb->data;
skb_pull(skb, sizeof(struct mpt_lan_ohdr));
}
}
+ fcllc = (struct fcllc *)skb->data;
+
+ /* Workaround for QLogic not following RFC 2625 in regards to the NAA
+ value. */
+
+ if ((source_naa & 0xF000) == 0)
+ source_naa = swab16(source_naa);
+
+ if (fcllc->ethertype == htons(ETH_P_ARP))
+ dprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
+ "%04x.\n", source_naa));
+
+ if ((fcllc->ethertype == htons(ETH_P_ARP)) &&
+ ((source_naa >> 12) != MPT_LAN_NAA_RFC2625)){
+ struct NAA_Hosed *nh, *prevnh;
+ int i;
+
+ dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
+ "system with non-RFC 2625 NAA value (%04x).\n",
+ source_naa));
+
+ write_lock_irq(&bad_naa_lock);
+ for (prevnh = nh = mpt_bad_naa; nh != NULL;
+ prevnh=nh, nh=nh->next) {
+ if ((nh->ieee[0] == fch->saddr[0]) &&
+ (nh->ieee[1] == fch->saddr[1]) &&
+ (nh->ieee[2] == fch->saddr[2]) &&
+ (nh->ieee[3] == fch->saddr[3]) &&
+ (nh->ieee[4] == fch->saddr[4]) &&
+ (nh->ieee[5] == fch->saddr[5])) {
+ found = 1;
+ dprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
+ "q/Rep w/ bad NAA from system already"
+ " in DB.\n"));
+ break;
+ }
+ }
+
+ if ((!found) && (nh == NULL)) {
+
+ nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
+ dprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
+ " bad NAA from system not yet in DB.\n"));
+
+ if (nh != NULL) {
+ nh->next = NULL;
+ if (!mpt_bad_naa)
+ mpt_bad_naa = nh;
+ if (prevnh)
+ prevnh->next = nh;
+
+ nh->NAA = source_naa; /* Set the S_NAA value. */
+ for (i = 0; i < FC_ALEN; i++)
+ nh->ieee[i] = fch->saddr[i];
+ dprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
+ "%02x:%02x with non-compliant S_NAA value.\n",
+ fch->saddr[0], fch->saddr[1], fch->saddr[2],
+ fch->saddr[3], fch->saddr[4],fch->saddr[5]));
+ } else {
+ printk (KERN_ERR "mptlan/type_trans: Unable to"
+ " kmalloc a NAA_Hosed struct.\n");
+ }
+ } else if (!found) {
+ printk (KERN_ERR "mptlan/type_trans: found not"
+ " set, but nh isn't null. Evil "
+ "funkiness abounds.\n");
+ }
+ write_unlock_irq(&bad_naa_lock);
+ }
+
+
/* Strip the SNAP header from ARP packets since we don't
* pass them through to the 802.2/SNAP layers.
*/
- fcllc = (struct fcllc *)skb->data;
-
if (fcllc->dsap == EXTENDED_SAP &&
(fcllc->ethertype == htons(ETH_P_IP) ||
fcllc->ethertype == htons(ETH_P_ARP))) {
#define MPT_LAN_MAX_MTU 65280 /* RFC2625 */
#define MPT_LAN_MTU 16128 /* be nice to slab allocator */
+#define MPT_LAN_NAA_RFC2625 0x1
+#define MPT_LAN_NAA_QLOGIC 0x2
+
/* MPT LAN Reset and Suspend Resource Flags Defines */
#define MPT_LAN_RESOURCE_FLAG_RETURN_POSTED_BUCKETS 0x01
* Original author: Steven J. Ralston
* (mailto:Steve.Ralston@lsil.com)
*
- * $Id: mptscsih.c,v 1.24 2001/03/22 08:45:08 sralston Exp $
+ * $Id: mptscsih.c,v 1.29 2001/06/18 18:59:05 sralston Exp $
*/
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*
u8 *SgHunks;
dma_addr_t SgHunksDMA;
u32 qtag_tick;
- FCDEV_TRACKER TargetsQ;
} MPT_SCSI_HOST;
typedef struct _MPT_SCSI_DEV {
static void copy_sense_data(Scsi_Cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
static u32 SCPNT_TO_MSGCTX(Scsi_Cmnd *sc);
+static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
dprintk((KERN_INFO MYNAM ": *NEW* SCSI device (%d:%d:%d)!\n",
sc->device->id, sc->device->lun, sc->device->channel));
if ((sc->device->hostdata = kmalloc(sizeof(MPT_SCSI_DEV), GFP_ATOMIC)) == NULL) {
- printk(KERN_ERR MYNAM ": ERROR: kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
+ printk(KERN_ERR MYNAM ": ERROR - kmalloc(%d) FAILED!\n", (int)sizeof(MPT_SCSI_DEV));
} else {
memset(sc->device->hostdata, 0, sizeof(MPT_SCSI_DEV));
mpt_sdev = (MPT_SCSI_DEV *) sc->device->hostdata;
if (! BeenHereDoneThat++) {
show_mptmod_ver(my_NAME, my_VERSION);
- ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
- ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
+ if ((ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER)) <= 0) {
+ printk(KERN_ERR MYNAM ": Failed to register callback1 with MPT base driver\n");
+ return mpt_scsi_hosts;
+ }
+ if ((ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER)) <= 0) {
+ printk(KERN_ERR MYNAM ": Failed to register callback2 with MPT base driver\n");
+ return mpt_scsi_hosts;
+ }
#ifndef MPT_SCSI_USE_NEW_EH
Q_INIT(&mpt_scsih_taskQ, MPT_FRAME_HDR);
} else {
/* FIXME! */
}
+
+ if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
+ dprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
+ } else {
+ /* FIXME! */
+ }
}
dprintk((KERN_INFO MYNAM ": mpt_scsih_detect()\n"));
* Added sanity check on SCSI Initiator-mode enabled
* for this MPT adapter.
*/
- if (!(this->pfacts0.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
+ if (!(this->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
printk(KERN_ERR MYNAM ": Skipping %s because SCSI Initiator mode is NOT enabled!\n",
this->name);
this = mpt_adapter_find_next(this);
/* Yikes! This is important!
* Otherwise, by default, linux only scans target IDs 0-7!
+ *
+ * BUG FIX! 20010618 -sralston & pdelaney
+ * FC919 testing was encountering "duplicate" FC devices,
+ * as it turns out because the 919 was returning 512
+ * for PortFacts.MaxDevices, causing a wraparound effect
+ * in SCSI IO requests. So instead of using:
+ * sh->max_id = this->pfacts[0].MaxDevices - 1
+ * we'll use a definitive max here.
*/
- sh->max_id = this->pfacts0.MaxDevices - 1;
+ sh->max_id = MPT_MAX_FC_DEVICES;
- sh->this_id = this->pfacts0.PortSCSIID;
+ sh->this_id = this->pfacts[0].PortSCSIID;
restore_flags(flags);
#if 0
mptscsih_flush_pending();
#endif
+ mpt_reset_deregister(ScsiDoneCtx);
+ dprintk((KERN_INFO MYNAM ": Deregistered for IOC reset notifications\n"));
+
mpt_event_deregister(ScsiDoneCtx);
dprintk((KERN_INFO MYNAM ": Deregistered for IOC event notifications\n"));
h = (MPT_SCSI_HOST *)SChost->hostdata;
info_kbuf[0] = '\0';
- mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0);
+ mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
info_kbuf[size-1] = '\0';
return info_kbuf;
dprintk((KERN_INFO MYNAM ": Queue depth now %d.\n", max_qd));
}
- mb();
dmfprintk((KERN_INFO MYNAM ": Issued SCSI cmd (%p)\n", SCpnt));
return 0;
u32 *msg;
u32 ctx2abort;
int i;
+ unsigned long flags;
printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO (=%p)\n", SCpnt);
printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
* the controller, so it does not matter. -DaveM
*/
ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
- dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
- pScsiTm->TaskMsgContext = ctx2abort;
-
- wmb();
+ if (ctx2abort == -1) {
+ printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#2) for SCpnt=%p\n", SCpnt);
+ SCpnt->result = DID_SOFT_ERROR << 16;
+ spin_lock_irqsave(&io_request_lock, flags);
+ SCpnt->scsi_done(SCpnt);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+ } else {
+ dprintk((KERN_INFO MYNAM ":DbG: ctx2abort = %08x\n", ctx2abort));
+ pScsiTm->TaskMsgContext = ctx2abort;
-/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
- mpt_put_msg_frame(hd->ioc->id, mf);
-*/
-/* FIXME! Check return status! */
- (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
- wmb();
+ /* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
+ mpt_put_msg_frame(hd->ioc->id, mf);
+ */
+ if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+ sizeof(SCSITaskMgmt_t), msg))
+ != 0) {
+ printk(KERN_WARNING MYNAM
+ ": WARNING[2] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+ i, mf, SCpnt);
+ SCpnt->result = DID_SOFT_ERROR << 16;
+ spin_lock_irqsave(&io_request_lock, flags);
+ SCpnt->scsi_done(SCpnt);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+ }
+ }
- return SUCCESS;
+ //return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
+ * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
* @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
*
- * (linux Scsi_Host_Template.eh_bus_reset_handler routine)
+ * (linux Scsi_Host_Template.eh_dev_reset_handler routine)
*
* Returns SUCCESS or FAILED.
*/
int
-mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
+mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
{
MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm;
MPT_SCSI_HOST *hd;
u32 *msg;
int i;
+ unsigned long flags;
- printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
+ printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
}
pScsiTm = (SCSITaskMgmt_t *) mf;
- msg = (u32 *) mf;
+ msg = (u32*)mf;
pScsiTm->TargetID = SCpnt->target;
pScsiTm->Bus = hd->port;
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
pScsiTm->Reserved = 0;
- pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
+ pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
pScsiTm->Reserved1 = 0;
pScsiTm->MsgFlags = 0;
+ /* _TARGET_RESET goes to LUN 0 always! */
for (i = 0; i < 8; i++)
pScsiTm->LUN[i] = 0;
pScsiTm->TaskMsgContext = cpu_to_le32(0);
- wmb();
-
/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
mpt_put_msg_frame(hd->ioc->id, mf);
*/
/* FIXME! Check return status! */
- (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
-
- wmb();
+ if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+ sizeof(SCSITaskMgmt_t), msg))
+ != 0) {
+ printk(KERN_WARNING MYNAM
+ ": WARNING[3] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+ i, mf, SCpnt);
+ SCpnt->result = DID_SOFT_ERROR << 16;
+ spin_lock_irqsave(&io_request_lock, flags);
+ SCpnt->scsi_done(SCpnt);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+ }
- return SUCCESS;
+ //return SUCCESS;
+ return FAILED;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
- * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
+ * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
* @SCpnt: Pointer to Scsi_Cmnd structure, IO which reset is due to
*
- * (linux Scsi_Host_Template.eh_dev_reset_handler routine)
+ * (linux Scsi_Host_Template.eh_bus_reset_handler routine)
*
* Returns SUCCESS or FAILED.
*/
int
-mptscsih_dev_reset(Scsi_Cmnd * SCpnt)
+mptscsih_bus_reset(Scsi_Cmnd * SCpnt)
{
MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm;
MPT_SCSI_HOST *hd;
u32 *msg;
int i;
+ unsigned long flags;
- printk(KERN_WARNING MYNAM ": Attempting _TARGET_RESET (%p)\n", SCpnt);
+ printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET (%p)\n", SCpnt);
printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
}
pScsiTm = (SCSITaskMgmt_t *) mf;
- msg = (u32*)mf;
+ msg = (u32 *) mf;
pScsiTm->TargetID = SCpnt->target;
pScsiTm->Bus = hd->port;
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
pScsiTm->Reserved = 0;
- pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
+ pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS;
pScsiTm->Reserved1 = 0;
pScsiTm->MsgFlags = 0;
- /* _TARGET_RESET goes to LUN 0 always! */
for (i = 0; i < 8; i++)
pScsiTm->LUN[i] = 0;
pScsiTm->TaskMsgContext = cpu_to_le32(0);
- wmb();
-
/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake
mpt_put_msg_frame(hd->ioc->id, mf);
*/
/* FIXME! Check return status! */
- (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), msg);
-
- wmb();
+ if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+ sizeof(SCSITaskMgmt_t), msg))
+ != 0) {
+ printk(KERN_WARNING MYNAM
+ ": WARNING[4] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n",
+ i, mf, SCpnt);
+ SCpnt->result = DID_SOFT_ERROR << 16;
+ spin_lock_irqsave(&io_request_lock, flags);
+ SCpnt->scsi_done(SCpnt);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+ }
return SUCCESS;
}
spin_unlock_irqrestore(&mpt_scsih_taskQ_lock, flags);
while (1) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ/4);
+
/*
* We MUST remove item from taskQ *before* we format the
* frame as a SCSITaskMgmt request and send it down to the IOC.
SCpnt = (Scsi_Cmnd*)mf->u.frame.linkage.argp1;
if (SCpnt == NULL) {
- printk(KERN_ERR MYNAM ": ERROR: TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
+ printk(KERN_ERR MYNAM ": ERROR - TaskMgmt has NULL SCpnt! (%p:%p)\n", mf, SCpnt);
continue;
}
+ hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
pScsiTm = (SCSITaskMgmt_t *) mf;
for (i = 0; i < 8; i++) {
}
task_type = mf->u.frame.linkage.arg1;
- if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
- {
- printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf:sc=%p:%p)\n", mf, SCpnt);
+ if (task_type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
+ printk(KERN_WARNING MYNAM ": Attempting _ABORT SCSI IO! (mf=%p:sc=%p)\n",
+ mf, SCpnt);
/* Most important! Set TaskMsgContext to SCpnt's MsgContext!
* (the IO to be ABORT'd)
* the controller, so it does not matter. -DaveM
*/
ctx2abort = SCPNT_TO_MSGCTX(SCpnt);
+ if (ctx2abort == -1) {
+ printk(KERN_ERR MYNAM ": ERROR - ScsiLookup fail(#1) for SCpnt=%p\n", SCpnt);
+ SCpnt->result = DID_SOFT_ERROR << 16;
+ spin_lock_irqsave(&io_request_lock, flags);
+ SCpnt->scsi_done(SCpnt);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+ continue;
+ }
pScsiTm->LUN[1] = SCpnt->lun;
}
else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
{
- printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf:sc=%p:%p)\n", mf, SCpnt);
+ printk(KERN_WARNING MYNAM ": Attempting _BUS_RESET! (against SCSI IO mf=%p:sc=%p)\n", mf, SCpnt);
}
#if 0
else if (task_type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {}
printk(KERN_WARNING MYNAM ": IOs outstanding = %d\n", atomic_read(&queue_depth));
- hd = (MPT_SCSI_HOST *) SCpnt->host->hostdata;
-
pScsiTm->TargetID = SCpnt->target;
pScsiTm->Bus = hd->port;
pScsiTm->ChainOffset = 0;
* mpt_put_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
* SCSITaskMgmt requests MUST be sent ONLY via
* Doorbell/handshake now. :-(
- *
- * FIXME! Check return status!
*/
- (void) mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id, sizeof(SCSITaskMgmt_t), (u32*)mf);
-
- /* Spin-Wait for TaskMgmt complete!!! */
- while (mpt_scsih_active_taskmgmt_mf != NULL) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(HZ/2);
+ if ((i = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc->id,
+ sizeof(SCSITaskMgmt_t), (u32*) mf))
+ != 0) {
+ printk(KERN_WARNING MYNAM ": WARNING[1] - IOC error (%d) processing TaskMgmt request (mf=%p:sc=%p)\n", i, mf, SCpnt);
+ SCpnt->result = DID_SOFT_ERROR << 16;
+ spin_lock_irqsave(&io_request_lock, flags);
+ SCpnt->scsi_done(SCpnt);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ mpt_free_msg_frame(ScsiTaskCtx, hd->ioc->id, mf);
+ } else {
+ /* Spin-Wait for TaskMgmt complete!!! */
+ while (mpt_scsih_active_taskmgmt_mf != NULL) {
+ current->state = TASK_INTERRUPTIBLE;
+ schedule_timeout(HZ/4);
+ }
}
}
#endif
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static int
+mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
+{
+ dprintk((KERN_INFO MYNAM ": IOC %s_reset routed to SCSI host driver!\n",
+ reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"));
+
+ if (reset_phase == MPT_IOC_PRE_RESET) {
+ /* FIXME! Do pre-reset cleanup */
+ } else {
+ /* FIXME! Do post-reset cleanup */
+ }
+
+ return 1; /* currently means nothing really */
+}
+
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static int
mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
* Written By: Steven J. Ralston (19960517)
* (mailto:Steve.Ralston@lsil.com)
*
- * $Id: scsi3.h,v 1.4 2001/01/06 15:54:25 sralston Exp $
+ * $Id: scsi3.h,v 1.5 2001/04/06 14:31:32 sralston Exp $
*/
#ifndef SCSI3_H_INCLUDED
#define CMD_WriteVerify 0x2E
#define CMD_Verify 0x2F
#define CMD_ReadDefectData 0x37
+#define CMD_ReadLong 0x3E
#define CMD_LogSelect 0x4C
#define CMD_LogSense 0x4D
#define CMD_ModeSelect10 0x55
#define CMD_Reserve10 0x56
#define CMD_Release10 0x57
#define CMD_ModeSense10 0x5A
+#define CMD_PersistReserveIn 0x5E
+#define CMD_PersistReserveOut 0x5F
#define CMD_ReportLuns 0xA0
/*
setup(dev);
if (new_device) {
+ int err;
+
rtnl_lock();
- register_netdevice(dev);
+ err = register_netdevice(dev);
rtnl_unlock();
+
+ if (err < 0) {
+ kfree(dev);
+ dev = NULL;
+ }
}
return dev;
}
outb(0xff, EDLC_XCLR); /* Clear all pending xmit IRQ's */
if (xmit_stat & XS_COLL){
- printk("ether collision\n"); /* FIXME: remove */
PRINTK((KERN_DEBUG "%s: collision detected, retransmitting\n",
dev->name));
outw(NI5010_BUFSIZE - lp->o_pkt_size, IE_GP);
- Initialize the TxMode register properly
- Don't dereference dev->priv after freeing it
+ LK1.3.4 (Ion Badulescu)
+ - Fixed initialization timing problems
+ - Fixed interrupt mask definitions
+
TODO:
- implement tx_timeout() properly
*/
#define DRV_NAME "starfire"
-#define DRV_VERSION "1.03+LK1.3.3"
-#define DRV_RELDATE "July 05, 2001"
+#define DRV_VERSION "1.03+LK1.3.4"
+#define DRV_RELDATE "August 14, 2001"
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <asm/processor.h> /* Processor type for cache alignment. */
+#include <asm/uaccess.h>
+#include <asm/io.h>
/*
* Adaptec's license for their Novell drivers (which is where I got the
#define ZEROCOPY
#endif
+#ifdef HAS_FIRMWARE
+#include "starfire_firmware.h"
+#endif /* HAS_FIRMWARE */
+
/* The user-configurable values.
These may be modified when a driver module is loaded.*/
#define skb_first_frag_len(skb) (skb->len)
#endif /* not ZEROCOPY */
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <asm/processor.h> /* Processor type for cache alignment. */
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#ifdef HAS_FIRMWARE
-#include "starfire_firmware.h"
-#endif /* HAS_FIRMWARE */
-
/* 2.2.x compatibility code */
#if LINUX_VERSION_CODE < 0x20300
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
KERN_INFO "starfire.c:v1.03 7/26/2000 Written by Donald Becker <becker@scyld.com>\n"
-KERN_INFO " Updates and info at http://www.scyld.com/network/starfire.html\n"
KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
/* not quite bits */
IntrRxDone=IntrRxQ2Done | IntrRxQ1Done,
IntrRxEmpty=IntrRxDescQ1Low | IntrRxDescQ2Low,
- IntrNormalMask=0xf0, IntrAbnormalMask=0x3f0e,
+ IntrNormalMask=0xff00, IntrAbnormalMask=0x3ff00fe,
};
/* Bits in the RxFilterMode register. */
#ifdef ZEROCOPY
/* Starfire can do SG and TCP/UDP checksumming */
- dev->features |= NETIF_F_SG;
-#ifdef HAS_FIRMWARE
- dev->features |= NETIF_F_IP_CSUM;
-#endif /* HAS_FIRMWARE */
+ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
#endif /* ZEROCOPY */
/* Serial EEPROM reads are hidden by the hardware. */
int mii_status;
for (phy = 0; phy < 32 && phy_idx < PHY_CNT; phy++) {
mdio_write(dev, phy, MII_BMCR, BMCR_RESET);
- udelay(500);
+ mdelay(100);
boguscnt = 1000;
while (--boguscnt > 0)
if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)
np->phy_cnt = phy_idx;
}
+#ifdef ZEROCOPY
+ printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n",
+ dev->name,
+#else /* not ZEROCOPY */
+ printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n",
+ dev->name);
+#endif /* not ZEROCOPY */
+
return 0;
err_out_cleardev:
/* Configure the PCI bus bursts and FIFO thresholds. */
np->tx_mode = 0x0C04; /* modified when link is up. */
writel(0x8000 | np->tx_mode, ioaddr + TxMode);
+ udelay(1000);
writel(np->tx_mode, ioaddr + TxMode);
np->tx_threshold = 4;
writel(np->tx_threshold, ioaddr + TxThreshold);
if (np->tx_mode != new_tx_mode) {
np->tx_mode = new_tx_mode;
writel(np->tx_mode | 0x8000, ioaddr + TxMode);
+ udelay(1000);
writel(np->tx_mode, ioaddr + TxMode);
}
} else {
--- /dev/null
+#!/usr/bin/perl
+
+# This script can be used to generate a new starfire_firmware.h
+# from GFP_RX.DAT and GFP_TX.DAT, files included with the DDK
+# and also with the Novell drivers.
+
+open FW, "GFP_RX.DAT" || die;
+open FWH, ">starfire_firmware.h" || die;
+
+printf(FWH "static u32 firmware_rx[] = {\n");
+$counter = 0;
+while ($foo = <FW>) {
+ chomp;
+ printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
+ $counter++;
+}
+
+close FW;
+open FW, "GFP_TX.DAT" || die;
+
+printf(FWH "};\t/* %d Rx instructions */\n#define FIRMWARE_RX_SIZE %d\n\nstatic u32 firmware_tx[] = {\n", $counter, $counter);
+$counter = 0;
+while ($foo = <FW>) {
+ chomp;
+ printf(FWH " 0x%s, 0x0000%s,\n", substr($foo, 4, 8), substr($foo, 0, 4));
+ $counter++;
+}
+
+close FW;
+printf(FWH "};\t/* %d Tx instructions */\n#define FIRMWARE_TX_SIZE %d\n", $counter, $counter);
+close(FWH);
- Manfred Spraul: use "singlecopy" for unaligned buffers
don't allocate bounce buffers for !ReqTxAlign cards
+ LK1.1.11:
+ - David Woodhouse: Set dev->base_addr before the first time we call
+ wait_for_reset(). It's a lot happier that way.
+ Free np->tx_bufs only if we actually allocated it.
*/
/* These identify the driver base version and may not be removed. */
static char version[] __devinitdata =
-KERN_INFO "via-rhine.c:v1.10-LK1.1.10 07/12/2001 Written by Donald Becker\n"
+KERN_INFO "via-rhine.c:v1.10-LK1.1.11 20/08/2001 Written by Donald Becker\n"
KERN_INFO " http://www.scyld.com/network/via-rhine.html\n";
static char shortname[] __devinitdata = "via-rhine";
/* Reset the chip to erase previous misconfiguration. */
writew(CmdReset, ioaddr + ChipCmd);
+
+ dev->base_addr = ioaddr;
wait_for_reset(dev, shortname);
/* Reload the station address from the EEPROM. */
writeb(readb(ioaddr + ConfigA) & 0xFE, ioaddr + ConfigA);
}
- dev->base_addr = ioaddr;
dev->irq = pdev->irq;
np = dev->priv;
TX_RING_SIZE * sizeof(struct tx_desc),
np->rx_ring, np->rx_ring_dma);
- pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
- np->tx_bufs, np->tx_bufs_dma);
+ if (np->tx_bufs)
+ pci_free_consistent(np->pdev, PKT_BUF_SZ * TX_RING_SIZE,
+ np->tx_bufs, np->tx_bufs_dma);
+
+ np->tx_bufs = NULL;
}
+2001-08-30 Tim Waugh <twaugh@redhat.com>
+
+ * parport_serial.c (parport_serial_pci_probe): Clean-up on partial
+ registration failure.
+
+2001-08-14 Tim Waugh <twaugh@redhat.com>
+
+ * parport_pc.c (parport_pc_init_superio): Allow for more than one
+ SuperIO device. Patch from Rich Lio (ITE).
+
2001-08-11 Tim Waugh <twaugh@redhat.com>
* parport_pc.c: Support for Titan Electronics cards.
{
const struct pci_device_id *id;
struct pci_dev *pdev;
+ int ret = 0;
pci_for_each_dev(pdev) {
id = pci_match_device (parport_pc_pci_tbl, pdev);
if (id == NULL || id->driver_data >= last_sio)
continue;
- return parport_pc_superio_info[id->driver_data].probe
- (pdev, autoirq, autodma);
+ if (parport_pc_superio_info[id->driver_data].probe
+ (pdev, autoirq, autodma)) {
+ ret++;
+ }
}
- return 0; /* zero devices found */
+ return ret; /* number of devices found */
}
#else
static struct pci_driver parport_pc_pci_driver;
return err;
}
- if (serial_register (dev, id) + parport_register (dev, id)) {
+ if (parport_register (dev, id)) {
+ pci_set_drvdata (dev, NULL);
+ kfree (priv);
+ return -ENODEV;
+ }
+
+ if (serial_register (dev, id)) {
+ int i;
+ for (i = 0; i < priv->num_par; i++)
+ parport_pc_unregister_port (priv->port[i]);
pci_set_drvdata (dev, NULL);
kfree (priv);
return -ENODEV;
0620 620 Host
0630 630 Host
0730 730 Host
+ 0735 735 Host
0900 SiS900 10/100 Ethernet
1039 0900 SiS900 10/100 Ethernet Adapter
3602 83C602
1569 6326 SiS6326 GUI Accelerator
7001 7001
7007 OHCI Compliant FireWire Controller
+ 7012 SiS7012 PCI Audio Accelerator
7016 SiS7016 10/100 Ethernet Adapter
1039 7016 SiS7016 10/100 Ethernet Adapter
7018 SiS PCI Audio Accelerator
103a Seiko Epson Corporation
103b Tatung Co. of America
103c Hewlett-Packard Company
+ 1005 A4977A Visualize EG
1030 J2585A
1031 J2585B
103c 1040 J2973A DeskDirect 10BaseT NIC
0505 VT82C505
0561 VT82C561
0571 Bus Master IDE
- 0576 VT82C576 3V [Apollo Master]
+ 0576 VT82C576 [Apollo Master]
0585 VT82C585VP [Apollo VP1/VPX]
0586 VT82C586/A/B PCI-to-ISA [Apollo VP]
1106 0000 MVP3 ISA Bridge
0926 VT82C926 [Amazon]
1000 VT82C570MV
1106 VT82C570MV
- 1571 VT82C416MV
+ 1571 VT82C576 IDE [Apollo Master]
1595 VT82C595/97 [Apollo VP2/97]
3038 UHCI USB
1234 0925 MVP3 USB Controller
3074 VT8233 PCI to ISA Bridge
3091 VT8633 [Apollo Pro266]
3099 VT8367 [KT266]
+ 3109 VT8233C PCI to ISA Bridge
5030 VT82C596 ACPI [Apollo PRO]
6100 VT85C100A [Rhine II]
8231 VT8231 [PCI-to-ISA Bridge]
11d2 Intercom Inc.
11d3 Trancell Systems Inc
11d4 Analog Devices
+ 1889 AD1889 sound chip
11d5 Ikon Corporation
0115 10115
0117 10117
tub3270_con_devno = dp->devno;
tubp->cmd = TBC_CONOPEN;
- tubp->flags |= TUB_OPEN_STET;
+ tubp->flags |= TUB_OPEN_STET | TUB_INPUT_HACK;
tty3270_size(tubp, &flags);
tty3270_aid_init(tubp);
tty3270_scl_init(tubp);
{
char name[16];
- sprintf(name, "tub%x", tubp->devno);
+ sprintf(name, "tub%.3x", tubp->devno);
devfs_register(fs3270_devfs_dir, name, DEVFS_FL_DEFAULT,
IBM_FS3270_MAJOR, tubp->minor,
S_IFCHR | S_IRUSR | S_IWUSR, &fs3270_fops, NULL);
- sprintf(name, "tty%x", tubp->devno);
+ sprintf(name, "tty%.3x", tubp->devno);
tty_register_devfs_name(&tty3270_driver, 0, tubp->minor,
fs3270_devfs_dir, name);
}
char name[16];
devfs_handle_t handle;
- sprintf(name, "tub%x", tubp->devno);
+ sprintf(name, "tub%.3x", tubp->devno);
handle = devfs_find_handle (fs3270_devfs_dir, name,
IBM_FS3270_MAJOR, tubp->minor,
DEVFS_SPECIAL_CHR, 0);
devfs_unregister (handle);
- sprintf(name, "tty%x", tubp->devno);
+ sprintf(name, "tty%.3x", tubp->devno);
handle = devfs_find_handle (fs3270_devfs_dir, name,
IBM_TTY3270_MAJOR, tubp->minor,
DEVFS_SPECIAL_CHR, 0);
fs3270_devfs_tub =
devfs_register(fs3270_devfs_dir, "tub", DEVFS_FL_DEFAULT,
IBM_FS3270_MAJOR, 0,
- S_IFCHR | S_IRUSR | S_IWUSR,
+ S_IFCHR | S_IRUGO | S_IWUGO,
&fs3270_fops, NULL);
#else
rc = register_chrdev(IBM_FS3270_MAJOR, "fs3270", &fs3270_fops);
#define TUB_UNSOL_DE 0x0200
#define TUB_OPEN_STET 0x0400 /* No screen clear on open */
#define TUB_UE_BUSY 0x0800
+#define TUB_INPUT_HACK 0x1000 /* Early init of command line */
#ifdef CONFIG_TN3270_CONSOLE
/*
if (MAJOR(current->tty->device) == IBM_TTY3270_MAJOR)
minor = MINOR(current->tty->device);
}
- if (minor >= tubnummins && minor > 0)
+ if (minor <= tubnummins && minor > 0)
tubp = (*tubminors)[minor];
return tubp;
}
if (tty)
len += sprintf(buf+len,
" write_wait=%.8x read_wait=%.8x\n",
- tty->write_wait, tty->read_wait);
+ (int)&tty->write_wait, (int)&tty->read_wait);
if (tty && ((mp = tty->termios)))
len += sprintf(buf+len," iflag=%.8x oflag=%.8x "
TUB_BUFADR(GEOM_INPUT, cpp);
*(*cpp)++ = '\0';
tubp->tty_oucol = tubp->tty_nextlogx = 0;
+ *(*cpp)++ = TO_SBA;
+ TUB_BUFADR(tubp->tty_nextlogx, cpp);
}
static void
printk(KERN_WARNING "tty3270_build unknown command %d\n", tubp->cmd);
return 0;
case TBC_OPEN:
+tbc_open:
+ tubp->flags &= ~TUB_INPUT_HACK;
chancmd = TC_EWRITEA;
tty3270_clear_input_area(tubp, &cp);
tty3270_set_status_area(tubp, &cp);
tty3270_clear_log_area(tubp, &cp);
break;
case TBC_UPDLOG:
+ if (tubp->flags & TUB_INPUT_HACK)
+ goto tbc_open;
chancmd = TC_WRITE;
writecc = TW_NONE;
tty3270_update_log_area(tubp, &cp);
1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
Remove check for invalid done function pointer from
tw_scsi_queue().
+ 1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
+ Add tw_decode_error() for printing readable error messages.
+ Print some useful information on certain aen codes.
+ Add tw_decode_bits() for interpreting status register output.
+ Make scsi_set_pci_device() for kernels >= 2.4.4
+ Fix bug where aen's could be lost before a reset.
+ Re-add spinlocks in tw_scsi_detect().
+ Fix possible null pointer dereference in tw_aen_drain_queue()
+ during initialization.
+ Clear pci parity errors during initialization and during io.
*/
#include <linux/module.h>
};
/* Globals */
-char *tw_driver_version="1.02.00.007";
+char *tw_driver_version="1.02.00.008";
TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
int tw_device_extension_count = 0;
TW_Param *param;
unsigned short aen;
+ dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
if (tw_dev->alignment_virtual_address[request_id] == NULL) {
printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
return 1;
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
aen = *(unsigned short *)(param->data);
dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
+
+ /* Print some useful info when certain aen codes come out */
+ switch (aen & 0x0ff) {
+ case TW_AEN_APORT_TIMEOUT:
+ printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive timeout AEN on port %d, check drive and drive cables.\n", tw_dev->host->host_no, aen >> 8);
+ break;
+ case TW_AEN_DRIVE_ERROR:
+ printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
+ break;
+ case TW_AEN_SMART_FAIL:
+ printk(KERN_WARNING "3w-xxxx: scsi%d: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8);
+ break;
+ case TW_AEN_SBUF_FAIL:
+ printk(KERN_WARNING "3w-xxxx: scsi%d: Received SBUF integrity check failure AEN, reseat card or bad card.\n", tw_dev->host->host_no);
+ break;
+ default:
+ printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen);
+ }
+
+ tw_dev->aen_count++;
+
/* Now queue the code */
tw_dev->aen_queue[tw_dev->aen_tail] = aen;
if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
response_que_addr = tw_dev->registers.response_que_addr;
if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) {
- printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_dev->host->host_no);
+ printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
return 1;
}
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n");
queue = 1;
break;
+ case TW_AEN_APORT_TIMEOUT:
+ printk(KERN_WARNING "3w-xxxx: Received drive timeout AEN on port %d, check drive and drive cables.\n", aen >> 8);
+ queue = 1;
+ break;
+ case TW_AEN_DRIVE_ERROR:
+ printk(KERN_WARNING "3w-xxxx: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", aen >> 8);
+ queue = 1;
+ break;
+ case TW_AEN_SMART_FAIL:
+ printk(KERN_WARNING "3w-xxxx: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", aen >> 8);
+ queue = 1;
+ break;
+ case TW_AEN_SBUF_FAIL:
+ printk(KERN_WARNING "3w-xxxx: Received SBUF integrity check failure AEN, reseat card or bad card.\n");
+ queue = 1;
+ break;
default:
dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code);
queue = 1;
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
}
} /* End tw_copy_mem_info() */
+/* This function will print readable messages from statsu register errors */
+void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
+{
+ dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
+ switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
+ case TW_STATUS_PCI_PARITY_ERROR:
+ printk(KERN_WARNING "3w-xxxx: PCI Parity Error: Reseat card, move card, or buggy device on the bus.\n");
+ outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
+ pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PARITY_ERRORS);
+ break;
+ case TW_STATUS_MICROCONTROLLER_ERROR:
+ printk(KERN_WARNING "3w-xxxx: Microcontroller Error.\n");
+ break;
+ }
+} /* End tw_decode_bits() */
+
+/* This function will print readable messages from flags and status values */
+void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit)
+{
+ dprintk(KERN_WARNING "3w-xxxx: tw_decode_error()\n");
+ switch (status) {
+ case 0xc7:
+ switch (flags) {
+ case 0x1b:
+ printk(KERN_WARNING "3w-xxxx: scsi%d: Drive timeout on unit %d, check drive and drive cables.\n", tw_dev->host->host_no, unit);
+ break;
+ case 0x51:
+ printk(KERN_WARNING "3w-xxxx: scsi%d: Unrecoverable drive error on unit %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, unit);
+ break;
+ }
+ break;
+ }
+} /* End tw_decode_error() */
+
/* This function will disable interrupts on the controller */
void tw_disable_interrupts(TW_Device_Extension *tw_dev)
{
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
}
/* Save pci_dev struct to device extension */
tw_dev->tw_pci_dev = tw_pci_dev;
+ /* Check for errors and clear them */
+ status_reg_value = inl(tw_dev->registers.status_reg_addr);
+ if (TW_STATUS_ERRORS(status_reg_value))
+ tw_decode_bits(tw_dev, status_reg_value);
+
/* Poll status register for 60 secs for 'Controller Ready' flag */
if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
continue;
}
+ /* Set max sectors per io */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
+ host->max_sectors = TW_MAX_SECTORS;
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
scsi_set_pci_device(host, tw_pci_dev);
+#endif
+
status_reg_value = inl(tw_dev->registers.status_reg_addr);
- dprintk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d P-chip: %d.%d\n", host->host_no,
+ printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
(u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
(status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
(status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
request_id = (unsigned char)response_queue.u.response_id;
if (request_id != 0) {
/* unexpected request id */
- printk(KERN_WARNING "3w-xxxx: tw_initia
-lize_units(): Unexpected request id.\n");
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
return 1;
}
if (command_packet->status != 0) {
/* bad response */
- printk(KERN_WARNING "3w-xxxx: tw_initia
-lize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
return 1;
}
found = 1;
}
if (found == 0) {
/* response never received */
- printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No
- response.\n");
+ printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
return 1;
}
/* Now allocate raid5 bounce buffers */
if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
for (i=0;i<TW_Q_LENGTH;i++) {
- tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*256, 2);
+ tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*TW_MAX_SECTORS, 2);
if (tw_dev->bounce_buffer[i] == NULL) {
printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bounce buffer allocation failed.\n");
return 1;
}
- memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*256);
+ memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*TW_MAX_SECTORS);
}
}
error = 0;
if (command_packet->status != 0) {
printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit);
+ tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
error = 1;
}
if (tw_dev->state[request_id] != TW_S_POSTED) {
printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
error = 1;
}
+ if (TW_STATUS_ERRORS(status_reg_value)) {
+ tw_decode_bits(tw_dev, status_reg_value);
+ error = 1;
+ }
dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
/* Check for internal command */
if (tw_dev->srb[request_id] == 0) {
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
}
} else {
switch (tw_dev->srb[request_id]->cmnd[0]) {
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
}
}
}
param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
memset(param, 0, sizeof(TW_Sector));
- dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id,, ioctl->parameter_size_bytes);
+ dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
opcode = ioctl->opcode;
switch (opcode) {
status_reg_addr = tw_dev->registers.status_reg_addr;
status_reg_value = inl(status_reg_addr);
- if (tw_check_bits(status_reg_value))
+ if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
+ }
if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
/* We successfully posted the command packet */
dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
+ printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
+
/* Check if the kernel has PCI interface compiled in */
if (!pci_present()) {
printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
return 0;
}
+ spin_unlock_irq(&io_request_lock);
ret = tw_findcards(tw_host);
+ spin_lock_irq(&io_request_lock);
return ret;
} /* End tw_scsi_detect() */
return (FAILED);
}
+ /* We have to let AEN requests through before the reset */
+ spin_unlock_irq(&io_request_lock);
+ mdelay(TW_AEN_WAIT_TIME);
+ spin_lock_irq(&io_request_lock);
+
spin_lock(&tw_dev->tw_lock);
tw_dev->num_aborts++;
return (FAILED);
}
+ /* We have to let AEN requests through before the reset */
+ spin_unlock_irq(&io_request_lock);
+ mdelay(TW_AEN_WAIT_TIME);
+ spin_lock_irq(&io_request_lock);
+
spin_lock(&tw_dev->tw_lock);
tw_dev->num_resets++;
status_reg_value = inl(status_reg_addr);
if (tw_check_bits(status_reg_value)) {
printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+ tw_decode_bits(tw_dev, status_reg_value);
return 1;
}
if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
#define TW_CONTROL_ENABLE_INTERRUPTS 0x00000080
#define TW_CONTROL_DISABLE_INTERRUPTS 0x00000040
#define TW_CONTROL_ISSUE_HOST_INTERRUPT 0x00000020
+#define TW_CONTROL_CLEAR_PARITY_ERROR 0x00800000
/* Status register bit definitions */
#define TW_STATUS_MAJOR_VERSION_MASK 0xF0000000
#define TW_DEVICE_ID (0x1000) /* Storage Controller */
#define TW_DEVICE_ID2 (0x1001) /* 7000 series controller */
#define TW_NUMDEVICES 2
+#define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
/* Command packet opcodes */
#define TW_OP_NOP 0x0
#define TW_AEN_REBUILD_DONE 0x0005
#define TW_AEN_QUEUE_FULL 0x00ff
#define TW_AEN_TABLE_UNDEFINED 0x15
+#define TW_AEN_APORT_TIMEOUT 0x0009
+#define TW_AEN_DRIVE_ERROR 0x000A
+#define TW_AEN_SMART_FAIL 0x000F
+#define TW_AEN_SBUF_FAIL 0x0024
/* Misc defines */
#define TW_ALIGNMENT 0x200 /* 16 D-WORDS */
#define TW_MAX_AEN_TRIES 100
#define TW_UNIT_ONLINE 1
#define TW_IN_INTR 1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
+#define TW_MAX_SECTORS 256
+#else
+#define TW_MAX_SECTORS 128
+#endif
+#define TW_AEN_WAIT_TIME 1000
/* Macros */
#define TW_STATUS_ERRORS(x) \
int tw_check_errors(TW_Device_Extension *tw_dev);
void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev);
void tw_clear_host_interrupt(TW_Device_Extension *tw_dev);
+void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value);
+void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit);
void tw_disable_interrupts(TW_Device_Extension *tw_dev);
int tw_empty_response_que(TW_Device_Extension *tw_dev);
void tw_enable_interrupts(TW_Device_Extension *tw_dev);
void (*my_done) (Scsi_Cmnd *) = NULL;
int errstatus, mbi, mbo, mbistatus;
int number_serviced;
- unsigned int flags;
+ unsigned long flags;
struct Scsi_Host *shost;
Scsi_Cmnd *SCtmp;
int flag;
--- /dev/null
+/* BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef __OSD_UTIL_H
+#define __OSD_UTIL_H
+
+/*File - OSD_UTIL.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ * This file contains defines and function prototypes that are
+ *operating system dependent. The resources defined in this file
+ *are not specific to any particular application.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ * 140 Candace Dr.
+ * Maitland, Fl. 32751 USA
+ * Phone: (407) 830-5522 Fax: (407) 260-5366
+ * All Rights Reserved
+ *
+ *Author: Doug Anderson
+ *Date: 1/7/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+/*----------------------------- */
+/* Operating system selections: */
+/*----------------------------- */
+
+/*#define _DPT_MSDOS */
+/*#define _DPT_WIN_3X */
+/*#define _DPT_WIN_4X */
+/*#define _DPT_WIN_NT */
+/*#define _DPT_NETWARE */
+/*#define _DPT_OS2 */
+/*#define _DPT_SCO */
+/*#define _DPT_UNIXWARE */
+/*#define _DPT_SOLARIS */
+/*#define _DPT_NEXTSTEP */
+/*#define _DPT_BANYAN */
+
+/*-------------------------------- */
+/* Include the OS specific defines */
+/*-------------------------------- */
+
+/*#define OS_SELECTION From Above List */
+/*#define SEMAPHORE_T ??? */
+/*#define DLL_HANDLE_T ??? */
+
+#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
+# include "i386/isa/dpt_osd_defs.h"
+#else
+# include "osd_defs.h"
+#endif
+
+#ifndef DPT_UNALIGNED
+ #define DPT_UNALIGNED
+#endif
+
+#ifndef DPT_EXPORT
+ #define DPT_EXPORT
+#endif
+
+#ifndef DPT_IMPORT
+ #define DPT_IMPORT
+#endif
+
+#ifndef DPT_RUNTIME_IMPORT
+ #define DPT_RUNTIME_IMPORT DPT_IMPORT
+#endif
+
+/*--------------------- */
+/* OS dependent defines */
+/*--------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
+ #define _DPT_16_BIT
+#else
+ #define _DPT_32_BIT
+#endif
+
+#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
+ #define _DPT_UNIX
+#endif
+
+#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
+ || defined (_DPT_OS2)
+ #define _DPT_DLL_SUPPORT
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
+ #define _DPT_PREEMPTIVE
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
+ #define _DPT_MULTI_THREADED
+#endif
+
+#if !defined (_DPT_MSDOS)
+ #define _DPT_MULTI_TASKING
+#endif
+
+ /* These exist for platforms that */
+ /* chunk when accessing mis-aligned */
+ /* data */
+#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
+ #if defined (_DPT_BIG_ENDIAN)
+ #if !defined (_DPT_STRICT_ALIGN)
+ #define _DPT_STRICT_ALIGN
+ #endif
+ #endif
+#endif
+
+ /* Determine if in C or C++ mode */
+#ifdef __cplusplus
+ #define _DPT_CPP
+#else
+ #define _DPT_C
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Under Solaris the compiler refuses to accept code like: */
+/* { {"DPT"}, 0, NULL .... }, */
+/* and complains about the {"DPT"} part by saying "cannot use { } */
+/* to initialize char*". */
+/* */
+/* By defining these ugly macros we can get around this and also */
+/* not have to copy and #ifdef large sections of code. I know that */
+/* these macros are *really* ugly, but they should help reduce */
+/* maintenance in the long run. */
+/* */
+/*-------------------------------------------------------------------*/
+#if !defined (DPTSQO)
+ #if defined (_DPT_SOLARIS)
+ #define DPTSQO
+ #define DPTSQC
+ #else
+ #define DPTSQO {
+ #define DPTSQC }
+ #endif /* solaris */
+#endif /* DPTSQO */
+
+
+/*---------------------- */
+/* OS dependent typedefs */
+/*---------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
+ #define BYTE unsigned char
+ #define WORD unsigned short
+#endif
+
+#ifndef _DPT_TYPEDEFS
+ #define _DPT_TYPEDEFS
+ typedef unsigned char uCHAR;
+ typedef unsigned short uSHORT;
+ typedef unsigned int uINT;
+ typedef unsigned long uLONG;
+
+ typedef union {
+ uCHAR u8[4];
+ uSHORT u16[2];
+ uLONG u32;
+ } access_U;
+#endif
+
+#if !defined (NULL)
+ #define NULL 0
+#endif
+
+
+/*Prototypes - function ----------------------------------------------------- */
+
+#ifdef __cplusplus
+ extern "C" { /* Declare all these functions as "C" functions */
+#endif
+
+/*------------------------ */
+/* Byte reversal functions */
+/*------------------------ */
+
+ /* Reverses the byte ordering of a 2 byte variable */
+#if (!defined(osdSwap2))
+ uSHORT osdSwap2(DPT_UNALIGNED uSHORT *);
+#endif // !osdSwap2
+
+ /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
+#if (!defined(osdSwap3))
+ uLONG osdSwap3(DPT_UNALIGNED uLONG *);
+#endif // !osdSwap3
+
+
+#ifdef _DPT_NETWARE
+ #include "novpass.h" /* For DPT_Bswapl() prototype */
+ /* Inline the byte swap */
+ #ifdef __cplusplus
+ inline uLONG osdSwap4(uLONG *inLong) {
+ return *inLong = DPT_Bswapl(*inLong);
+ }
+ #else
+ #define osdSwap4(inLong) DPT_Bswapl(inLong)
+ #endif // cplusplus
+#else
+ /* Reverses the byte ordering of a 4 byte variable */
+# if (!defined(osdSwap4))
+ uLONG osdSwap4(DPT_UNALIGNED uLONG *);
+# endif // !osdSwap4
+
+ /* The following functions ALWAYS swap regardless of the *
+ * presence of DPT_BIG_ENDIAN */
+
+ uSHORT trueSwap2(DPT_UNALIGNED uSHORT *);
+ uLONG trueSwap4(DPT_UNALIGNED uLONG *);
+
+#endif // netware
+
+
+/*-------------------------------------*
+ * Network order swap functions *
+ * *
+ * These functions/macros will be used *
+ * by the structure insert()/extract() *
+ * functions. *
+ *
+ * We will enclose all structure *
+ * portability modifications inside *
+ * #ifdefs. When we are ready, we *
+ * will #define DPT_PORTABLE to begin *
+ * using the modifications. *
+ *-------------------------------------*/
+uLONG netSwap4(uLONG val);
+
+#if defined (_DPT_BIG_ENDIAN)
+
+// for big-endian we need to swap
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
+#endif // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) netSwap4((x))
+#endif // NET_SWAP_4
+
+#else
+
+// for little-endian we don't need to do anything
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (x)
+#endif // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) (x)
+#endif // NET_SWAP_4
+
+#endif // big endian
+
+
+
+/*----------------------------------- */
+/* Run-time loadable module functions */
+/*----------------------------------- */
+
+ /* Loads the specified run-time loadable DLL */
+DLL_HANDLE_T osdLoadModule(uCHAR *);
+ /* Unloads the specified run-time loadable DLL */
+uSHORT osdUnloadModule(DLL_HANDLE_T);
+ /* Returns a pointer to a function inside a run-time loadable DLL */
+void * osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
+
+/*--------------------------------------- */
+/* Mutually exclusive semaphore functions */
+/*--------------------------------------- */
+
+ /* Create a named semaphore */
+SEMAPHORE_T osdCreateNamedSemaphore(char *);
+ /* Create a mutually exlusive semaphore */
+SEMAPHORE_T osdCreateSemaphore(void);
+ /* create an event semaphore */
+SEMAPHORE_T osdCreateEventSemaphore(void);
+ /* create a named event semaphore */
+SEMAPHORE_T osdCreateNamedEventSemaphore(char *);
+
+ /* Destroy the specified mutually exclusive semaphore object */
+uSHORT osdDestroySemaphore(SEMAPHORE_T);
+ /* Request access to the specified mutually exclusive semaphore */
+uLONG osdRequestSemaphore(SEMAPHORE_T,uLONG);
+ /* Release access to the specified mutually exclusive semaphore */
+uSHORT osdReleaseSemaphore(SEMAPHORE_T);
+ /* wait for a event to happen */
+uLONG osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
+ /* signal an event */
+uLONG osdSignalEventSemaphore(SEMAPHORE_T);
+ /* reset the event */
+uLONG osdResetEventSemaphore(SEMAPHORE_T);
+
+/*----------------- */
+/* Thread functions */
+/*----------------- */
+
+ /* Releases control to the task switcher in non-preemptive */
+ /* multitasking operating systems. */
+void osdSwitchThreads(void);
+
+ /* Starts a thread function */
+uLONG osdStartThread(void *,void *);
+
+/* what is my thread id */
+uLONG osdGetThreadID(void);
+
+/* wakes up the specifed thread */
+void osdWakeThread(uLONG);
+
+/* osd sleep for x miliseconds */
+void osdSleep(uLONG);
+
+#define DPT_THREAD_PRIORITY_LOWEST 0x00
+#define DPT_THREAD_PRIORITY_NORMAL 0x01
+#define DPT_THREAD_PRIORITY_HIGHEST 0x02
+
+uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
+
+#ifdef __cplusplus
+ } /* end the xtern "C" declaration */
+#endif
+
+#endif /* osd_util_h */
--- /dev/null
+#ifndef _SCSI_I2O_H
+#define _SCSI_I2O_H
+
+/* I2O kernel space accessible structures/APIs
+ *
+ * (c) Copyright 1999, 2000 Red Hat Software
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ *************************************************************************
+ *
+ * This header file defined the I2O APIs/structures for use by
+ * the I2O kernel modules.
+ *
+ */
+
+#ifdef __KERNEL__ /* This file to be included by kernel only */
+
+#include <linux/i2o-dev.h>
+
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+#include <linux/config.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+
+/*
+ * Tunable parameters first
+ */
+
+/* How many different OSM's are we allowing */
+#define MAX_I2O_MODULES 64
+
+#define I2O_EVT_CAPABILITY_OTHER 0x01
+#define I2O_EVT_CAPABILITY_CHANGED 0x02
+
+#define I2O_EVT_SENSOR_STATE_CHANGED 0x01
+
+//#ifdef __KERNEL__ /* ioctl stuff only thing exported to users */
+
+#define I2O_MAX_MANAGERS 4
+
+#include <asm/semaphore.h> /* Needed for MUTEX init macros */
+
+/*
+ * I2O Interface Objects
+ */
+
+#include <linux/config.h>
+#include <linux/notifier.h>
+#include <asm/atomic.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+
+#define DECLARE_MUTEX(name) struct semaphore name=MUTEX
+
+typedef struct wait_queue *adpt_wait_queue_head_t;
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) adpt_wait_queue_head_t wait = NULL
+typedef struct wait_queue adpt_wait_queue_t;
+#else
+
+#include <linux/wait.h>
+typedef wait_queue_head_t adpt_wait_queue_head_t;
+#define ADPT_DECLARE_WAIT_QUEUE_HEAD(wait) DECLARE_WAIT_QUEUE_HEAD(wait)
+typedef wait_queue_t adpt_wait_queue_t;
+
+#endif
+/*
+ * message structures
+ */
+
+struct i2o_message
+{
+ u8 version_offset;
+ u8 flags;
+ u16 size;
+ u32 target_tid:12;
+ u32 init_tid:12;
+ u32 function:8;
+ u32 initiator_context;
+ /* List follows */
+};
+
+struct adpt_device;
+struct _adpt_hba;
+struct i2o_device
+{
+ struct i2o_device *next; /* Chain */
+ struct i2o_device *prev;
+
+ char dev_name[8]; /* linux /dev name if available */
+ i2o_lct_entry lct_data;/* Device LCT information */
+ u32 flags;
+ struct proc_dir_entry* proc_entry; /* /proc dir */
+ struct adpt_device *owner;
+ struct _adpt_hba *controller; /* Controlling IOP */
+};
+
+/*
+ * Each I2O controller has one of these objects
+ */
+
+struct i2o_controller
+{
+ char name[16];
+ int unit;
+ int type;
+ int enabled;
+
+ struct notifier_block *event_notifer; /* Events */
+ atomic_t users;
+ struct i2o_device *devices; /* I2O device chain */
+ struct i2o_controller *next; /* Controller chain */
+
+};
+
+/*
+ * I2O System table entry
+ */
+struct i2o_sys_tbl_entry
+{
+ u16 org_id;
+ u16 reserved1;
+ u32 iop_id:12;
+ u32 reserved2:20;
+ u16 seg_num:12;
+ u16 i2o_version:4;
+ u8 iop_state;
+ u8 msg_type;
+ u16 frame_size;
+ u16 reserved3;
+ u32 last_changed;
+ u32 iop_capabilities;
+ u32 inbound_low;
+ u32 inbound_high;
+};
+
+struct i2o_sys_tbl
+{
+ u8 num_entries;
+ u8 version;
+ u16 reserved1;
+ u32 change_ind;
+ u32 reserved2;
+ u32 reserved3;
+ struct i2o_sys_tbl_entry iops[0];
+};
+
+/*
+ * I2O classes / subclasses
+ */
+
+/* Class ID and Code Assignments
+ * (LCT.ClassID.Version field)
+ */
+#define I2O_CLASS_VERSION_10 0x00
+#define I2O_CLASS_VERSION_11 0x01
+
+/* Class code names
+ * (from v1.5 Table 6-1 Class Code Assignments.)
+ */
+
+#define I2O_CLASS_EXECUTIVE 0x000
+#define I2O_CLASS_DDM 0x001
+#define I2O_CLASS_RANDOM_BLOCK_STORAGE 0x010
+#define I2O_CLASS_SEQUENTIAL_STORAGE 0x011
+#define I2O_CLASS_LAN 0x020
+#define I2O_CLASS_WAN 0x030
+#define I2O_CLASS_FIBRE_CHANNEL_PORT 0x040
+#define I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL 0x041
+#define I2O_CLASS_SCSI_PERIPHERAL 0x051
+#define I2O_CLASS_ATE_PORT 0x060
+#define I2O_CLASS_ATE_PERIPHERAL 0x061
+#define I2O_CLASS_FLOPPY_CONTROLLER 0x070
+#define I2O_CLASS_FLOPPY_DEVICE 0x071
+#define I2O_CLASS_BUS_ADAPTER_PORT 0x080
+#define I2O_CLASS_PEER_TRANSPORT_AGENT 0x090
+#define I2O_CLASS_PEER_TRANSPORT 0x091
+
+/* Rest of 0x092 - 0x09f reserved for peer-to-peer classes
+ */
+
+#define I2O_CLASS_MATCH_ANYCLASS 0xffffffff
+
+/* Subclasses
+ */
+
+#define I2O_SUBCLASS_i960 0x001
+#define I2O_SUBCLASS_HDM 0x020
+#define I2O_SUBCLASS_ISM 0x021
+
+/* Operation functions */
+
+#define I2O_PARAMS_FIELD_GET 0x0001
+#define I2O_PARAMS_LIST_GET 0x0002
+#define I2O_PARAMS_MORE_GET 0x0003
+#define I2O_PARAMS_SIZE_GET 0x0004
+#define I2O_PARAMS_TABLE_GET 0x0005
+#define I2O_PARAMS_FIELD_SET 0x0006
+#define I2O_PARAMS_LIST_SET 0x0007
+#define I2O_PARAMS_ROW_ADD 0x0008
+#define I2O_PARAMS_ROW_DELETE 0x0009
+#define I2O_PARAMS_TABLE_CLEAR 0x000A
+
+/*
+ * I2O serial number conventions / formats
+ * (circa v1.5)
+ */
+
+#define I2O_SNFORMAT_UNKNOWN 0
+#define I2O_SNFORMAT_BINARY 1
+#define I2O_SNFORMAT_ASCII 2
+#define I2O_SNFORMAT_UNICODE 3
+#define I2O_SNFORMAT_LAN48_MAC 4
+#define I2O_SNFORMAT_WAN 5
+
+/* Plus new in v2.0 (Yellowstone pdf doc)
+ */
+
+#define I2O_SNFORMAT_LAN64_MAC 6
+#define I2O_SNFORMAT_DDM 7
+#define I2O_SNFORMAT_IEEE_REG64 8
+#define I2O_SNFORMAT_IEEE_REG128 9
+#define I2O_SNFORMAT_UNKNOWN2 0xff
+
+/* Transaction Reply Lists (TRL) Control Word structure */
+
+#define TRL_SINGLE_FIXED_LENGTH 0x00
+#define TRL_SINGLE_VARIABLE_LENGTH 0x40
+#define TRL_MULTIPLE_FIXED_LENGTH 0x80
+
+/*
+ * Messaging API values
+ */
+
+#define I2O_CMD_ADAPTER_ASSIGN 0xB3
+#define I2O_CMD_ADAPTER_READ 0xB2
+#define I2O_CMD_ADAPTER_RELEASE 0xB5
+#define I2O_CMD_BIOS_INFO_SET 0xA5
+#define I2O_CMD_BOOT_DEVICE_SET 0xA7
+#define I2O_CMD_CONFIG_VALIDATE 0xBB
+#define I2O_CMD_CONN_SETUP 0xCA
+#define I2O_CMD_DDM_DESTROY 0xB1
+#define I2O_CMD_DDM_ENABLE 0xD5
+#define I2O_CMD_DDM_QUIESCE 0xC7
+#define I2O_CMD_DDM_RESET 0xD9
+#define I2O_CMD_DDM_SUSPEND 0xAF
+#define I2O_CMD_DEVICE_ASSIGN 0xB7
+#define I2O_CMD_DEVICE_RELEASE 0xB9
+#define I2O_CMD_HRT_GET 0xA8
+#define I2O_CMD_ADAPTER_CLEAR 0xBE
+#define I2O_CMD_ADAPTER_CONNECT 0xC9
+#define I2O_CMD_ADAPTER_RESET 0xBD
+#define I2O_CMD_LCT_NOTIFY 0xA2
+#define I2O_CMD_OUTBOUND_INIT 0xA1
+#define I2O_CMD_PATH_ENABLE 0xD3
+#define I2O_CMD_PATH_QUIESCE 0xC5
+#define I2O_CMD_PATH_RESET 0xD7
+#define I2O_CMD_STATIC_MF_CREATE 0xDD
+#define I2O_CMD_STATIC_MF_RELEASE 0xDF
+#define I2O_CMD_STATUS_GET 0xA0
+#define I2O_CMD_SW_DOWNLOAD 0xA9
+#define I2O_CMD_SW_UPLOAD 0xAB
+#define I2O_CMD_SW_REMOVE 0xAD
+#define I2O_CMD_SYS_ENABLE 0xD1
+#define I2O_CMD_SYS_MODIFY 0xC1
+#define I2O_CMD_SYS_QUIESCE 0xC3
+#define I2O_CMD_SYS_TAB_SET 0xA3
+
+#define I2O_CMD_UTIL_NOP 0x00
+#define I2O_CMD_UTIL_ABORT 0x01
+#define I2O_CMD_UTIL_CLAIM 0x09
+#define I2O_CMD_UTIL_RELEASE 0x0B
+#define I2O_CMD_UTIL_PARAMS_GET 0x06
+#define I2O_CMD_UTIL_PARAMS_SET 0x05
+#define I2O_CMD_UTIL_EVT_REGISTER 0x13
+#define I2O_CMD_UTIL_EVT_ACK 0x14
+#define I2O_CMD_UTIL_CONFIG_DIALOG 0x10
+#define I2O_CMD_UTIL_DEVICE_RESERVE 0x0D
+#define I2O_CMD_UTIL_DEVICE_RELEASE 0x0F
+#define I2O_CMD_UTIL_LOCK 0x17
+#define I2O_CMD_UTIL_LOCK_RELEASE 0x19
+#define I2O_CMD_UTIL_REPLY_FAULT_NOTIFY 0x15
+
+#define I2O_CMD_SCSI_EXEC 0x81
+#define I2O_CMD_SCSI_ABORT 0x83
+#define I2O_CMD_SCSI_BUSRESET 0x27
+
+#define I2O_CMD_BLOCK_READ 0x30
+#define I2O_CMD_BLOCK_WRITE 0x31
+#define I2O_CMD_BLOCK_CFLUSH 0x37
+#define I2O_CMD_BLOCK_MLOCK 0x49
+#define I2O_CMD_BLOCK_MUNLOCK 0x4B
+#define I2O_CMD_BLOCK_MMOUNT 0x41
+#define I2O_CMD_BLOCK_MEJECT 0x43
+
+#define I2O_PRIVATE_MSG 0xFF
+
+/*
+ * Init Outbound Q status
+ */
+
+#define I2O_CMD_OUTBOUND_INIT_IN_PROGRESS 0x01
+#define I2O_CMD_OUTBOUND_INIT_REJECTED 0x02
+#define I2O_CMD_OUTBOUND_INIT_FAILED 0x03
+#define I2O_CMD_OUTBOUND_INIT_COMPLETE 0x04
+
+/*
+ * I2O Get Status State values
+ */
+
+#define ADAPTER_STATE_INITIALIZING 0x01
+#define ADAPTER_STATE_RESET 0x02
+#define ADAPTER_STATE_HOLD 0x04
+#define ADAPTER_STATE_READY 0x05
+#define ADAPTER_STATE_OPERATIONAL 0x08
+#define ADAPTER_STATE_FAILED 0x10
+#define ADAPTER_STATE_FAULTED 0x11
+
+/* I2O API function return values */
+
+#define I2O_RTN_NO_ERROR 0
+#define I2O_RTN_NOT_INIT 1
+#define I2O_RTN_FREE_Q_EMPTY 2
+#define I2O_RTN_TCB_ERROR 3
+#define I2O_RTN_TRANSACTION_ERROR 4
+#define I2O_RTN_ADAPTER_ALREADY_INIT 5
+#define I2O_RTN_MALLOC_ERROR 6
+#define I2O_RTN_ADPTR_NOT_REGISTERED 7
+#define I2O_RTN_MSG_REPLY_TIMEOUT 8
+#define I2O_RTN_NO_STATUS 9
+#define I2O_RTN_NO_FIRM_VER 10
+#define I2O_RTN_NO_LINK_SPEED 11
+
+/* Reply message status defines for all messages */
+
+#define I2O_REPLY_STATUS_SUCCESS 0x00
+#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01
+#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02
+#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03
+#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04
+#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05
+#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06
+#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x08
+#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x09
+#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x0A
+#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0B
+#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80
+
+/* Status codes and Error Information for Parameter functions */
+
+#define I2O_PARAMS_STATUS_SUCCESS 0x00
+#define I2O_PARAMS_STATUS_BAD_KEY_ABORT 0x01
+#define I2O_PARAMS_STATUS_BAD_KEY_CONTINUE 0x02
+#define I2O_PARAMS_STATUS_BUFFER_FULL 0x03
+#define I2O_PARAMS_STATUS_BUFFER_TOO_SMALL 0x04
+#define I2O_PARAMS_STATUS_FIELD_UNREADABLE 0x05
+#define I2O_PARAMS_STATUS_FIELD_UNWRITEABLE 0x06
+#define I2O_PARAMS_STATUS_INSUFFICIENT_FIELDS 0x07
+#define I2O_PARAMS_STATUS_INVALID_GROUP_ID 0x08
+#define I2O_PARAMS_STATUS_INVALID_OPERATION 0x09
+#define I2O_PARAMS_STATUS_NO_KEY_FIELD 0x0A
+#define I2O_PARAMS_STATUS_NO_SUCH_FIELD 0x0B
+#define I2O_PARAMS_STATUS_NON_DYNAMIC_GROUP 0x0C
+#define I2O_PARAMS_STATUS_OPERATION_ERROR 0x0D
+#define I2O_PARAMS_STATUS_SCALAR_ERROR 0x0E
+#define I2O_PARAMS_STATUS_TABLE_ERROR 0x0F
+#define I2O_PARAMS_STATUS_WRONG_GROUP_TYPE 0x10
+
+/* DetailedStatusCode defines for Executive, DDM, Util and Transaction error
+ * messages: Table 3-2 Detailed Status Codes.*/
+
+#define I2O_DSC_SUCCESS 0x0000
+#define I2O_DSC_BAD_KEY 0x0002
+#define I2O_DSC_TCL_ERROR 0x0003
+#define I2O_DSC_REPLY_BUFFER_FULL 0x0004
+#define I2O_DSC_NO_SUCH_PAGE 0x0005
+#define I2O_DSC_INSUFFICIENT_RESOURCE_SOFT 0x0006
+#define I2O_DSC_INSUFFICIENT_RESOURCE_HARD 0x0007
+#define I2O_DSC_CHAIN_BUFFER_TOO_LARGE 0x0009
+#define I2O_DSC_UNSUPPORTED_FUNCTION 0x000A
+#define I2O_DSC_DEVICE_LOCKED 0x000B
+#define I2O_DSC_DEVICE_RESET 0x000C
+#define I2O_DSC_INAPPROPRIATE_FUNCTION 0x000D
+#define I2O_DSC_INVALID_INITIATOR_ADDRESS 0x000E
+#define I2O_DSC_INVALID_MESSAGE_FLAGS 0x000F
+#define I2O_DSC_INVALID_OFFSET 0x0010
+#define I2O_DSC_INVALID_PARAMETER 0x0011
+#define I2O_DSC_INVALID_REQUEST 0x0012
+#define I2O_DSC_INVALID_TARGET_ADDRESS 0x0013
+#define I2O_DSC_MESSAGE_TOO_LARGE 0x0014
+#define I2O_DSC_MESSAGE_TOO_SMALL 0x0015
+#define I2O_DSC_MISSING_PARAMETER 0x0016
+#define I2O_DSC_TIMEOUT 0x0017
+#define I2O_DSC_UNKNOWN_ERROR 0x0018
+#define I2O_DSC_UNKNOWN_FUNCTION 0x0019
+#define I2O_DSC_UNSUPPORTED_VERSION 0x001A
+#define I2O_DSC_DEVICE_BUSY 0x001B
+#define I2O_DSC_DEVICE_NOT_AVAILABLE 0x001C
+
+/* Device Claim Types */
+#define I2O_CLAIM_PRIMARY 0x01000000
+#define I2O_CLAIM_MANAGEMENT 0x02000000
+#define I2O_CLAIM_AUTHORIZED 0x03000000
+#define I2O_CLAIM_SECONDARY 0x04000000
+
+/* Message header defines for VersionOffset */
+#define I2OVER15 0x0001
+#define I2OVER20 0x0002
+/* Default is 1.5, FIXME: Need support for both 1.5 and 2.0 */
+#define I2OVERSION I2OVER15
+#define SGL_OFFSET_0 I2OVERSION
+#define SGL_OFFSET_4 (0x0040 | I2OVERSION)
+#define SGL_OFFSET_5 (0x0050 | I2OVERSION)
+#define SGL_OFFSET_6 (0x0060 | I2OVERSION)
+#define SGL_OFFSET_7 (0x0070 | I2OVERSION)
+#define SGL_OFFSET_8 (0x0080 | I2OVERSION)
+#define SGL_OFFSET_9 (0x0090 | I2OVERSION)
+#define SGL_OFFSET_10 (0x00A0 | I2OVERSION)
+#define SGL_OFFSET_12 (0x00C0 | I2OVERSION)
+
+#define TRL_OFFSET_5 (0x0050 | I2OVERSION)
+#define TRL_OFFSET_6 (0x0060 | I2OVERSION)
+
+ /* msg header defines for MsgFlags */
+#define MSG_STATIC 0x0100
+#define MSG_64BIT_CNTXT 0x0200
+#define MSG_MULTI_TRANS 0x1000
+#define MSG_FAIL 0x2000
+#define MSG_LAST 0x4000
+#define MSG_REPLY 0x8000
+
+ /* minimum size msg */
+#define THREE_WORD_MSG_SIZE 0x00030000
+#define FOUR_WORD_MSG_SIZE 0x00040000
+#define FIVE_WORD_MSG_SIZE 0x00050000
+#define SIX_WORD_MSG_SIZE 0x00060000
+#define SEVEN_WORD_MSG_SIZE 0x00070000
+#define EIGHT_WORD_MSG_SIZE 0x00080000
+#define NINE_WORD_MSG_SIZE 0x00090000
+#define TEN_WORD_MSG_SIZE 0x000A0000
+#define I2O_MESSAGE_SIZE(x) ((x)<<16)
+
+
+/* Special TID Assignments */
+
+#define ADAPTER_TID 0
+#define HOST_TID 1
+
+#define MSG_FRAME_SIZE 128
+#define NMBR_MSG_FRAMES 128
+
+#define MSG_POOL_SIZE 16384
+
+#define I2O_POST_WAIT_OK 0
+#define I2O_POST_WAIT_TIMEOUT -ETIMEDOUT
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _SCSI_I2O_H */
--- /dev/null
+/***************************************************************************
+ dpti_ioctl.h - description
+ -------------------
+ begin : Thu Sep 7 2000
+ copyright : (C) 2001 by Adaptec
+ email : deanna_bonds@adaptec.com
+
+ See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+/***************************************************************************
+ * This file is generated from osd_unix.h *
+ * *************************************************************************/
+
+#ifndef _dpti_ioctl_h
+#define _dpti_ioctl_h
+
+// IOCTL interface commands
+
+#ifndef _IOWR
+# define _IOWR(x,y,z) (((x)<<8)|y)
+#endif
+#ifndef _IOW
+# define _IOW(x,y,z) (((x)<<8)|y)
+#endif
+#ifndef _IOR
+# define _IOR(x,y,z) (((x)<<8)|y)
+#endif
+#ifndef _IO
+# define _IO(x,y) (((x)<<8)|y)
+#endif
+/* EATA PassThrough Command */
+#define EATAUSRCMD _IOWR('D',65,EATA_CP)
+/* Set Debug Level If Enabled */
+#define DPT_DEBUG _IOW('D',66,int)
+/* Get Signature Structure */
+#define DPT_SIGNATURE _IOR('D',67,dpt_sig_S)
+#if defined __bsdi__
+#define DPT_SIGNATURE_PACKED _IOR('D',67,dpt_sig_S_Packed)
+#endif
+/* Get Number Of DPT Adapters */
+#define DPT_NUMCTRLS _IOR('D',68,int)
+/* Get Adapter Info Structure */
+#define DPT_CTRLINFO _IOR('D',69,CtrlInfo)
+/* Get Statistics If Enabled */
+#define DPT_STATINFO _IO('D',70)
+/* Clear Stats If Enabled */
+#define DPT_CLRSTAT _IO('D',71)
+/* Get System Info Structure */
+#define DPT_SYSINFO _IOR('D',72,sysInfo_S)
+/* Set Timeout Value */
+#define DPT_TIMEOUT _IO('D',73)
+/* Get config Data */
+#define DPT_CONFIG _IO('D',74)
+/* Get Blink LED Code */
+#define DPT_BLINKLED _IOR('D',75,int)
+/* Get Statistical information (if available) */
+#define DPT_STATS_INFO _IOR('D',80,STATS_DATA)
+/* Clear the statistical information */
+#define DPT_STATS_CLEAR _IO('D',81)
+/* Get Performance metrics */
+#define DPT_PERF_INFO _IOR('D',82,dpt_perf_t)
+/* Send an I2O command */
+#define I2OUSRCMD _IO('D',76)
+/* Inform driver to re-acquire LCT information */
+#define I2ORESCANCMD _IO('D',77)
+/* Inform driver to reset adapter */
+#define I2ORESETCMD _IO('D',78)
+/* See if the target is mounted */
+#define DPT_TARGET_BUSY _IOR('D',79, TARGET_BUSY_T)
+
+
+ /* Structure Returned From Get Controller Info */
+
+typedef struct {
+ uCHAR state; /* Operational state */
+ uCHAR id; /* Host adapter SCSI id */
+ int vect; /* Interrupt vector number */
+ int base; /* Base I/O address */
+ int njobs; /* # of jobs sent to HA */
+ int qdepth; /* Controller queue depth. */
+ int wakebase; /* mpx wakeup base index. */
+ uLONG SGsize; /* Scatter/Gather list size. */
+ unsigned heads; /* heads for drives on cntlr. */
+ unsigned sectors; /* sectors for drives on cntlr. */
+ uCHAR do_drive32; /* Flag for Above 16 MB Ability */
+ uCHAR BusQuiet; /* SCSI Bus Quiet Flag */
+ char idPAL[4]; /* 4 Bytes Of The ID Pal */
+ uCHAR primary; /* 1 For Primary, 0 For Secondary */
+ uCHAR eataVersion; /* EATA Version */
+ uLONG cpLength; /* EATA Command Packet Length */
+ uLONG spLength; /* EATA Status Packet Length */
+ uCHAR drqNum; /* DRQ Index (0,5,6,7) */
+ uCHAR flag1; /* EATA Flags 1 (Byte 9) */
+ uCHAR flag2; /* EATA Flags 2 (Byte 30) */
+} CtrlInfo;
+
+typedef struct {
+ uSHORT length; // Remaining length of this
+ uSHORT drvrHBAnum; // Relative HBA # used by the driver
+ uLONG baseAddr; // Base I/O address
+ uSHORT blinkState; // Blink LED state (0=Not in blink LED)
+ uCHAR pciBusNum; // PCI Bus # (Optional)
+ uCHAR pciDeviceNum; // PCI Device # (Optional)
+ uSHORT hbaFlags; // Miscellaneous HBA flags
+ uSHORT Interrupt; // Interrupt set for this device.
+# if (defined(_DPT_ARC))
+ uLONG baseLength;
+ ADAPTER_OBJECT *AdapterObject;
+ LARGE_INTEGER DmaLogicalAddress;
+ PVOID DmaVirtualAddress;
+ LARGE_INTEGER ReplyLogicalAddress;
+ PVOID ReplyVirtualAddress;
+# else
+ uLONG reserved1; // Reserved for future expansion
+ uLONG reserved2; // Reserved for future expansion
+ uLONG reserved3; // Reserved for future expansion
+# endif
+} drvrHBAinfo_S;
+
+typedef struct TARGET_BUSY
+{
+ uLONG channel;
+ uLONG id;
+ uLONG lun;
+ uLONG isBusy;
+} TARGET_BUSY_T;
+
+#endif
+
--- /dev/null
+/* BSDI dptsig.h,v 1.7 1998/06/03 19:15:00 karels Exp */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef __DPTSIG_H_
+#define __DPTSIG_H_
+#ifdef _SINIX_ADDON
+#include "dpt.h"
+#endif
+/* DPT SIGNATURE SPEC AND HEADER FILE */
+/* Signature Version 1 (sorry no 'A') */
+
+/* to make sure we are talking the same size under all OS's */
+typedef unsigned char sigBYTE;
+typedef unsigned short sigWORD;
+#if (defined(_MULTI_DATAMODEL) && defined(sun) && !defined(_ILP32))
+typedef uint32_t sigLONG;
+#else
+typedef unsigned long sigLONG;
+#endif
+
+/*
+ * use sigWORDLittleEndian for:
+ * dsCapabilities
+ * dsDeviceSupp
+ * dsAdapterSupp
+ * dsApplication
+ * use sigLONGLittleEndian for:
+ * dsOS
+ * so that the sig can be standardised to Little Endian
+ */
+#if (defined(_DPT_BIG_ENDIAN))
+# define sigWORDLittleEndian(x) ((((x)&0xFF)<<8)|(((x)>>8)&0xFF))
+# define sigLONGLittleEndian(x) \
+ ((((x)&0xFF)<<24) | \
+ (((x)&0xFF00)<<8) | \
+ (((x)&0xFF0000L)>>8) | \
+ (((x)&0xFF000000L)>>24))
+#else
+# define sigWORDLittleEndian(x) (x)
+# define sigLONGLittleEndian(x) (x)
+#endif
+
+/* must make sure the structure is not word or double-word aligned */
+/* --------------------------------------------------------------- */
+/* Borland will ignore the following pragma: */
+/* Word alignment is OFF by default. If in the, IDE make */
+/* sure that Options | Compiler | Code Generation | Word Alignment */
+/* is not checked. If using BCC, do not use the -a option. */
+
+#ifndef NO_PACK
+#if defined (_DPT_AIX)
+#pragma options align=packed
+#else
+#pragma pack(1)
+#endif /* aix */
+#endif
+/* For the Macintosh */
+#if STRUCTALIGNMENTSUPPORTED
+#pragma options align=mac68k
+#endif
+
+
+/* Current Signature Version - sigBYTE dsSigVersion; */
+/* ------------------------------------------------------------------ */
+#define SIG_VERSION 1
+
+/* Processor Family - sigBYTE dsProcessorFamily; DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+/* What type of processor the file is meant to run on. */
+/* This will let us know whether to read sigWORDs as high/low or low/high. */
+#define PROC_INTEL 0x00 /* Intel 80x86 */
+#define PROC_MOTOROLA 0x01 /* Motorola 68K */
+#define PROC_MIPS4000 0x02 /* MIPS RISC 4000 */
+#define PROC_ALPHA 0x03 /* DEC Alpha */
+#define PROC_POWERPC 0x04 /* IBM Power PC */
+#define PROC_i960 0x05 /* Intel i960 */
+#define PROC_ULTRASPARC 0x06 /* SPARC processor */
+
+/* Specific Minimim Processor - sigBYTE dsProcessor; FLAG BITS */
+/* ------------------------------------------------------------------ */
+/* Different bit definitions dependent on processor_family */
+
+/* PROC_INTEL: */
+#define PROC_8086 0x01 /* Intel 8086 */
+#define PROC_286 0x02 /* Intel 80286 */
+#define PROC_386 0x04 /* Intel 80386 */
+#define PROC_486 0x08 /* Intel 80486 */
+#define PROC_PENTIUM 0x10 /* Intel 586 aka P5 aka Pentium */
+#define PROC_SEXIUM 0x20 /* Intel 686 aka P6 aka Pentium Pro or MMX */
+
+/* PROC_i960: */
+#define PROC_960RX 0x01 /* Intel 80960RC/RD */
+#define PROC_960HX 0x02 /* Intel 80960HA/HD/HT */
+
+/* PROC_MOTOROLA: */
+#define PROC_68000 0x01 /* Motorola 68000 */
+#define PROC_68010 0x02 /* Motorola 68010 */
+#define PROC_68020 0x04 /* Motorola 68020 */
+#define PROC_68030 0x08 /* Motorola 68030 */
+#define PROC_68040 0x10 /* Motorola 68040 */
+
+/* PROC_POWERPC */
+#define PROC_PPC601 0x01 /* PowerPC 601 */
+#define PROC_PPC603 0x02 /* PowerPC 603 */
+#define PROC_PPC604 0x04 /* PowerPC 604 */
+
+/* PROC_MIPS4000: */
+#define PROC_R4000 0x01 /* MIPS R4000 */
+
+/* Filetype - sigBYTE dsFiletype; DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+#define FT_EXECUTABLE 0 /* Executable Program */
+#define FT_SCRIPT 1 /* Script/Batch File??? */
+#define FT_HBADRVR 2 /* HBA Driver */
+#define FT_OTHERDRVR 3 /* Other Driver */
+#define FT_IFS 4 /* Installable Filesystem Driver */
+#define FT_ENGINE 5 /* DPT Engine */
+#define FT_COMPDRVR 6 /* Compressed Driver Disk */
+#define FT_LANGUAGE 7 /* Foreign Language file */
+#define FT_FIRMWARE 8 /* Downloadable or actual Firmware */
+#define FT_COMMMODL 9 /* Communications Module */
+#define FT_INT13 10 /* INT 13 style HBA Driver */
+#define FT_HELPFILE 11 /* Help file */
+#define FT_LOGGER 12 /* Event Logger */
+#define FT_INSTALL 13 /* An Install Program */
+#define FT_LIBRARY 14 /* Storage Manager Real-Mode Calls */
+#define FT_RESOURCE 15 /* Storage Manager Resource File */
+#define FT_MODEM_DB 16 /* Storage Manager Modem Database */
+
+/* Filetype flags - sigBYTE dsFiletypeFlags; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define FTF_DLL 0x01 /* Dynamic Link Library */
+#define FTF_NLM 0x02 /* Netware Loadable Module */
+#define FTF_OVERLAYS 0x04 /* Uses overlays */
+#define FTF_DEBUG 0x08 /* Debug version */
+#define FTF_TSR 0x10 /* TSR */
+#define FTF_SYS 0x20 /* DOS Loadable driver */
+#define FTF_PROTECTED 0x40 /* Runs in protected mode */
+#define FTF_APP_SPEC 0x80 /* Application Specific */
+#define FTF_ROM (FTF_SYS|FTF_TSR) /* Special Case */
+
+/* OEM - sigBYTE dsOEM; DISTINCT VALUES */
+/* ------------------------------------------------------------------ */
+#define OEM_DPT 0 /* DPT */
+#define OEM_ATT 1 /* ATT */
+#define OEM_NEC 2 /* NEC */
+#define OEM_ALPHA 3 /* Alphatronix */
+#define OEM_AST 4 /* AST */
+#define OEM_OLIVETTI 5 /* Olivetti */
+#define OEM_SNI 6 /* Siemens/Nixdorf */
+#define OEM_SUN 7 /* SUN Microsystems */
+
+/* Operating System - sigLONG dsOS; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define OS_DOS 0x00000001 /* PC/MS-DOS */
+#define OS_WINDOWS 0x00000002 /* Microsoft Windows 3.x */
+#define OS_WINDOWS_NT 0x00000004 /* Microsoft Windows NT */
+#define OS_OS2M 0x00000008 /* OS/2 1.2.x,MS 1.3.0,IBM 1.3.x - Monolithic */
+#define OS_OS2L 0x00000010 /* Microsoft OS/2 1.301 - LADDR */
+#define OS_OS22x 0x00000020 /* IBM OS/2 2.x */
+#define OS_NW286 0x00000040 /* Novell NetWare 286 */
+#define OS_NW386 0x00000080 /* Novell NetWare 386 */
+#define OS_GEN_UNIX 0x00000100 /* Generic Unix */
+#define OS_SCO_UNIX 0x00000200 /* SCO Unix */
+#define OS_ATT_UNIX 0x00000400 /* ATT Unix */
+#define OS_UNIXWARE 0x00000800 /* USL Unix */
+#define OS_INT_UNIX 0x00001000 /* Interactive Unix */
+#define OS_SOLARIS 0x00002000 /* SunSoft Solaris */
+#define OS_QNX 0x00004000 /* QNX for Tom Moch */
+#define OS_NEXTSTEP 0x00008000 /* NeXTSTEP/OPENSTEP/MACH */
+#define OS_BANYAN 0x00010000 /* Banyan Vines */
+#define OS_OLIVETTI_UNIX 0x00020000/* Olivetti Unix */
+#define OS_MAC_OS 0x00040000 /* Mac OS */
+#define OS_WINDOWS_95 0x00080000 /* Microsoft Windows '95 */
+#define OS_NW4x 0x00100000 /* Novell Netware 4.x */
+#define OS_BSDI_UNIX 0x00200000 /* BSDi Unix BSD/OS 2.0 and up */
+#define OS_AIX_UNIX 0x00400000 /* AIX Unix */
+#define OS_FREE_BSD 0x00800000 /* FreeBSD Unix */
+#define OS_LINUX 0x01000000 /* Linux */
+#define OS_DGUX_UNIX 0x02000000 /* Data General Unix */
+#define OS_SINIX_N 0x04000000 /* SNI SINIX-N */
+#define OS_PLAN9 0x08000000 /* ATT Plan 9 */
+#define OS_TSX 0x10000000 /* SNH TSX-32 */
+
+#define OS_OTHER 0x80000000 /* Other */
+
+/* Capabilities - sigWORD dsCapabilities; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define CAP_RAID0 0x0001 /* RAID-0 */
+#define CAP_RAID1 0x0002 /* RAID-1 */
+#define CAP_RAID3 0x0004 /* RAID-3 */
+#define CAP_RAID5 0x0008 /* RAID-5 */
+#define CAP_SPAN 0x0010 /* Spanning */
+#define CAP_PASS 0x0020 /* Provides passthrough */
+#define CAP_OVERLAP 0x0040 /* Passthrough supports overlapped commands */
+#define CAP_ASPI 0x0080 /* Supports ASPI Command Requests */
+#define CAP_ABOVE16MB 0x0100 /* ISA Driver supports greater than 16MB */
+#define CAP_EXTEND 0x8000 /* Extended info appears after description */
+#ifdef SNI_MIPS
+#define CAP_CACHEMODE 0x1000 /* dpt_force_cache is set in driver */
+#endif
+
+/* Devices Supported - sigWORD dsDeviceSupp; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define DEV_DASD 0x0001 /* DASD (hard drives) */
+#define DEV_TAPE 0x0002 /* Tape drives */
+#define DEV_PRINTER 0x0004 /* Printers */
+#define DEV_PROC 0x0008 /* Processors */
+#define DEV_WORM 0x0010 /* WORM drives */
+#define DEV_CDROM 0x0020 /* CD-ROM drives */
+#define DEV_SCANNER 0x0040 /* Scanners */
+#define DEV_OPTICAL 0x0080 /* Optical Drives */
+#define DEV_JUKEBOX 0x0100 /* Jukebox */
+#define DEV_COMM 0x0200 /* Communications Devices */
+#define DEV_OTHER 0x0400 /* Other Devices */
+#define DEV_ALL 0xFFFF /* All SCSI Devices */
+
+/* Adapters Families Supported - sigWORD dsAdapterSupp; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define ADF_2001 0x0001 /* PM2001 */
+#define ADF_2012A 0x0002 /* PM2012A */
+#define ADF_PLUS_ISA 0x0004 /* PM2011,PM2021 */
+#define ADF_PLUS_EISA 0x0008 /* PM2012B,PM2022 */
+#define ADF_SC3_ISA 0x0010 /* PM2021 */
+#define ADF_SC3_EISA 0x0020 /* PM2022,PM2122, etc */
+#define ADF_SC3_PCI 0x0040 /* SmartCache III PCI */
+#define ADF_SC4_ISA 0x0080 /* SmartCache IV ISA */
+#define ADF_SC4_EISA 0x0100 /* SmartCache IV EISA */
+#define ADF_SC4_PCI 0x0200 /* SmartCache IV PCI */
+#define ADF_SC5_PCI 0x0400 /* Fifth Generation I2O products */
+/*
+ * Combinations of products
+ */
+#define ADF_ALL_2000 (ADF_2001|ADF_2012A)
+#define ADF_ALL_PLUS (ADF_PLUS_ISA|ADF_PLUS_EISA)
+#define ADF_ALL_SC3 (ADF_SC3_ISA|ADF_SC3_EISA|ADF_SC3_PCI)
+#define ADF_ALL_SC4 (ADF_SC4_ISA|ADF_SC4_EISA|ADF_SC4_PCI)
+#define ADF_ALL_SC5 (ADF_SC5_PCI)
+/* All EATA Cacheing Products */
+#define ADF_ALL_CACHE (ADF_ALL_PLUS|ADF_ALL_SC3|ADF_ALL_SC4)
+/* All EATA Bus Mastering Products */
+#define ADF_ALL_MASTER (ADF_2012A|ADF_ALL_CACHE)
+/* All EATA Adapter Products */
+#define ADF_ALL_EATA (ADF_2001|ADF_ALL_MASTER)
+#define ADF_ALL ADF_ALL_EATA
+
+/* Application - sigWORD dsApplication; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define APP_DPTMGR 0x0001 /* DPT Storage Manager */
+#define APP_ENGINE 0x0002 /* DPT Engine */
+#define APP_SYTOS 0x0004 /* Sytron Sytos Plus */
+#define APP_CHEYENNE 0x0008 /* Cheyenne ARCServe + ARCSolo */
+#define APP_MSCDEX 0x0010 /* Microsoft CD-ROM extensions */
+#define APP_NOVABACK 0x0020 /* NovaStor Novaback */
+#define APP_AIM 0x0040 /* Archive Information Manager */
+
+/* Requirements - sigBYTE dsRequirements; FLAG BITS */
+/* ------------------------------------------------------------------ */
+#define REQ_SMARTROM 0x01 /* Requires SmartROM to be present */
+#define REQ_DPTDDL 0x02 /* Requires DPTDDL.SYS to be loaded */
+#define REQ_HBA_DRIVER 0x04 /* Requires an HBA driver to be loaded */
+#define REQ_ASPI_TRAN 0x08 /* Requires an ASPI Transport Modules */
+#define REQ_ENGINE 0x10 /* Requires a DPT Engine to be loaded */
+#define REQ_COMM_ENG 0x20 /* Requires a DPT Communications Engine */
+
+/*
+ * You may adjust dsDescription_size with an override to a value less than
+ * 50 so that the structure allocates less real space.
+ */
+#if (!defined(dsDescription_size))
+# define dsDescription_size 50
+#endif
+
+typedef struct dpt_sig {
+ char dsSignature[6]; /* ALWAYS "dPtSiG" */
+ sigBYTE dsSigVersion; /* signature version (currently 1) */
+ sigBYTE dsProcessorFamily; /* what type of processor */
+ sigBYTE dsProcessor; /* precise processor */
+ sigBYTE dsFiletype; /* type of file */
+ sigBYTE dsFiletypeFlags; /* flags to specify load type, etc. */
+ sigBYTE dsOEM; /* OEM file was created for */
+ sigLONG dsOS; /* which Operating systems */
+ sigWORD dsCapabilities; /* RAID levels, etc. */
+ sigWORD dsDeviceSupp; /* Types of SCSI devices supported */
+ sigWORD dsAdapterSupp; /* DPT adapter families supported */
+ sigWORD dsApplication; /* applications file is for */
+ sigBYTE dsRequirements; /* Other driver dependencies */
+ sigBYTE dsVersion; /* 1 */
+ sigBYTE dsRevision; /* 'J' */
+ sigBYTE dsSubRevision; /* '9' ' ' if N/A */
+ sigBYTE dsMonth; /* creation month */
+ sigBYTE dsDay; /* creation day */
+ sigBYTE dsYear; /* creation year since 1980 (1993=13) */
+ /* description (NULL terminated) */
+ char dsDescription[dsDescription_size];
+} dpt_sig_S;
+/* 32 bytes minimum - with no description. Put NULL at description[0] */
+/* 81 bytes maximum - with 49 character description plus NULL. */
+
+/* This line added at Roycroft's request */
+/* Microsoft's NT compiler gets confused if you do a pack and don't */
+/* restore it. */
+
+#ifndef NO_UNPACK
+#if defined (_DPT_AIX)
+#pragma options align=reset
+#elif defined (UNPACK_FOUR)
+#pragma pack(4)
+#else
+#pragma pack()
+#endif /* aix */
+#endif
+/* For the Macintosh */
+#if STRUCTALIGNMENTSUPPORTED
+#pragma options align=reset
+#endif
+
+#endif
--- /dev/null
+/* BSDI osd_defs.h,v 1.4 1998/06/03 19:14:58 karels Exp */
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef _OSD_DEFS_H
+#define _OSD_DEFS_H
+
+/*File - OSD_DEFS.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ * This file contains the OS dependent defines. This file is included
+ *in osd_util.h and provides the OS specific defines for that file.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ * 140 Candace Dr.
+ * Maitland, Fl. 32751 USA
+ * Phone: (407) 830-5522 Fax: (407) 260-5366
+ * All Rights Reserved
+ *
+ *Author: Doug Anderson
+ *Date: 1/31/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+ /* Define the operating system */
+#if (defined(__linux__))
+# define _DPT_LINUX
+#elif (defined(__bsdi__))
+# define _DPT_BSDI
+#elif (defined(__FreeBSD__))
+# define _DPT_FREE_BSD
+#else
+# define _DPT_SCO
+#endif
+
+#if defined (ZIL_CURSES)
+#define _DPT_CURSES
+#else
+#define _DPT_MOTIF
+#endif
+
+ /* Redefine 'far' to nothing - no far pointer type required in UNIX */
+#define far
+
+ /* Define the mutually exclusive semaphore type */
+#define SEMAPHORE_T unsigned int *
+ /* Define a handle to a DLL */
+#define DLL_HANDLE_T unsigned int *
+
+#endif
--- /dev/null
+/* BSDI osd_util.h,v 1.8 1998/06/03 19:14:58 karels Exp */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef __OSD_UTIL_H
+#define __OSD_UTIL_H
+
+/*File - OSD_UTIL.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ * This file contains defines and function prototypes that are
+ *operating system dependent. The resources defined in this file
+ *are not specific to any particular application.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ * 140 Candace Dr.
+ * Maitland, Fl. 32751 USA
+ * Phone: (407) 830-5522 Fax: (407) 260-5366
+ * All Rights Reserved
+ *
+ *Author: Doug Anderson
+ *Date: 1/7/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Definitions - Defines & Constants ----------------------------------------- */
+
+/*----------------------------- */
+/* Operating system selections: */
+/*----------------------------- */
+
+/*#define _DPT_MSDOS */
+/*#define _DPT_WIN_3X */
+/*#define _DPT_WIN_4X */
+/*#define _DPT_WIN_NT */
+/*#define _DPT_NETWARE */
+/*#define _DPT_OS2 */
+/*#define _DPT_SCO */
+/*#define _DPT_UNIXWARE */
+/*#define _DPT_SOLARIS */
+/*#define _DPT_NEXTSTEP */
+/*#define _DPT_BANYAN */
+
+/*-------------------------------- */
+/* Include the OS specific defines */
+/*-------------------------------- */
+
+/*#define OS_SELECTION From Above List */
+/*#define SEMAPHORE_T ??? */
+/*#define DLL_HANDLE_T ??? */
+
+#if (defined(KERNEL) && (defined(__FreeBSD__) || defined(__bsdi__)))
+# include "i386/isa/dpt_osd_defs.h"
+#else
+# include "osd_defs.h"
+#endif
+
+#ifndef DPT_UNALIGNED
+ #define DPT_UNALIGNED
+#endif
+
+#ifndef DPT_EXPORT
+ #define DPT_EXPORT
+#endif
+
+#ifndef DPT_IMPORT
+ #define DPT_IMPORT
+#endif
+
+#ifndef DPT_RUNTIME_IMPORT
+ #define DPT_RUNTIME_IMPORT DPT_IMPORT
+#endif
+
+/*--------------------- */
+/* OS dependent defines */
+/*--------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_WIN_3X)
+ #define _DPT_16_BIT
+#else
+ #define _DPT_32_BIT
+#endif
+
+#if defined (_DPT_SCO) || defined (_DPT_UNIXWARE) || defined (_DPT_SOLARIS) || defined (_DPT_AIX) || defined (SNI_MIPS) || defined (_DPT_BSDI) || defined (_DPT_FREE_BSD) || defined(_DPT_LINUX)
+ #define _DPT_UNIX
+#endif
+
+#if defined (_DPT_WIN_3x) || defined (_DPT_WIN_4X) || defined (_DPT_WIN_NT) \
+ || defined (_DPT_OS2)
+ #define _DPT_DLL_SUPPORT
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X) && !defined (_DPT_NETWARE)
+ #define _DPT_PREEMPTIVE
+#endif
+
+#if !defined (_DPT_MSDOS) && !defined (_DPT_WIN_3X)
+ #define _DPT_MULTI_THREADED
+#endif
+
+#if !defined (_DPT_MSDOS)
+ #define _DPT_MULTI_TASKING
+#endif
+
+ /* These exist for platforms that */
+ /* chunk when accessing mis-aligned */
+ /* data */
+#if defined (SNI_MIPS) || defined (_DPT_SOLARIS)
+ #if defined (_DPT_BIG_ENDIAN)
+ #if !defined (_DPT_STRICT_ALIGN)
+ #define _DPT_STRICT_ALIGN
+ #endif
+ #endif
+#endif
+
+ /* Determine if in C or C++ mode */
+#ifdef __cplusplus
+ #define _DPT_CPP
+#else
+ #define _DPT_C
+#endif
+
+/*-------------------------------------------------------------------*/
+/* Under Solaris the compiler refuses to accept code like: */
+/* { {"DPT"}, 0, NULL .... }, */
+/* and complains about the {"DPT"} part by saying "cannot use { } */
+/* to initialize char*". */
+/* */
+/* By defining these ugly macros we can get around this and also */
+/* not have to copy and #ifdef large sections of code. I know that */
+/* these macros are *really* ugly, but they should help reduce */
+/* maintenance in the long run. */
+/* */
+/*-------------------------------------------------------------------*/
+#if !defined (DPTSQO)
+ #if defined (_DPT_SOLARIS)
+ #define DPTSQO
+ #define DPTSQC
+ #else
+ #define DPTSQO {
+ #define DPTSQC }
+ #endif /* solaris */
+#endif /* DPTSQO */
+
+
+/*---------------------- */
+/* OS dependent typedefs */
+/*---------------------- */
+
+#if defined (_DPT_MSDOS) || defined (_DPT_SCO)
+ #define BYTE unsigned char
+ #define WORD unsigned short
+#endif
+
+#ifndef _DPT_TYPEDEFS
+ #define _DPT_TYPEDEFS
+ typedef unsigned char uCHAR;
+ typedef unsigned short uSHORT;
+ typedef unsigned int uINT;
+ typedef unsigned long uLONG;
+
+ typedef union {
+ uCHAR u8[4];
+ uSHORT u16[2];
+ uLONG u32;
+ } access_U;
+#endif
+
+#if !defined (NULL)
+ #define NULL 0
+#endif
+
+
+/*Prototypes - function ----------------------------------------------------- */
+
+#ifdef __cplusplus
+ extern "C" { /* Declare all these functions as "C" functions */
+#endif
+
+/*------------------------ */
+/* Byte reversal functions */
+/*------------------------ */
+
+ /* Reverses the byte ordering of a 2 byte variable */
+#if (!defined(osdSwap2))
+ uSHORT osdSwap2(DPT_UNALIGNED uSHORT *);
+#endif // !osdSwap2
+
+ /* Reverses the byte ordering of a 4 byte variable and shifts left 8 bits */
+#if (!defined(osdSwap3))
+ uLONG osdSwap3(DPT_UNALIGNED uLONG *);
+#endif // !osdSwap3
+
+
+#ifdef _DPT_NETWARE
+ #include "novpass.h" /* For DPT_Bswapl() prototype */
+ /* Inline the byte swap */
+ #ifdef __cplusplus
+ inline uLONG osdSwap4(uLONG *inLong) {
+ return *inLong = DPT_Bswapl(*inLong);
+ }
+ #else
+ #define osdSwap4(inLong) DPT_Bswapl(inLong)
+ #endif // cplusplus
+#else
+ /* Reverses the byte ordering of a 4 byte variable */
+# if (!defined(osdSwap4))
+ uLONG osdSwap4(DPT_UNALIGNED uLONG *);
+# endif // !osdSwap4
+
+ /* The following functions ALWAYS swap regardless of the *
+ * presence of DPT_BIG_ENDIAN */
+
+ uSHORT trueSwap2(DPT_UNALIGNED uSHORT *);
+ uLONG trueSwap4(DPT_UNALIGNED uLONG *);
+
+#endif // netware
+
+
+/*-------------------------------------*
+ * Network order swap functions *
+ * *
+ * These functions/macros will be used *
+ * by the structure insert()/extract() *
+ * functions. *
+ *
+ * We will enclose all structure *
+ * portability modifications inside *
+ * #ifdefs. When we are ready, we *
+ * will #define DPT_PORTABLE to begin *
+ * using the modifications. *
+ *-------------------------------------*/
+uLONG netSwap4(uLONG val);
+
+#if defined (_DPT_BIG_ENDIAN)
+
+// for big-endian we need to swap
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (((x) >> 8) | ((x) << 8))
+#endif // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) netSwap4((x))
+#endif // NET_SWAP_4
+
+#else
+
+// for little-endian we don't need to do anything
+
+#ifndef NET_SWAP_2
+#define NET_SWAP_2(x) (x)
+#endif // NET_SWAP_2
+
+#ifndef NET_SWAP_4
+#define NET_SWAP_4(x) (x)
+#endif // NET_SWAP_4
+
+#endif // big endian
+
+
+
+/*----------------------------------- */
+/* Run-time loadable module functions */
+/*----------------------------------- */
+
+ /* Loads the specified run-time loadable DLL */
+DLL_HANDLE_T osdLoadModule(uCHAR *);
+ /* Unloads the specified run-time loadable DLL */
+uSHORT osdUnloadModule(DLL_HANDLE_T);
+ /* Returns a pointer to a function inside a run-time loadable DLL */
+void * osdGetFnAddr(DLL_HANDLE_T,uCHAR *);
+
+/*--------------------------------------- */
+/* Mutually exclusive semaphore functions */
+/*--------------------------------------- */
+
+ /* Create a named semaphore */
+SEMAPHORE_T osdCreateNamedSemaphore(char *);
+ /* Create a mutually exlusive semaphore */
+SEMAPHORE_T osdCreateSemaphore(void);
+ /* create an event semaphore */
+SEMAPHORE_T osdCreateEventSemaphore(void);
+ /* create a named event semaphore */
+SEMAPHORE_T osdCreateNamedEventSemaphore(char *);
+
+ /* Destroy the specified mutually exclusive semaphore object */
+uSHORT osdDestroySemaphore(SEMAPHORE_T);
+ /* Request access to the specified mutually exclusive semaphore */
+uLONG osdRequestSemaphore(SEMAPHORE_T,uLONG);
+ /* Release access to the specified mutually exclusive semaphore */
+uSHORT osdReleaseSemaphore(SEMAPHORE_T);
+ /* wait for a event to happen */
+uLONG osdWaitForEventSemaphore(SEMAPHORE_T, uLONG);
+ /* signal an event */
+uLONG osdSignalEventSemaphore(SEMAPHORE_T);
+ /* reset the event */
+uLONG osdResetEventSemaphore(SEMAPHORE_T);
+
+/*----------------- */
+/* Thread functions */
+/*----------------- */
+
+ /* Releases control to the task switcher in non-preemptive */
+ /* multitasking operating systems. */
+void osdSwitchThreads(void);
+
+ /* Starts a thread function */
+uLONG osdStartThread(void *,void *);
+
+/* what is my thread id */
+uLONG osdGetThreadID(void);
+
+/* wakes up the specifed thread */
+void osdWakeThread(uLONG);
+
+/* osd sleep for x miliseconds */
+void osdSleep(uLONG);
+
+#define DPT_THREAD_PRIORITY_LOWEST 0x00
+#define DPT_THREAD_PRIORITY_NORMAL 0x01
+#define DPT_THREAD_PRIORITY_HIGHEST 0x02
+
+uCHAR osdSetThreadPriority(uLONG tid, uCHAR priority);
+
+#ifdef __cplusplus
+ } /* end the xtern "C" declaration */
+#endif
+
+#endif /* osd_util_h */
--- /dev/null
+/* BSDI sys_info.h,v 1.6 1998/06/03 19:14:59 karels Exp */
+
+/*
+ * Copyright (c) 1996-1999 Distributed Processing Technology Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source form, with or without modification, are
+ * permitted provided that redistributions of source code must retain the
+ * above copyright notice, this list of conditions and the following disclaimer.
+ *
+ * This software is provided `as is' by Distributed Processing Technology and
+ * any express or implied warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose,
+ * are disclaimed. In no event shall Distributed Processing Technology be
+ * liable for any direct, indirect, incidental, special, exemplary or
+ * consequential damages (including, but not limited to, procurement of
+ * substitute goods or services; loss of use, data, or profits; or business
+ * interruptions) however caused and on any theory of liability, whether in
+ * contract, strict liability, or tort (including negligence or otherwise)
+ * arising in any way out of the use of this driver software, even if advised
+ * of the possibility of such damage.
+ *
+ */
+
+#ifndef __SYS_INFO_H
+#define __SYS_INFO_H
+
+/*File - SYS_INFO.H
+ ****************************************************************************
+ *
+ *Description:
+ *
+ * This file contains structure definitions for the OS dependent
+ *layer system information buffers.
+ *
+ *Copyright Distributed Processing Technology, Corp.
+ * 140 Candace Dr.
+ * Maitland, Fl. 32751 USA
+ * Phone: (407) 830-5522 Fax: (407) 260-5366
+ * All Rights Reserved
+ *
+ *Author: Don Kemper
+ *Date: 5/10/94
+ *
+ *Editors:
+ *
+ *Remarks:
+ *
+ *
+ *****************************************************************************/
+
+
+/*Include Files ------------------------------------------------------------- */
+
+#include "osd_util.h"
+
+#ifndef NO_PACK
+#if defined (_DPT_AIX)
+#pragma options align=packed
+#else
+#pragma pack(1)
+#endif /* aix */
+#endif // no unpack
+
+
+/*struct - driveParam_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the drive parameters seen during
+ *booting.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ struct driveParam_S {
+#else
+ typedef struct {
+#endif
+
+ uSHORT cylinders; /* Upto 1024 */
+ uCHAR heads; /* Upto 255 */
+ uCHAR sectors; /* Upto 63 */
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } driveParam_S;
+#endif
+/*driveParam_S - end */
+
+
+/*struct - sysInfo_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the command system information that
+ *should be returned by every OS dependent layer.
+ *
+ *---------------------------------------------------------------------------*/
+
+/*flags - bit definitions */
+#define SI_CMOS_Valid 0x0001
+#define SI_NumDrivesValid 0x0002
+#define SI_ProcessorValid 0x0004
+#define SI_MemorySizeValid 0x0008
+#define SI_DriveParamsValid 0x0010
+#define SI_SmartROMverValid 0x0020
+#define SI_OSversionValid 0x0040
+#define SI_OSspecificValid 0x0080 /* 1 if OS structure returned */
+#define SI_BusTypeValid 0x0100
+
+#define SI_ALL_VALID 0x0FFF /* All Std SysInfo is valid */
+#define SI_NO_SmartROM 0x8000
+
+/*busType - definitions */
+#define SI_ISA_BUS 0x00
+#define SI_MCA_BUS 0x01
+#define SI_EISA_BUS 0x02
+#define SI_PCI_BUS 0x04
+
+#ifdef __cplusplus
+ struct sysInfo_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR drive0CMOS; /* CMOS Drive 0 Type */
+ uCHAR drive1CMOS; /* CMOS Drive 1 Type */
+ uCHAR numDrives; /* 0040:0075 contents */
+ uCHAR processorFamily; /* Same as DPTSIG's definition */
+ uCHAR processorType; /* Same as DPTSIG's definition */
+ uCHAR smartROMMajorVersion;
+ uCHAR smartROMMinorVersion; /* SmartROM version */
+ uCHAR smartROMRevision;
+ uSHORT flags; /* See bit definitions above */
+ uSHORT conventionalMemSize; /* in KB */
+ uLONG extendedMemSize; /* in KB */
+ uLONG osType; /* Same as DPTSIG's definition */
+ uCHAR osMajorVersion;
+ uCHAR osMinorVersion; /* The OS version */
+ uCHAR osRevision;
+#ifdef _SINIX_ADDON
+ uCHAR busType; /* See defininitions above */
+ uSHORT osSubRevision;
+ uCHAR pad[2]; /* For alignment */
+#else
+ uCHAR osSubRevision;
+ uCHAR busType; /* See defininitions above */
+ uCHAR pad[3]; /* For alignment */
+#endif
+ driveParam_S drives[16]; /* SmartROM Logical Drives */
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } sysInfo_S;
+#endif
+/*sysInfo_S - end */
+
+
+/*struct - DOS_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the system information specific to a
+ *DOS workstation.
+ *
+ *---------------------------------------------------------------------------*/
+
+/*flags - bit definitions */
+#define DI_DOS_HIGH 0x01 /* DOS is loaded high */
+#define DI_DPMI_VALID 0x02 /* DPMI version is valid */
+
+#ifdef __cplusplus
+ struct DOS_Info_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR flags; /* See bit definitions above */
+ uSHORT driverLocation; /* SmartROM BIOS address */
+ uSHORT DOS_version;
+ uSHORT DPMI_version;
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } DOS_Info_S;
+#endif
+/*DOS_Info_S - end */
+
+
+/*struct - Netware_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the system information specific to a
+ *Netware machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ struct Netware_Info_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR driverName[13]; /* ie PM12NW31.DSK */
+ uCHAR serverName[48];
+ uCHAR netwareVersion; /* The Netware OS version */
+ uCHAR netwareSubVersion;
+ uCHAR netwareRevision;
+ uSHORT maxConnections; /* Probably 250 or 1000 */
+ uSHORT connectionsInUse;
+ uSHORT maxVolumes;
+ uCHAR unused;
+ uCHAR SFTlevel;
+ uCHAR TTSlevel;
+
+ uCHAR clibMajorVersion; /* The CLIB.NLM version */
+ uCHAR clibMinorVersion;
+ uCHAR clibRevision;
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } Netware_Info_S;
+#endif
+/*Netware_Info_S - end */
+
+
+/*struct - OS2_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the system information specific to an
+ *OS/2 machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ struct OS2_Info_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR something;
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } OS2_Info_S;
+#endif
+/*OS2_Info_S - end */
+
+
+/*struct - WinNT_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the system information specific to a
+ *Windows NT machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ struct WinNT_Info_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR something;
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } WinNT_Info_S;
+#endif
+/*WinNT_Info_S - end */
+
+
+/*struct - SCO_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the system information specific to an
+ *SCO UNIX machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ struct SCO_Info_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR something;
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } SCO_Info_S;
+#endif
+/*SCO_Info_S - end */
+
+
+/*struct - USL_Info_S - start
+ *===========================================================================
+ *
+ *Description:
+ *
+ * This structure defines the system information specific to a
+ *USL UNIX machine.
+ *
+ *---------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+ struct USL_Info_S {
+#else
+ typedef struct {
+#endif
+
+ uCHAR something;
+
+#ifdef __cplusplus
+
+//---------- Portability Additions ----------- in sp_sinfo.cpp
+#ifdef DPT_PORTABLE
+ uSHORT netInsert(dptBuffer_S *buffer);
+ uSHORT netExtract(dptBuffer_S *buffer);
+#endif // DPT PORTABLE
+//--------------------------------------------
+
+ };
+#else
+ } USL_Info_S;
+#endif
+/*USL_Info_S - end */
+
+
+ /* Restore default structure packing */
+#ifndef NO_UNPACK
+#if defined (_DPT_AIX)
+#pragma options align=reset
+#elif defined (UNPACK_FOUR)
+#pragma pack(4)
+#else
+#pragma pack()
+#endif /* aix */
+#endif // no unpack
+
+#endif // __SYS_INFO_H
+
--- /dev/null
+/***************************************************************************
+ dpti.c - description
+ -------------------
+ begin : Thu Sep 7 2000
+ copyright : (C) 2000 by Adaptec
+ email : deanna_bonds@adaptec.com
+
+ July 30, 2001 First version being submitted
+ for inclusion in the kernel. V2.4
+
+ See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+//#define DEBUG 1
+//#define UARTDELAY 1
+
+// On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
+// high pages. Keep the macro around because of the broken unmerged ia64 tree
+
+#define ADDR32 (0)
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
+MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
+
+////////////////////////////////////////////////////////////////
+
+#include <linux/ioctl.h> /* For SCSI-Passthrough */
+#include <asm/uaccess.h>
+
+#include <linux/stat.h>
+#include <linux/slab.h> /* for kmalloc() */
+#include <linux/config.h> /* for CONFIG_PCI */
+#include <linux/pci.h> /* for PCI support */
+#include <linux/proc_fs.h>
+#include <linux/blk.h>
+#include <linux/delay.h> /* for udelay */
+#include <linux/tqueue.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h> /* for printk */
+#include <linux/sched.h>
+#include <linux/reboot.h>
+#include <linux/smp_lock.h>
+
+#include <linux/timer.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/stat.h>
+
+#include <asm/processor.h> /* for boot_cpu_data */
+#include <asm/pgtable.h>
+#include <asm/io.h> /* for virt_to_bus, etc. */
+
+#include "scsi.h"
+#include "hosts.h"
+#include "sd.h"
+
+#include "dpt/dptsig.h"
+#include "dpti.h"
+
+/*============================================================================
+ * Create a binary signature - this is read by dptsig
+ * Needed for our management apps
+ *============================================================================
+ */
+static dpt_sig_S DPTI_sig = {
+ {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
+#ifdef __i386__
+ PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
+#elif defined __ia64__
+ PROC_INTEL, PROC_IA64,
+#elif define __sparc__
+ PROC_ULTRASPARC,
+#elif defined(__alpha__)
+ PROC_ALPHA ,
+#else
+ (-1),
+#endif
+ FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
+ ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
+ DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
+};
+
+
+
+
+/*============================================================================
+ * Globals
+ *============================================================================
+ */
+
+DECLARE_MUTEX(adpt_configuration_lock);
+
+static struct i2o_sys_tbl *sys_tbl = NULL;
+static int sys_tbl_ind = 0;
+static int sys_tbl_len = 0;
+
+static adpt_hba* hbas[DPTI_MAX_HBA];
+static adpt_hba* hba_chain = NULL;
+static int hba_count = 0;
+
+// Debug flags to be put into the HBA flags field when initialized
+// Make sure to enable DEBUG_PRINT for these flags to work
+static unsigned long DebugFlags = HBA_FLAGS_DBG_SCAN_B | HBA_FLAGS_DBG_FLAGS_MASK;
+
+static struct file_operations adpt_fops = {
+ ioctl: adpt_ioctl,
+ open: adpt_open,
+ release: adpt_close
+};
+
+#ifdef REBOOT_NOTIFIER
+static struct notifier_block adpt_reboot_notifier =
+{
+ adpt_reboot_event,
+ NULL,
+ 0
+};
+#endif
+
+/* Structures and definitions for synchronous message posting.
+ * See adpt_i2o_post_wait() for description
+ * */
+struct adpt_i2o_post_wait_data
+{
+ int status;
+ u32 id;
+ adpt_wait_queue_head_t *wq;
+ struct adpt_i2o_post_wait_data *next;
+};
+
+static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
+static u32 adpt_post_wait_id = 0;
+static spinlock_t adpt_post_wait_lock = SPIN_LOCK_UNLOCKED;
+
+
+/*============================================================================
+ * Functions
+ *============================================================================
+ */
+
+static u8 adpt_read_blink_led(adpt_hba* host)
+{
+ if(host->FwDebugBLEDflag_P != 0) {
+ if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
+ return readb(host->FwDebugBLEDvalue_P);
+ }
+ }
+ return 0;
+}
+
+/*============================================================================
+ * Scsi host template interface functions
+ *============================================================================
+ */
+
+static int adpt_detect(Scsi_Host_Template* sht)
+{
+ struct pci_dev *pDev = NULL;
+ adpt_hba* pHba;
+
+ adpt_init();
+ sht->use_new_eh_code = 1;
+
+ PINFO("Detecting Adaptec I2O RAID controllers...\n");
+
+ /* search for all Adatpec I2O RAID cards */
+ while ((pDev = pci_find_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
+ if(pDev->device == PCI_DPT_DEVICE_ID ||
+ pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
+ if(adpt_install_hba(sht, pDev) ){
+ PERROR("Could not Init an I2O RAID device\n");
+ PERROR("Will not try to detect others.\n");
+ return hba_count-1;
+ }
+ }
+ }
+
+ /* In INIT state, Activate IOPs */
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ // Activate does get status , init outbound, and get hrt
+ if (adpt_i2o_activate_hba(pHba) < 0) {
+ adpt_i2o_delete_hba(pHba);
+ }
+ }
+
+
+ /* Active IOPs in HOLD state */
+
+rebuild_sys_tab:
+ if (hba_chain == NULL)
+ return 0;
+
+ /*
+ * If build_sys_table fails, we kill everything and bail
+ * as we can't init the IOPs w/o a system table
+ */
+ if (adpt_i2o_build_sys_table() < 0) {
+ adpt_i2o_sys_shutdown();
+ return 0;
+ }
+
+ PDEBUG("HBA's in HOLD state\n");
+
+ /* If IOP don't get online, we need to rebuild the System table */
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ if (adpt_i2o_online_hba(pHba) < 0) {
+ adpt_i2o_delete_hba(pHba);
+ goto rebuild_sys_tab;
+ }
+ }
+
+ /* Active IOPs now in OPERATIONAL state */
+ PDEBUG("HBA's in OPERATIONAL state\n");
+
+ printk(KERN_INFO"dpti: If you have a lot of devices this could take a few minutes.\n");
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
+ if (adpt_i2o_lct_get(pHba) < 0){
+ adpt_i2o_delete_hba(pHba);
+ continue;
+ }
+
+ if (adpt_i2o_parse_lct(pHba) < 0){
+ adpt_i2o_delete_hba(pHba);
+ continue;
+ }
+ adpt_inquiry(pHba);
+ }
+
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ if( adpt_scsi_register(pHba,sht) < 0){
+ adpt_i2o_delete_hba(pHba);
+ continue;
+ }
+ pHba->initialized = TRUE;
+ pHba->state &= ~DPTI_STATE_RESET;
+ }
+
+ // Register our control device node
+ // nodes will need to be created in /dev to access this
+ // the nodes can not be created from within the driver
+ if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
+ adpt_i2o_sys_shutdown();
+ return 0;
+ }
+ return hba_count;
+}
+
+
+/*
+ * scsi_unregister will be called AFTER we return.
+ */
+static int adpt_release(struct Scsi_Host *host)
+{
+ adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
+// adpt_i2o_quiesce_hba(pHba);
+ adpt_i2o_delete_hba(pHba);
+ return 0;
+}
+
+
+static void adpt_inquiry(adpt_hba* pHba)
+{
+ u32 msg[14];
+ u32 *mptr;
+ u32 *lenptr;
+ int direction;
+ int scsidir;
+ u32 len;
+ u32 reqlen;
+ u8* buf;
+ u8 scb[16];
+ s32 rcode;
+
+ memset(msg, 0, sizeof(msg));
+ buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+ if(!buf){
+ printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
+ return;
+ }
+ memset((void*)buf, 0, 36);
+
+ len = 36;
+ direction = 0x00000000;
+ scsidir =0x40000000; // DATA IN (iop<--dev)
+
+ reqlen = 14; // SINGLE SGE
+ /* Stick the headers on */
+ msg[0] = reqlen<<16 | SGL_OFFSET_12;
+ msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
+ msg[2] = 0;
+ msg[3] = 0;
+ // Adaptec/DPT Private stuff
+ msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
+ msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
+ /* Direction, disconnect ok | sense data | simple queue , CDBLen */
+ // I2O_SCB_FLAG_ENABLE_DISCONNECT |
+ // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG |
+ // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
+ msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
+
+ mptr=msg+7;
+
+ memset(scb, 0, sizeof(scb));
+ // Write SCSI command into the message - always 16 byte block
+ scb[0] = INQUIRY;
+ scb[1] = 0;
+ scb[2] = 0;
+ scb[3] = 0;
+ scb[4] = 36;
+ scb[5] = 0;
+ // Don't care about the rest of scb
+
+ memcpy(mptr, scb, sizeof(scb));
+ mptr+=4;
+ lenptr=mptr++; /* Remember me - fill in when we know */
+
+ /* Now fill in the SGList and command */
+ *lenptr = len;
+ *mptr++ = 0xD0000000|direction|len;
+ *mptr++ = virt_to_bus(buf);
+
+ // Send it on it's way
+ rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
+ if (rcode != 0) {
+ sprintf(pHba->detail, "Adaptec I2O RAID");
+ printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
+ } else {
+ memset(pHba->detail, 0, sizeof(pHba->detail));
+ memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
+ memcpy(&(pHba->detail[16]), " Model: ", 8);
+ memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
+ memcpy(&(pHba->detail[40]), " FW: ", 4);
+ memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
+ pHba->detail[48] = '\0'; /* precautionary */
+ }
+ kfree(buf);
+ adpt_i2o_status_get(pHba);
+ return ;
+}
+
+
+static void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist)
+{
+ Scsi_Device *device; /* scsi layer per device information */
+ adpt_hba* pHba;
+
+ pHba = (adpt_hba *) host->hostdata[0];
+
+ for (device = devicelist; device != NULL; device = device->next) {
+ if (device->host != host) {
+ continue;
+ }
+ if (host->can_queue) {
+ device->queue_depth = host->can_queue - 1;
+ } else {
+ device->queue_depth = 1;
+ }
+ }
+}
+
+static int adpt_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
+{
+ adpt_hba* pHba = NULL;
+ struct adpt_device* pDev = NULL; /* dpt per device information */
+ ulong timeout = jiffies + (TMOUT_SCSI*HZ);
+
+ cmd->scsi_done = done;
+ /*
+ * SCSI REQUEST_SENSE commands will be executed automatically by the
+ * Host Adapter for any errors, so they should not be executed
+ * explicitly unless the Sense Data is zero indicating that no error
+ * occurred.
+ */
+
+ if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
+ cmd->result = (DID_OK << 16);
+ cmd->scsi_done(cmd);
+ return 0;
+ }
+
+ pHba = (adpt_hba*)cmd->host->hostdata[0];
+ if (!pHba) {
+ return FAILED;
+ }
+
+ rmb();
+ /*
+ * TODO: I need to block here if I am processing ioctl cmds
+ * but if the outstanding cmds all finish before the ioctl,
+ * the scsi-core will not know to start sending cmds to me again.
+ * I need to a way to restart the scsi-cores queues or should I block
+ * calling scsi_done on the outstanding cmds instead
+ * for now we don't set the IOCTL state
+ */
+ if(((pHba->state) & DPTI_STATE_IOCTL) || ((pHba->state) & DPTI_STATE_RESET)) {
+ pHba->host->last_reset = jiffies;
+ pHba->host->resetting = 1;
+ return 1;
+ }
+
+ if(cmd->eh_state != SCSI_STATE_QUEUED){
+ // If we are not doing error recovery
+ mod_timer(&cmd->eh_timeout, timeout);
+ }
+
+ // TODO if the cmd->device if offline then I may need to issue a bus rescan
+ // followed by a get_lct to see if the device is there anymore
+ if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
+ /*
+ * First command request for this device. Set up a pointer
+ * to the device structure. This should be a TEST_UNIT_READY
+ * command from scan_scsis_single.
+ */
+ if ((pDev = adpt_find_device(pHba, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun)) == NULL) {
+ // TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response
+ // with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
+ cmd->result = (DID_NO_CONNECT << 16);
+ cmd->scsi_done(cmd);
+ return 0;
+ }
+ (struct adpt_device*)(cmd->device->hostdata) = pDev;
+ }
+ pDev->pScsi_dev = cmd->device;
+
+ /*
+ * If we are being called from when the device is being reset,
+ * delay processing of the command until later.
+ */
+ if (pDev->state & DPTI_DEV_RESET ) {
+ return FAILED;
+ }
+ return adpt_scsi_to_i2o(pHba, cmd, pDev);
+}
+
+static int adpt_bios_param(Disk* disk, kdev_t dev, int geom[])
+{
+ int heads=-1;
+ int sectors=-1;
+ int cylinders=-1;
+
+ // *** First lets set the default geometry ****
+
+ // If the capacity is less than ox2000
+ if (disk->capacity < 0x2000 ) { // floppy
+ heads = 18;
+ sectors = 2;
+ }
+ // else if between 0x2000 and 0x20000
+ else if (disk->capacity < 0x20000) {
+ heads = 64;
+ sectors = 32;
+ }
+ // else if between 0x20000 and 0x40000
+ else if (disk->capacity < 0x40000) {
+ heads = 65;
+ sectors = 63;
+ }
+ // else if between 0x4000 and 0x80000
+ else if (disk->capacity < 0x80000) {
+ heads = 128;
+ sectors = 63;
+ }
+ // else if greater than 0x80000
+ else {
+ heads = 255;
+ sectors = 63;
+ }
+ cylinders = disk->capacity / (heads * sectors);
+
+ // Special case if CDROM
+ if(disk->device->type == 5) { // CDROM
+ heads = 252;
+ sectors = 63;
+ cylinders = 1111;
+ }
+
+ geom[0] = heads;
+ geom[1] = sectors;
+ geom[2] = cylinders;
+
+ PDEBUG("adpt_bios_param: exit\n");
+ return 0;
+}
+
+
+static const char *adpt_info(struct Scsi_Host *host)
+{
+ adpt_hba* pHba;
+
+ pHba = (adpt_hba *) host->hostdata[0];
+ return (char *) (pHba->detail);
+}
+
+static int adpt_proc_info(char *buffer, char **start, off_t offset,
+ int length, int hostno, int inout)
+{
+ struct adpt_device* d;
+ int id;
+ int chan;
+ int len = 0;
+ int begin = 0;
+ int pos = 0;
+ adpt_hba* pHba;
+ struct Scsi_Host *host;
+ int unit;
+
+ *start = buffer;
+ if (inout == TRUE) {
+ /*
+ * The user has done a write and wants us to take the
+ * data in the buffer and do something with it.
+ * proc_scsiwrite calls us with inout = 1
+ *
+ * Read data from buffer (writing to us) - NOT SUPPORTED
+ */
+ return -EINVAL;
+ }
+
+ /*
+ * inout = 0 means the user has done a read and wants information
+ * returned, so we write information about the cards into the buffer
+ * proc_scsiread() calls us with inout = 0
+ */
+
+ // Find HBA (host bus adapter) we are looking for
+ down(&adpt_configuration_lock);
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ if (pHba->host->host_no == hostno) {
+ break; /* found adapter */
+ }
+ }
+ up(&adpt_configuration_lock);
+ if (pHba == NULL) {
+ return 0;
+ }
+ host = pHba->host;
+
+ len = sprintf(buffer , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
+ len += sprintf(buffer+len, "%s\n", pHba->detail);
+ len += sprintf(buffer+len, "SCSI Host=scsi%d Control Node=/dev/%s irq=%d\n",
+ pHba->host->host_no, pHba->name, host->irq);
+ len += sprintf(buffer+len, "\tpost fifo size = %d\n\treply fifo size = %d\n\tsg table size = %d\n\n",
+ host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
+
+ pos = begin + len;
+
+ /* CHECKPOINT */
+ if(pos > offset + length) {
+ goto stop_output;
+ }
+ if(pos <= offset) {
+ /*
+ * If we haven't even written to where we last left
+ * off (the last time we were called), reset the
+ * beginning pointer.
+ */
+ len = 0;
+ begin = pos;
+ }
+ len += sprintf(buffer+len, "Devices:\n");
+ for(chan = 0; chan < MAX_CHANNEL; chan++) {
+ for(id = 0; id < MAX_ID; id++) {
+ d = pHba->channel[chan].device[id];
+ while(d){
+ len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
+ len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
+ pos = begin + len;
+
+
+ /* CHECKPOINT */
+ if(pos > offset + length) {
+ goto stop_output;
+ }
+ if(pos <= offset) {
+ len = 0;
+ begin = pos;
+ }
+
+ unit = d->pI2o_dev->lct_data.tid;
+ len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d) (%s)\n\n",
+ unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
+ d->pScsi_dev->online? "online":"offline");
+ pos = begin + len;
+
+ /* CHECKPOINT */
+ if(pos > offset + length) {
+ goto stop_output;
+ }
+ if(pos <= offset) {
+ len = 0;
+ begin = pos;
+ }
+
+ d = d->next_lun;
+ }
+ }
+ }
+
+ /*
+ * begin is where we last checked our position with regards to offset
+ * begin is always less than offset. len is relative to begin. It
+ * is the number of bytes written past begin
+ *
+ */
+stop_output:
+ /* stop the output and calculate the correct length */
+ *(buffer + len) = '\0';
+
+ *start = buffer + (offset - begin); /* Start of wanted data */
+ len -= (offset - begin);
+ if(len > length) {
+ len = length;
+ } else if(len < 0){
+ len = 0;
+ **start = '\0';
+ }
+ return len;
+}
+
+
+/*===========================================================================
+ * Error Handling routines
+ *===========================================================================
+ */
+
+static int adpt_abort(Scsi_Cmnd * cmd)
+{
+ adpt_hba* pHba = NULL; /* host bus adapter structure */
+ struct adpt_device* dptdevice; /* dpt per device information */
+ u32 msg[5];
+ int rcode;
+
+ if(cmd->serial_number == 0){
+ return FAILED;
+ }
+ pHba = (adpt_hba*) cmd->host->hostdata[0];
+ printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);
+ if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
+ printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
+ return FAILED;
+ }
+
+ memset(msg, 0, sizeof(msg));
+ msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
+ msg[2] = 0;
+ msg[3]= 0;
+ msg[4] = (u32)cmd;
+ if( (rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER)) != 0){
+ if(rcode == -EOPNOTSUPP ){
+ printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
+ return FAILED;
+ }
+ printk(KERN_INFO"%s: Abort cmd=%ld failed.\n",pHba->name, cmd->serial_number);
+ return FAILED;
+ }
+ printk(KERN_INFO"%s: Abort cmd=%ld complete.\n",pHba->name, cmd->serial_number);
+ return SUCCESS;
+}
+
+
+#define I2O_DEVICE_RESET 0x27
+// This is the same for BLK and SCSI devices
+// NOTE this is wrong in the i2o.h definitions
+// This is not currently supported by our adapter but we issue it anyway
+static int adpt_device_reset(Scsi_Cmnd* cmd)
+{
+ adpt_hba* pHba;
+ u32 msg[4];
+ u32 rcode;
+ int old_state;
+ struct adpt_device* d = (void*) cmd->device->hostdata;
+
+ pHba = (void*) cmd->host->hostdata[0];
+ printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
+ if (!d) {
+ printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
+ return FAILED;
+ }
+ memset(msg, 0, sizeof(msg));
+ msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
+ msg[2] = 0;
+ msg[3] = 0;
+
+ old_state = d->state;
+ d->state |= DPTI_DEV_RESET;
+ if( (rcode = adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER)) ){
+ d->state = old_state;
+ if(rcode == -EOPNOTSUPP ){
+ printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
+ return FAILED;
+ }
+ printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
+ return FAILED;
+ } else {
+ d->state = old_state;
+ printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
+ return SUCCESS;
+ }
+}
+
+
+#define I2O_HBA_BUS_RESET 0x87
+// This version of bus reset is called by the eh_error handler
+static int adpt_bus_reset(Scsi_Cmnd* cmd)
+{
+ adpt_hba* pHba;
+ u32 msg[4];
+
+ pHba = (adpt_hba*)cmd->host->hostdata[0];
+ memset(msg, 0, sizeof(msg));
+ printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->channel,pHba->channel[cmd->channel].tid );
+ msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->channel].tid);
+ msg[2] = 0;
+ msg[3] = 0;
+ if(adpt_i2o_post_wait(pHba, (void*)msg,sizeof(msg), FOREVER) ){
+ printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
+ return FAILED;
+ } else {
+ printk(KERN_WARNING"%s: Bus reset success.\n",pHba->name);
+ return SUCCESS;
+ }
+}
+
+// This version of reset is called by the eh_error_handler
+static int adpt_reset(Scsi_Cmnd* cmd)
+{
+ adpt_hba* pHba;
+ int rcode;
+ pHba = (adpt_hba*)cmd->host->hostdata[0];
+ printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->channel,pHba->channel[cmd->channel].tid );
+ rcode = adpt_hba_reset(pHba);
+ if(rcode == 0){
+ printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
+ return SUCCESS;
+ } else {
+ printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode);
+ return FAILED;
+ }
+}
+
+// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
+static int adpt_hba_reset(adpt_hba* pHba)
+{
+ int rcode;
+
+ pHba->state |= DPTI_STATE_RESET;
+
+ // Activate does get status , init outbound, and get hrt
+ if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {
+ printk(KERN_ERR "%s: Could not activate\n", pHba->name);
+ adpt_i2o_delete_hba(pHba);
+ return rcode;
+ }
+
+ if ((rcode=adpt_i2o_build_sys_table()) < 0) {
+ adpt_i2o_delete_hba(pHba);
+ return rcode;
+ }
+ PDEBUG("%s: in HOLD state\n",pHba->name);
+
+ if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
+ adpt_i2o_delete_hba(pHba);
+ return rcode;
+ }
+ PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
+
+ if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
+ adpt_i2o_delete_hba(pHba);
+ return rcode;
+ }
+
+ if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
+ adpt_i2o_delete_hba(pHba);
+ return rcode;
+ }
+ pHba->state &= ~DPTI_STATE_RESET;
+
+ adpt_fail_posted_scbs(pHba);
+ return 0; /* return success */
+}
+
+/*===========================================================================
+ *
+ *===========================================================================
+ */
+
+
+static void adpt_i2o_sys_shutdown(void)
+{
+ adpt_hba *pHba, *pNext;
+ struct adpt_i2o_post_wait_data *p1, *p2;
+
+ printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");
+ printk(KERN_INFO" This could take a few minutes if there are many devices attached\n");
+ /* Delete all IOPs from the controller chain */
+ /* They should have already been released by the
+ * scsi-core
+ */
+ for (pHba = hba_chain; pHba; pHba = pNext) {
+ pNext = pHba->next;
+ adpt_i2o_delete_hba(pHba);
+ }
+
+ /* Remove any timedout entries from the wait queue. */
+ p2 = NULL;
+// spin_lock_irqsave(&adpt_post_wait_lock, flags);
+ /* Nothing should be outstanding at this point so just
+ * free them
+ */
+ for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p2->next) {
+ kfree(p1);
+ }
+// spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+ adpt_post_wait_queue = 0;
+
+ printk(KERN_INFO "Adaptec I2O controllers down.\n");
+}
+
+/*
+ * reboot/shutdown notification.
+ *
+ * - Quiesce each IOP in the system
+ *
+ */
+
+#ifdef REBOOT_NOTIFIER
+static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
+{
+
+ if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
+ return NOTIFY_DONE;
+
+ adpt_i2o_sys_shutdown();
+
+ return NOTIFY_DONE;
+}
+#endif
+
+
+static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev)
+{
+
+ adpt_hba* pHba = NULL;
+ adpt_hba* p = NULL;
+ ulong base_addr0_phys = 0;
+ ulong base_addr1_phys = 0;
+ u32 hba_map0_area_size = 0;
+ u32 hba_map1_area_size = 0;
+ ulong base_addr_virt = 0;
+ ulong msg_addr_virt = 0;
+
+ int raptorFlag = FALSE;
+ int i;
+
+ if(pci_enable_device(pDev)) {
+ return -EINVAL;
+ }
+ pci_set_master(pDev);
+
+ base_addr0_phys = pci_resource_start(pDev,0);
+ hba_map0_area_size = pci_resource_len(pDev,0);
+
+ // Check if standard PCI card or single BAR Raptor
+ if(pDev->device == PCI_DPT_DEVICE_ID){
+ if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
+ // Raptor card with this device id needs 4M
+ hba_map0_area_size = 0x400000;
+ } else { // Not Raptor - it is a PCI card
+ if(hba_map0_area_size > 0x100000 ){
+ hba_map0_area_size = 0x100000;
+ }
+ }
+ } else {// Raptor split BAR config
+ // Use BAR1 in this configuration
+ base_addr1_phys = pci_resource_start(pDev,1);
+ hba_map1_area_size = pci_resource_len(pDev,1);
+ raptorFlag = TRUE;
+ }
+
+
+ base_addr_virt = (ulong)ioremap(base_addr0_phys,hba_map0_area_size);
+ if(base_addr_virt == 0) {
+ PERROR("dpti: adpt_config_hba: io remap failed\n");
+ return -EINVAL;
+ }
+
+ if(raptorFlag == TRUE) {
+ msg_addr_virt = (ulong)ioremap(base_addr1_phys, hba_map1_area_size );
+ if(msg_addr_virt == 0) {
+ PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
+ iounmap((void*)base_addr_virt);
+ return -EINVAL;
+ }
+ } else {
+ msg_addr_virt = base_addr_virt;
+ }
+
+ // Allocate and zero the data structure
+ pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
+ if( pHba == NULL) {
+ if(msg_addr_virt != base_addr_virt){
+ iounmap((void*)msg_addr_virt);
+ }
+ iounmap((void*)base_addr_virt);
+ return -ENOMEM;
+ }
+ memset(pHba, 0, sizeof(adpt_hba));
+
+ down(&adpt_configuration_lock);
+ for(i=0;i<DPTI_MAX_HBA;i++) {
+ if(hbas[i]==NULL) {
+ hbas[i]=pHba;
+ break;
+ }
+ }
+
+ if(hba_chain != NULL){
+ for(p = hba_chain; p->next; p = p->next);
+ p->next = pHba;
+ } else {
+ hba_chain = pHba;
+ }
+ pHba->next = NULL;
+ pHba->unit = hba_count;
+ sprintf(pHba->name, "dpti%d", i);
+ hba_count++;
+
+ up(&adpt_configuration_lock);
+
+ pHba->pDev = pDev;
+ pHba->base_addr_phys = base_addr0_phys;
+
+ // Set up the Virtual Base Address of the I2O Device
+ pHba->base_addr_virt = base_addr_virt;
+ pHba->msg_addr_virt = msg_addr_virt;
+ pHba->irq_mask = (ulong)(base_addr_virt+0x30);
+ pHba->post_port = (ulong)(base_addr_virt+0x40);
+ pHba->reply_port = (ulong)(base_addr_virt+0x44);
+
+ pHba->hrt = NULL;
+ pHba->lct = NULL;
+ pHba->lct_size = 0;
+ pHba->status_block = NULL;
+ pHba->post_count = 0;
+ pHba->state = DPTI_STATE_RESET;
+ pHba->pDev = pDev;
+ pHba->devices = NULL;
+
+ // Initializing the spinlocks
+ spin_lock_init(&pHba->state_lock);
+
+ if(raptorFlag == 0){
+ printk(KERN_INFO"Adaptec I2O RAID controller %d at %lx size=%x irq=%d\n",
+ hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
+ } else {
+ printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
+ printk(KERN_INFO" BAR0 %lx - size= %x\n",base_addr_virt,hba_map0_area_size);
+ printk(KERN_INFO" BAR1 %lx - size= %x\n",msg_addr_virt,hba_map1_area_size);
+ }
+
+ if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
+ printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
+ adpt_i2o_delete_hba(pHba);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static void adpt_i2o_delete_hba(adpt_hba* pHba)
+{
+ adpt_hba* p1;
+ adpt_hba* p2;
+ struct i2o_device* d;
+ struct i2o_device* next;
+ int i;
+ int j;
+ struct adpt_device* pDev;
+ struct adpt_device* pNext;
+
+
+ down(&adpt_configuration_lock);
+ // scsi_unregister calls our adpt_release which
+ // does a quiese
+ if(pHba->host){
+ free_irq(pHba->host->irq, pHba);
+ }
+ for(i=0;i<DPTI_MAX_HBA;i++) {
+ if(hbas[i]==pHba) {
+ hbas[i] = NULL;
+ }
+ }
+ p2 = NULL;
+ for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
+ if(p1 == pHba) {
+ if(p2) {
+ p2->next = p1->next;
+ } else {
+ hba_chain = p1->next;
+ }
+ break;
+ }
+ }
+
+ hba_count--;
+ up(&adpt_configuration_lock);
+
+ iounmap((void*)pHba->base_addr_virt);
+ if(pHba->msg_addr_virt != pHba->base_addr_virt){
+ iounmap((void*)pHba->msg_addr_virt);
+ }
+ if(pHba->hrt) {
+ kfree(pHba->hrt);
+ }
+ if(pHba->lct){
+ kfree(pHba->lct);
+ }
+ if(pHba->status_block) {
+ kfree(pHba->status_block);
+ }
+ if(pHba->reply_pool){
+ kfree(pHba->reply_pool);
+ }
+
+ for(d = pHba->devices; d ; d = next){
+ next = d->next;
+ kfree(d);
+ }
+ for(i = 0 ; i < pHba->top_scsi_channel ; i++){
+ for(j = 0; j < MAX_ID; j++){
+ if(pHba->channel[i].device[j] != NULL){
+ for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
+ pNext = pDev->next_lun;
+ kfree(pDev);
+ }
+ }
+ }
+ }
+ kfree(pHba);
+
+ if(hba_count <= 0){
+ unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
+ }
+}
+
+
+static int adpt_init(void)
+{
+ int i;
+
+ printk(KERN_INFO"Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+ for (i = 0; i < DPTI_MAX_HBA; i++) {
+ hbas[i] = NULL;
+ }
+#ifdef REBOOT_NOTIFIER
+ register_reboot_notifier(&adpt_reboot_notifier);
+#endif
+
+ return 0;
+}
+
+
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
+{
+ struct adpt_device* d;
+
+ if( pHba->channel[chan].device == NULL){
+ printk(KERN_DEBUG"Adaptec I2O RAID: Trying to find device before they are allocated\n");
+ return NULL;
+ }
+
+ d = pHba->channel[chan].device[id];
+ if(!d || d->tid == 0) {
+ return NULL;
+ }
+
+ /* If it is the only lun at that address then this should match*/
+ if(d->scsi_lun == lun){
+ return d;
+ }
+
+ /* else we need to look through all the luns */
+ for(d=d->next_lun ; d ; d = d->next_lun){
+ if(d->scsi_lun == lun){
+ return d;
+ }
+ }
+ return NULL;
+}
+
+
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
+{
+ // I used my own version of the WAIT_QUEUE_HEAD
+ // to handle some version differences
+ // When embedded in the kernel this could go back to the vanilla one
+ ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
+ int status = 0;
+ ulong flags = 0;
+ struct adpt_i2o_post_wait_data *p1, *p2;
+ struct adpt_i2o_post_wait_data *wait_data =
+ kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
+ adpt_wait_queue_t wait;
+
+ if(!wait_data){
+ return -ENOMEM;
+ }
+ /*
+ * The spin locking is needed to keep anyone from playing
+ * with the queue pointers and id while we do the same
+ */
+ spin_lock_irqsave(&adpt_post_wait_lock, flags);
+ // TODO we need a MORE unique way of getting ids
+ // to support async LCT get
+ wait_data->next = adpt_post_wait_queue;
+ adpt_post_wait_queue = wait_data;
+ adpt_post_wait_id = (++adpt_post_wait_id & 0x7fff);
+ wait_data->id = adpt_post_wait_id;
+ spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+
+ wait_data->wq = &adpt_wq_i2o_post;
+ wait_data->status = -ETIMEDOUT;
+
+ // this code is taken from kernel/sched.c:interruptible_sleep_on_timeout
+ wait.task = current;
+ init_waitqueue_entry(&wait, current);
+ wq_write_lock_irqsave(&adpt_wq_i2o_post.lock,flags);
+ __add_wait_queue(&adpt_wq_i2o_post, &wait);
+ wq_write_unlock(&adpt_wq_i2o_post.lock);
+
+ msg[2] |= 0x80000000 | ((u32)wait_data->id);
+ timeout *= HZ;
+ if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
+ if(!timeout){
+ current->state = TASK_INTERRUPTIBLE;
+ spin_unlock_irq(&io_request_lock);
+ schedule();
+ spin_lock_irq(&io_request_lock);
+ } else {
+ current->state = TASK_INTERRUPTIBLE;
+ spin_unlock_irq(&io_request_lock);
+ schedule_timeout(timeout*HZ);
+ spin_lock_irq(&io_request_lock);
+ }
+ }
+ wq_write_lock_irq(&adpt_wq_i2o_post.lock);
+ __remove_wait_queue(&adpt_wq_i2o_post, &wait);
+ wq_write_unlock_irqrestore(&adpt_wq_i2o_post.lock,flags);
+
+ if(status == -ETIMEDOUT){
+ printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
+ // We will have to free the wait_data memory during shutdown
+ return status;
+ }
+
+ /* Remove the entry from the queue. */
+ p2 = NULL;
+ spin_lock_irqsave(&adpt_post_wait_lock, flags);
+ for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p1->next) {
+ if(p1 == wait_data) {
+ if(p1->status == I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION ) {
+ status = -EOPNOTSUPP;
+ }
+ if(p2) {
+ p2->next = p1->next;
+ } else {
+ adpt_post_wait_queue = p1->next;
+ }
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
+
+ kfree(wait_data);
+
+ return status;
+}
+
+
+static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
+{
+
+ u32 m = EMPTY_QUEUE;
+ u32 *msg;
+ ulong timeout = jiffies + 30*HZ;
+ do {
+ rmb();
+ m = readl(pHba->post_port);
+ if (m != EMPTY_QUEUE) {
+ break;
+ }
+ if(time_after(jiffies,timeout)){
+ printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
+ return -ETIMEDOUT;
+ }
+ } while(m == EMPTY_QUEUE);
+
+ msg = (u32*) (pHba->msg_addr_virt + m);
+ memcpy_toio(msg, data, len);
+ wmb();
+
+ //post message
+ writel(m, pHba->post_port);
+ wmb();
+
+ return 0;
+}
+
+
+static void adpt_i2o_post_wait_complete(u32 context, int status)
+{
+ struct adpt_i2o_post_wait_data *p1 = NULL;
+ /*
+ * We need to search through the adpt_post_wait
+ * queue to see if the given message is still
+ * outstanding. If not, it means that the IOP
+ * took longer to respond to the message than we
+ * had allowed and timer has already expired.
+ * Not much we can do about that except log
+ * it for debug purposes, increase timeout, and recompile
+ *
+ * Lock needed to keep anyone from moving queue pointers
+ * around while we're looking through them.
+ */
+
+ context &= 0x7fff;
+
+ spin_lock(&adpt_post_wait_lock);
+ for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
+ if(p1->id == context) {
+ p1->status = status;
+ spin_unlock(&adpt_post_wait_lock);
+ wake_up_interruptible(p1->wq);
+ return;
+ }
+ }
+ spin_unlock(&adpt_post_wait_lock);
+ // If this happens we loose commands that probably really completed
+ printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
+ printk(KERN_DEBUG" Tasks in wait queue:\n");
+ for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
+ printk(KERN_DEBUG" %d\n",p1->id);
+ }
+ return;
+}
+
+static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
+{
+ u32 msg[8];
+ u8* status;
+ u32 m = EMPTY_QUEUE ;
+ ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
+
+ if(pHba->initialized == FALSE) { // First time reset should be quick
+ timeout = jiffies + (25*HZ);
+ } else {
+ adpt_i2o_quiesce_hba(pHba);
+ }
+
+ do {
+ rmb();
+ m = readl(pHba->post_port);
+ if (m != EMPTY_QUEUE) {
+ break;
+ }
+ if(time_after(jiffies,timeout)){
+ printk(KERN_WARNING"Timeout waiting for message!\n");
+ return -ETIMEDOUT;
+ }
+ } while (m == EMPTY_QUEUE);
+
+ status = (u8*)kmalloc(4, GFP_KERNEL|ADDR32);
+ if(status == NULL) {
+ adpt_send_nop(pHba, m);
+ printk(KERN_ERR"IOP reset failed - no free memory.\n");
+ return -ENOMEM;
+ }
+ memset(status,0,4);
+
+ msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
+ msg[2]=0;
+ msg[3]=0;
+ msg[4]=0;
+ msg[5]=0;
+ msg[6]=virt_to_bus(status);
+ msg[7]=0;
+
+ memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
+ wmb();
+ writel(m, pHba->post_port);
+ wmb();
+
+ while(*status == 0){
+ if(time_after(jiffies,timeout)){
+ printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
+ kfree(status);
+ return -ETIMEDOUT;
+ }
+ rmb();
+ }
+
+ if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
+ PDEBUG("%s: Reset in progress...\n", pHba->name);
+ // Here we wait for message frame to become available
+ // indicated that reset has finished
+ do {
+ rmb();
+ m = readl(pHba->post_port);
+ if (m != EMPTY_QUEUE) {
+ break;
+ }
+ if(time_after(jiffies,timeout)){
+ printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
+ return -ETIMEDOUT;
+ }
+ } while (m == EMPTY_QUEUE);
+ // Flush the offset
+ adpt_send_nop(pHba, m);
+ }
+ adpt_i2o_status_get(pHba);
+ if(*status == 0x02 ||
+ pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+ printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
+ pHba->name);
+ } else {
+ PDEBUG("%s: Reset completed.\n", pHba->name);
+ }
+
+ kfree(status);
+#ifdef UARTDELAY
+ // This delay is to allow someone attached to the card through the debug UART to
+ // set up the dump levels that they want before the rest of the initialization sequence
+ adpt_delay(20000);
+#endif
+ return 0;
+}
+
+
+static int adpt_i2o_parse_lct(adpt_hba* pHba)
+{
+ int i;
+ int max;
+ int tid;
+ struct i2o_device *d;
+ i2o_lct *lct = pHba->lct;
+ u8 bus_no = 0;
+ s16 scsi_id;
+ s16 scsi_lun;
+ u32 buf[10]; // larger than 7, or 8 ...
+ struct adpt_device* pDev;
+
+ if (lct == NULL) {
+ printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
+ return -1;
+ }
+
+ max = lct->table_size;
+ max -= 3;
+ max /= 9;
+
+ for(i=0;i<max;i++) {
+ if( lct->lct_entry[i].user_tid != 0xfff){
+ /*
+ * If we have hidden devices, we need to inform the upper layers about
+ * the possible maximum id reference to handle device access when
+ * an array is disassembled. This code has no other purpose but to
+ * allow us future access to devices that are currently hidden
+ * behind arrays, hotspares or have not been configured (JBOD mode).
+ */
+ if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
+ lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
+ lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+ continue;
+ }
+ tid = lct->lct_entry[i].tid;
+ // I2O_DPT_DEVICE_INFO_GROUP_NO;
+ if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
+ continue;
+ }
+ bus_no = buf[0]>>16;
+ scsi_id = buf[1];
+ scsi_lun = (buf[2]>>8 )&0xff;
+ if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
+ printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
+ continue;
+ }
+ if(scsi_id > MAX_ID){
+ printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
+ continue;
+ }
+ if(bus_no > pHba->top_scsi_channel){
+ pHba->top_scsi_channel = bus_no;
+ }
+ if(scsi_id > pHba->top_scsi_id){
+ pHba->top_scsi_id = scsi_id;
+ }
+ if(scsi_lun > pHba->top_scsi_lun){
+ pHba->top_scsi_lun = scsi_lun;
+ }
+ continue;
+ }
+ d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+ if(d==NULL)
+ {
+ printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
+ return -ENOMEM;
+ }
+
+ d->controller = (void*)pHba;
+ d->next = NULL;
+
+ memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+ d->flags = 0;
+ tid = d->lct_data.tid;
+ adpt_i2o_report_hba_unit(pHba, d);
+ adpt_i2o_install_device(pHba, d);
+ }
+ bus_no = 0;
+ for(d = pHba->devices; d ; d = d->next) {
+ if(d->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT ||
+ d->lct_data.class_id == I2O_CLASS_FIBRE_CHANNEL_PORT){
+ tid = d->lct_data.tid;
+ // TODO get the bus_no from hrt-but for now they are in order
+ //bus_no =
+ if(bus_no > pHba->top_scsi_channel){
+ pHba->top_scsi_channel = bus_no;
+ }
+ pHba->channel[bus_no].type = d->lct_data.class_id;
+ pHba->channel[bus_no].tid = tid;
+ if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
+ {
+ pHba->channel[bus_no].scsi_id = buf[1];
+ PDEBUG("Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
+ }
+ // TODO remove - this is just until we get from hrt
+ bus_no++;
+ if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
+ printk(KERN_WARNING"%s: Channel number %d out of range - LCT\n", pHba->name, bus_no);
+ break;
+ }
+ }
+ }
+
+ // Setup adpt_device table
+ for(d = pHba->devices; d ; d = d->next) {
+ if(d->lct_data.class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
+ d->lct_data.class_id == I2O_CLASS_SCSI_PERIPHERAL ||
+ d->lct_data.class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+
+ tid = d->lct_data.tid;
+ scsi_id = -1;
+ // I2O_DPT_DEVICE_INFO_GROUP_NO;
+ if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
+ bus_no = buf[0]>>16;
+ scsi_id = buf[1];
+ scsi_lun = (buf[2]>>8 )&0xff;
+ if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
+ continue;
+ }
+ if(scsi_id > MAX_ID){
+ continue;
+ }
+ if( pHba->channel[bus_no].device[scsi_id] == NULL){
+ pDev = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+ if(pDev == NULL) {
+ return -ENOMEM;
+ }
+ pHba->channel[bus_no].device[scsi_id] = pDev;
+ memset(pDev,0,sizeof(struct adpt_device));
+ } else {
+ for( pDev = pHba->channel[bus_no].device[scsi_id];
+ pDev->next_lun; pDev = pDev->next_lun){
+ }
+ pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+ if(pDev == NULL) {
+ return -ENOMEM;
+ }
+ memset(pDev->next_lun,0,sizeof(struct adpt_device));
+ pDev = pDev->next_lun;
+ }
+ pDev->tid = tid;
+ pDev->scsi_channel = bus_no;
+ pDev->scsi_id = scsi_id;
+ pDev->scsi_lun = scsi_lun;
+ pDev->pI2o_dev = d;
+ d->owner = pDev;
+ pDev->type = (buf[0])&0xff;
+ pDev->flags = (buf[0]>>8)&0xff;
+ if(scsi_id > pHba->top_scsi_id){
+ pHba->top_scsi_id = scsi_id;
+ }
+ if(scsi_lun > pHba->top_scsi_lun){
+ pHba->top_scsi_lun = scsi_lun;
+ }
+ }
+ if(scsi_id == -1){
+ printk(KERN_WARNING"Could not find SCSI ID for %s\n",
+ d->lct_data.identity_tag);
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * Each I2O controller has a chain of devices on it - these match
+ * the useful parts of the LCT of the board.
+ */
+
+static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
+{
+ down(&adpt_configuration_lock);
+ d->controller=pHba;
+ d->owner=NULL;
+ d->next=pHba->devices;
+ d->prev=NULL;
+ if (pHba->devices != NULL){
+ pHba->devices->prev=d;
+ }
+ pHba->devices=d;
+ *d->dev_name = 0;
+
+ up(&adpt_configuration_lock);
+ return 0;
+}
+
+static int adpt_open(struct inode *inode, struct file *file)
+{
+ int minor;
+ adpt_hba* pHba;
+
+ //TODO check for root access
+ //
+ minor = MINOR(inode->i_rdev);
+ if (minor >= hba_count) {
+ return -ENXIO;
+ }
+ down(&adpt_configuration_lock);
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ if (pHba->unit == minor) {
+ break; /* found adapter */
+ }
+ }
+ if (pHba == NULL) {
+ up(&adpt_configuration_lock);
+ return -ENXIO;
+ }
+
+// if(pHba->in_use){
+ // up(&adpt_configuration_lock);
+// return -EBUSY;
+// }
+
+ pHba->in_use = 1;
+ up(&adpt_configuration_lock);
+
+ return 0;
+}
+
+static int adpt_close(struct inode *inode, struct file *file)
+{
+ int minor;
+ adpt_hba* pHba;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor >= hba_count) {
+ return -ENXIO;
+ }
+ down(&adpt_configuration_lock);
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ if (pHba->unit == minor) {
+ break; /* found adapter */
+ }
+ }
+ up(&adpt_configuration_lock);
+ if (pHba == NULL) {
+ return -ENXIO;
+ }
+
+ pHba->in_use = 0;
+
+ return 0;
+}
+
+
+static int adpt_i2o_passthru(adpt_hba* pHba, u32* arg)
+{
+ u32 msg[MAX_MESSAGE_SIZE];
+ u32* reply = NULL;
+ u32 size = 0;
+ u32 reply_size = 0;
+ u32* user_msg = (u32*)arg;
+ u32* user_reply = NULL;
+ ulong sg_list[pHba->sg_tablesize];
+ u32 sg_offset = 0;
+ u32 sg_count = 0;
+ int sg_index = 0;
+ u32 i = 0;
+ u32 rcode = 0;
+ ulong p = 0;
+ ulong flags = 0;
+
+ memset(&msg, 0, MAX_MESSAGE_SIZE*4);
+ // get user msg size in u32s
+ if(get_user(size, &user_msg[0])){
+ return -EFAULT;
+ }
+ size = size>>16;
+
+ user_reply = &user_msg[size];
+ if(size > MAX_MESSAGE_SIZE){
+ return -EFAULT;
+ }
+ size *= 4; // Convert to bytes
+
+ /* Copy in the user's I2O command */
+ if(copy_from_user((void*)msg, (void*)user_msg, size)) {
+ return -EFAULT;
+ }
+ get_user(reply_size, &user_reply[0]);
+ reply_size = reply_size>>16;
+ if(reply_size > REPLY_FRAME_SIZE){
+ reply_size = REPLY_FRAME_SIZE;
+ }
+ reply_size *= 4;
+ reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
+ if(reply == NULL) {
+ printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
+ return -ENOMEM;
+ }
+ memset(reply,0,REPLY_FRAME_SIZE*4);
+ sg_offset = (msg[0]>>4)&0xf;
+ msg[2] = 0x40000000; // IOCTL context
+ msg[3] = (u32)reply;
+ memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
+ if(sg_offset) {
+ // TODO 64bit fix
+ struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset);
+ sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
+ if (sg_count > pHba->sg_tablesize){
+ printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
+ kfree (reply);
+ return -EINVAL;
+ }
+
+ for(i = 0; i < sg_count; i++) {
+ int sg_size;
+
+ if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
+ printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i, sg[i].flag_count);
+ rcode = -EINVAL;
+ goto cleanup;
+ }
+ sg_size = sg[i].flag_count & 0xffffff;
+ /* Allocate memory for the transfer */
+ p = (ulong)kmalloc(sg_size, GFP_KERNEL|ADDR32);
+ if(p == 0) {
+ printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
+ pHba->name,sg_size,i,sg_count);
+ rcode = -ENOMEM;
+ goto cleanup;
+ }
+ sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
+ /* Copy in the user's SG buffer if necessary */
+ if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
+ // TODO 64bit fix
+ if (copy_from_user((void*)p,(void*)sg[i].addr_bus, sg_size)) {
+ printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
+ rcode = -EFAULT;
+ goto cleanup;
+ }
+ }
+ //TODO 64bit fix
+ sg[i].addr_bus = (u32)virt_to_bus((void*)p);
+ }
+ }
+
+ do {
+ spin_lock_irqsave(&io_request_lock, flags);
+ // This state stops any new commands from enterring the
+ // controller while processing the ioctl
+// pHba->state |= DPTI_STATE_IOCTL;
+// We can't set this now - The scsi subsystem sets host_blocked and
+// the queue empties and stops. We need a way to restart the queue
+ rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
+// pHba->state &= ~DPTI_STATE_IOCTL;
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ } while(rcode == -ETIMEDOUT);
+
+ if(rcode){
+ goto cleanup;
+ }
+
+ if(sg_offset) {
+ /* Copy back the Scatter Gather buffers back to user space */
+ u32 j;
+ // TODO 64bit fix
+ struct sg_simple_element* sg;
+ int sg_size;
+
+ // re-acquire the original message to handle correctly the sg copy operation
+ memset(&msg, 0, MAX_MESSAGE_SIZE*4);
+ // get user msg size in u32s
+ if(get_user(size, &user_msg[0])){
+ rcode = -EFAULT;
+ goto cleanup;
+ }
+ size = size>>16;
+ size *= 4;
+ /* Copy in the user's I2O command */
+ if (copy_from_user ((void*)msg, (void*)user_msg, size)) {
+ rcode = -EFAULT;
+ goto cleanup;
+ }
+ sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
+
+ // TODO 64bit fix
+ sg = (struct sg_simple_element*)(msg + sg_offset);
+ for (j = 0; j < sg_count; j++) {
+ /* Copy out the SG list to user's buffer if necessary */
+ if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
+ sg_size = sg[j].flag_count & 0xffffff;
+ // TODO 64bit fix
+ if (copy_to_user((void*)sg[j].addr_bus,(void*)sg_list[j], sg_size)) {
+ printk(KERN_WARNING"%s: Could not copy %lx TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
+ rcode = -EFAULT;
+ goto cleanup;
+ }
+ }
+ }
+ }
+
+ /* Copy back the reply to user space */
+ if (reply_size) {
+ // we wrote our own values for context - now restore the user supplied ones
+ if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
+ printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
+ rcode = -EFAULT;
+ }
+ if(copy_to_user(user_reply, reply, reply_size)) {
+ printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
+ rcode = -EFAULT;
+ }
+ }
+
+
+cleanup:
+ kfree (reply);
+ while(sg_index) {
+ if(sg_list[--sg_index]) {
+ kfree((void*)(sg_list[sg_index]));
+ }
+ }
+ return rcode;
+}
+
+
+/*
+ * This routine returns information about the system. This does not effect
+ * any logic and if the info is wrong - it doesn't matter.
+ */
+
+/* Get all the info we can not get from kernel services */
+static int adpt_system_info(void *buffer)
+{
+ sysInfo_S si;
+
+ memset(&si, 0, sizeof(si));
+
+ si.osType = OS_LINUX;
+ si.osMajorVersion = (u8) (LINUX_VERSION_CODE >> 16);
+ si.osMinorVersion = (u8) (LINUX_VERSION_CODE >> 8 & 0x0ff);
+ si.osRevision = (u8) (LINUX_VERSION_CODE & 0x0ff);
+ si.busType = SI_PCI_BUS;
+ si.processorFamily = DPTI_sig.dsProcessorFamily;
+
+#if defined __i386__
+ adpt_i386_info(&si);
+#elif defined __ia64__
+ adpt_ia64_info(&si);
+#elif define __sparc__
+ adpt_sparc_info(&si);
+#elif defined __alpha__
+ adpt_alpha_info(&si);
+#else
+ si.processorType = 0xff ;
+#endif
+ if(copy_to_user(buffer, &si, sizeof(si))){
+ printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+#if defined __ia64__
+static void adpt_ia64_info(sysInfo_S* si)
+{
+ // This is all the info we need for now
+ // We will add more info as our new
+ // managmenent utility requires it
+ si->processorType = PROC_IA64;
+}
+#endif
+
+
+#if defined __sparc__
+static void adpt_sparc_info(sysInfo_S* si)
+{
+ // This is all the info we need for now
+ // We will add more info as our new
+ // managmenent utility requires it
+ si->processorType = PROC_ULTRASPARC;
+}
+#endif
+
+#if defined __alpha__
+static void adpt_sparc_info(sysInfo_S* si)
+{
+ // This is all the info we need for now
+ // We will add more info as our new
+ // managmenent utility requires it
+ si->processorType = PROC_ALPHA;
+}
+#endif
+
+#if defined __i386__
+
+static void adpt_i386_info(sysInfo_S* si)
+{
+ // This is all the info we need for now
+ // We will add more info as our new
+ // managmenent utility requires it
+ switch (boot_cpu_data.x86) {
+ case CPU_386:
+ si->processorType = PROC_386;
+ break;
+ case CPU_486:
+ si->processorType = PROC_486;
+ break;
+ case CPU_586:
+ si->processorType = PROC_PENTIUM;
+ break;
+ default: // Just in case
+ si->processorType = PROC_PENTIUM;
+ break;
+ }
+}
+
+#endif
+
+
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
+ ulong arg)
+{
+ int minor;
+ int error = 0;
+ adpt_hba* pHba;
+ ulong flags;
+
+ minor = MINOR(inode->i_rdev);
+ if (minor >= DPTI_MAX_HBA){
+ return -ENXIO;
+ }
+ down(&adpt_configuration_lock);
+ for (pHba = hba_chain; pHba; pHba = pHba->next) {
+ if (pHba->unit == minor) {
+ break; /* found adapter */
+ }
+ }
+ up(&adpt_configuration_lock);
+ if(pHba == NULL){
+ return -ENXIO;
+ }
+
+ while((volatile u32) pHba->state & DPTI_STATE_RESET ) {
+ set_task_state(current,TASK_UNINTERRUPTIBLE);
+ schedule_timeout(2);
+
+ }
+
+ switch (cmd) {
+ // TODO: handle 3 cases
+ case DPT_SIGNATURE:
+ if (copy_to_user((char*)arg, &DPTI_sig, sizeof(DPTI_sig))) {
+ return -EFAULT;
+ }
+ break;
+ case I2OUSRCMD:
+ return adpt_i2o_passthru(pHba,(u32*)arg);
+ break;
+
+ case DPT_CTRLINFO:{
+ drvrHBAinfo_S HbaInfo;
+
+#define FLG_OSD_PCI_VALID 0x0001
+#define FLG_OSD_DMA 0x0002
+#define FLG_OSD_I2O 0x0004
+ memset(&HbaInfo, 0, sizeof(HbaInfo));
+ HbaInfo.drvrHBAnum = pHba->unit;
+ HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;
+ HbaInfo.blinkState = adpt_read_blink_led(pHba);
+ HbaInfo.pciBusNum = pHba->pDev->bus->number;
+ HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn);
+ HbaInfo.Interrupt = pHba->pDev->irq;
+ HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
+ if(copy_to_user((void *) arg, &HbaInfo, sizeof(HbaInfo))){
+ printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);
+ return -EFAULT;
+ }
+ break;
+ }
+ case DPT_SYSINFO:
+ return adpt_system_info((void*)arg);
+ break;
+ case DPT_BLINKLED:{
+ u32 value;
+ value = (u32)adpt_read_blink_led(pHba);
+ if (copy_to_user((char*)arg, &value, sizeof(value))) {
+ return -EFAULT;
+ }
+ break;
+ }
+ case I2ORESETCMD:
+ spin_lock_irqsave(&io_request_lock, flags);
+ adpt_hba_reset(pHba);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ break;
+ case I2ORESCANCMD:
+ adpt_rescan(pHba);
+ break;
+ case DPT_TARGET_BUSY & 0xFFFF:
+ case DPT_TARGET_BUSY:
+ {
+ TARGET_BUSY_T busy;
+ struct adpt_device* d;
+
+ if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
+ return -EFAULT;
+ }
+
+ d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
+ if(d == NULL){
+ return -ENODEV;
+ }
+ busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
+ if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
+ return -EFAULT;
+ }
+ break;
+ }
+ default:
+ return -EINVAL;
+ }
+
+ return error;
+}
+
+
+static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
+{
+ Scsi_Cmnd* cmd;
+ adpt_hba* pHba=NULL;
+ u32 m;
+ ulong reply;
+ u32 status=0;
+ u32 context;
+ ulong flags = 0;
+
+ pHba = dev_id;
+ if (pHba == NULL ){
+ printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
+ return;
+ }
+ spin_lock_irqsave(&io_request_lock, flags);
+ while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
+ m = readl(pHba->reply_port);
+ if(m == EMPTY_QUEUE){
+ // Try twice then give up
+ rmb();
+ m = readl(pHba->reply_port);
+ if(m == EMPTY_QUEUE){
+ // This really should not happen
+ printk(KERN_ERR"dpti: Could not get reply frame\n");
+ spin_unlock_irqrestore(&io_request_lock,flags);
+ return;
+ }
+ }
+ reply = (ulong)bus_to_virt(m);
+
+ if (readl(reply) & MSG_FAIL) {
+ u32 old_m = readl(reply+28);
+ ulong msg;
+ u32 old_context;
+ PDEBUG("%s: Failed message\n",pHba->name);
+ if(old_m >= 0x100000){
+ printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
+ writel(m,pHba->reply_port);
+ continue;
+ }
+ // Transaction context is 0 in failed reply frame
+ msg = (ulong)(pHba->msg_addr_virt + old_m);
+ old_context = readl(msg+12);
+ writel(old_context, reply+12);
+ adpt_send_nop(pHba, old_m);
+ }
+ context = readl(reply+8);
+ if(context & 0x40000000){ // IOCTL
+ ulong p = (ulong)(readl(reply+12));
+ if( p != 0) {
+ memcpy((void*)p, (void*)reply, REPLY_FRAME_SIZE * 4);
+ }
+ // All IOCTLs will also be post wait
+ }
+ if(context & 0x80000000){ // Post wait message
+ status = readl(reply+16);
+ if(status >> 24){
+ status &= 0xffff; /* Get detail status */
+ } else {
+ status = I2O_POST_WAIT_OK;
+ }
+ if(!(context & 0x40000000)) {
+ cmd = (Scsi_Cmnd*) readl(reply+12);
+ if(cmd != NULL) {
+ printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
+ }
+ }
+ adpt_i2o_post_wait_complete(context, status);
+ } else { // SCSI message
+ cmd = (Scsi_Cmnd*) readl(reply+12);
+ if(cmd != NULL){
+ if(cmd->serial_number != 0) { // If not timedout
+ adpt_i2o_to_scsi(reply, cmd);
+ }
+ }
+ }
+ writel(m, pHba->reply_port);
+ wmb();
+ rmb();
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return;
+
+}
+
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* d)
+{
+ int i;
+ u32 msg[MAX_MESSAGE_SIZE];
+ u32* mptr;
+ u32 *lenptr;
+ int direction;
+ int scsidir;
+ u32 len;
+ u32 reqlen;
+ s32 rcode;
+
+ memset(msg, 0 , sizeof(msg));
+ len = cmd->request_bufflen;
+ direction = 0x00000000;
+
+ scsidir = 0x00000000; // DATA NO XFER
+ if(len) {
+ /*
+ * Set SCBFlags to indicate if data is being transferred
+ * in or out, or no data transfer
+ * Note: Do not have to verify index is less than 0 since
+ * cmd->cmnd[0] is an unsigned char
+ */
+ switch(cmd->sc_data_direction){
+ case SCSI_DATA_READ:
+ scsidir =0x40000000; // DATA IN (iop<--dev)
+ break;
+ case SCSI_DATA_WRITE:
+ direction=0x04000000; // SGL OUT
+ scsidir =0x80000000; // DATA OUT (iop-->dev)
+ break;
+ case SCSI_DATA_NONE:
+ break;
+ case SCSI_DATA_UNKNOWN:
+ scsidir =0x40000000; // DATA IN (iop<--dev)
+ // Assume In - and continue;
+ break;
+ default:
+ printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
+ pHba->name, cmd->cmnd[0]);
+ cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
+ cmd->scsi_done(cmd);
+ return 0;
+ }
+ }
+ // msg[0] is set later
+ // I2O_CMD_SCSI_EXEC
+ msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
+ msg[2] = 0;
+ msg[3] = (u32)cmd; /* We want the SCSI control block back */
+ // Our cards use the transaction context as the tag for queueing
+ // Adaptec/DPT Private stuff
+ msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
+ msg[5] = d->tid;
+ /* Direction, disconnect ok | sense data | simple queue , CDBLen */
+ // I2O_SCB_FLAG_ENABLE_DISCONNECT |
+ // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG |
+ // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
+ msg[6] = scsidir|0x20a00000|cmd->cmd_len;
+
+ mptr=msg+7;
+
+ // Write SCSI command into the message - always 16 byte block
+ memset(mptr, 0, 16);
+ memcpy(mptr, cmd->cmnd, cmd->cmd_len);
+ mptr+=4;
+ lenptr=mptr++; /* Remember me - fill in when we know */
+ reqlen = 14; // SINGLE SGE
+ /* Now fill in the SGList and command */
+ if(cmd->use_sg) {
+ struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
+ len = 0;
+ for(i = 0 ; i < cmd->use_sg; i++) {
+ *mptr++ = direction|0x10000000|sg->length;
+ len+=sg->length;
+ *mptr++ = virt_to_bus(sg->address);
+ sg++;
+ }
+ /* Make this an end of list */
+ mptr[-2] = direction|0xD0000000|(sg-1)->length;
+ reqlen = mptr - msg;
+ *lenptr = len;
+
+ if(cmd->underflow && len != cmd->underflow){
+ printk(KERN_WARNING"Cmd len %08X Cmd underflow %08X\n",
+ len, cmd->underflow);
+ }
+ } else {
+ *lenptr = len = cmd->request_bufflen;
+ if(len == 0) {
+ reqlen = 12;
+ } else {
+ *mptr++ = 0xD0000000|direction|cmd->request_bufflen;
+ *mptr++ = virt_to_bus(cmd->request_buffer);
+ }
+ }
+
+ /* Stick the headers on */
+ msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
+
+ // Send it on it's way
+ rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
+ if (rcode == 0) {
+ return 0;
+ }
+ return rcode;
+}
+
+
+static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht)
+{
+ struct Scsi_Host *host = NULL;
+
+ host = scsi_register(sht, sizeof(adpt_hba*));
+ if (host == NULL) {
+ printk ("%s: scsi_register returned NULL\n",pHba->name);
+ return -1;
+ }
+ (adpt_hba*)(host->hostdata[0]) = pHba;
+ pHba->host = host;
+
+ host->irq = pHba->pDev->irq;;
+ /* no IO ports, so don't have to set host->io_port and
+ * host->n_io_port
+ */
+ host->io_port = 0;
+ host->n_io_port = 0;
+ /* see comments in hosts.h */
+ host->max_id = 16;
+ host->max_lun = 256;
+ host->max_channel = pHba->top_scsi_channel + 1;
+ host->cmd_per_lun = 256;
+ host->unique_id = (uint) pHba;
+ host->sg_tablesize = pHba->sg_tablesize;
+ host->can_queue = pHba->post_fifo_size;
+ host->select_queue_depths = adpt_select_queue_depths;
+
+ return 0;
+}
+
+
+static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd)
+{
+ adpt_hba* pHba;
+ u32 hba_status;
+ u32 dev_status;
+ u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits
+ // I know this would look cleaner if I just read bytes
+ // but the model I have been using for all the rest of the
+ // io is in 4 byte words - so I keep that model
+ u16 detailed_status = readl(reply+16) &0xffff;
+ dev_status = (detailed_status & 0xff);
+ hba_status = detailed_status >> 8;
+
+ // calculate resid for sg
+ cmd->resid = cmd->request_bufflen - readl(reply+5);
+
+ pHba = (adpt_hba*) cmd->host->hostdata[0];
+
+ cmd->sense_buffer[0] = '\0'; // initialize sense valid flag to false
+
+ if(!(reply_flags & MSG_FAIL)) {
+ switch(detailed_status & I2O_SCSI_DSC_MASK) {
+ case I2O_SCSI_DSC_SUCCESS:
+ cmd->result = (DID_OK << 16);
+ // handle underflow
+ if(readl(reply+5) < cmd->underflow ) {
+ cmd->result = (DID_ERROR <<16);
+ printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
+ }
+ break;
+ case I2O_SCSI_DSC_REQUEST_ABORTED:
+ cmd->result = (DID_ABORT << 16);
+ break;
+ case I2O_SCSI_DSC_PATH_INVALID:
+ case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
+ case I2O_SCSI_DSC_SELECTION_TIMEOUT:
+ case I2O_SCSI_DSC_COMMAND_TIMEOUT:
+ case I2O_SCSI_DSC_NO_ADAPTER:
+ case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
+ printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
+ pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun, hba_status, dev_status, cmd->cmnd[0]);
+ cmd->result = (DID_TIME_OUT << 16);
+ break;
+ case I2O_SCSI_DSC_ADAPTER_BUSY:
+ case I2O_SCSI_DSC_BUS_BUSY:
+ cmd->result = (DID_BUS_BUSY << 16);
+ break;
+ case I2O_SCSI_DSC_SCSI_BUS_RESET:
+ case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
+ cmd->result = (DID_RESET << 16);
+ break;
+ case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
+ printk(KERN_WARNING"%s: SCSI CMD parity error\n",pHba->name);
+ cmd->result = (DID_PARITY << 16);
+ break;
+ case I2O_SCSI_DSC_UNABLE_TO_ABORT:
+ case I2O_SCSI_DSC_COMPLETE_WITH_ERROR:
+ case I2O_SCSI_DSC_UNABLE_TO_TERMINATE:
+ case I2O_SCSI_DSC_MR_MESSAGE_RECEIVED:
+ case I2O_SCSI_DSC_AUTOSENSE_FAILED:
+ case I2O_SCSI_DSC_DATA_OVERRUN:
+ case I2O_SCSI_DSC_UNEXPECTED_BUS_FREE:
+ case I2O_SCSI_DSC_SEQUENCE_FAILURE:
+ case I2O_SCSI_DSC_REQUEST_LENGTH_ERROR:
+ case I2O_SCSI_DSC_PROVIDE_FAILURE:
+ case I2O_SCSI_DSC_REQUEST_TERMINATED:
+ case I2O_SCSI_DSC_IDE_MESSAGE_SENT:
+ case I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT:
+ case I2O_SCSI_DSC_MESSAGE_RECEIVED:
+ case I2O_SCSI_DSC_INVALID_CDB:
+ case I2O_SCSI_DSC_LUN_INVALID:
+ case I2O_SCSI_DSC_SCSI_TID_INVALID:
+ case I2O_SCSI_DSC_FUNCTION_UNAVAILABLE:
+ case I2O_SCSI_DSC_NO_NEXUS:
+ case I2O_SCSI_DSC_CDB_RECEIVED:
+ case I2O_SCSI_DSC_LUN_ALREADY_ENABLED:
+ case I2O_SCSI_DSC_QUEUE_FROZEN:
+ case I2O_SCSI_DSC_REQUEST_INVALID:
+ default:
+ printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+ pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+ hba_status, dev_status, cmd->cmnd[0]);
+ cmd->result = (DID_ERROR << 16);
+ break;
+ }
+
+ // copy over the request sense data if it was a check
+ // condition status
+ if(dev_status == 0x02 /*CHECK_CONDITION*/) {
+ u32 len = sizeof(cmd->sense_buffer);
+ len = (len > 40) ? 40 : len;
+ // Copy over the sense data
+ memcpy(cmd->sense_buffer, (void*)(reply+28) , len);
+ if(cmd->sense_buffer[0] == 0x70 /* class 7 */ &&
+ cmd->sense_buffer[2] == DATA_PROTECT ){
+ /* This is to handle an array failed */
+ cmd->result = (DID_TIME_OUT << 16);
+ printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
+ pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd->lun,
+ hba_status, dev_status, cmd->cmnd[0]);
+
+ }
+ }
+ } else {
+ /* In this condtion we could not talk to the tid
+ * the card rejected it. We should signal a retry
+ * for a limitted number of retries.
+ */
+ cmd->result = (DID_TIME_OUT << 16);
+ printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n",
+ pHba->name, (u32)cmd->channel, (u32)cmd->target, (u32)cmd-> lun,
+ ((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
+ }
+
+ cmd->result |= (dev_status);
+
+ if(cmd->scsi_done != NULL){
+ cmd->scsi_done(cmd);
+ }
+ return cmd->result;
+}
+
+
+static s32 adpt_rescan(adpt_hba* pHba)
+{
+ s32 rcode;
+ ulong flags;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return rcode;
+ }
+
+ if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return rcode;
+ }
+ spin_unlock_irqrestore(&io_request_lock, flags);
+ return 0;
+}
+
+
+static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
+{
+ int i;
+ int max;
+ int tid;
+ struct i2o_device *d;
+ i2o_lct *lct = pHba->lct;
+ u8 bus_no = 0;
+ s16 scsi_id;
+ s16 scsi_lun;
+ u32 buf[10]; // at least 8 u32's
+ struct adpt_device* pDev = NULL;
+ struct i2o_device* pI2o_dev = NULL;
+
+ if (lct == NULL) {
+ printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
+ return -1;
+ }
+
+ max = lct->table_size;
+ max -= 3;
+ max /= 9;
+
+ // Mark each drive as unscanned
+ for (d = pHba->devices; d; d = d->next) {
+ pDev =(struct adpt_device*) d->owner;
+ if(!pDev){
+ continue;
+ }
+ pDev->state |= DPTI_DEV_UNSCANNED;
+ }
+
+ printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
+
+ for(i=0;i<max;i++) {
+ if( lct->lct_entry[i].user_tid != 0xfff){
+ continue;
+ }
+
+ if( lct->lct_entry[i].class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
+ lct->lct_entry[i].class_id == I2O_CLASS_SCSI_PERIPHERAL ||
+ lct->lct_entry[i].class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
+ tid = lct->lct_entry[i].tid;
+ if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
+ printk(KERN_ERR"%s: Could not query device\n",pHba->name);
+ continue;
+ }
+ bus_no = buf[0]>>16;
+ scsi_id = buf[1];
+ scsi_lun = (buf[2]>>8 )&0xff;
+ pDev = pHba->channel[bus_no].device[scsi_id];
+ /* da lun */
+ while(pDev) {
+ if(pDev->scsi_lun == scsi_lun) {
+ break;
+ }
+ pDev = pDev->next_lun;
+ }
+ if(!pDev ) { // Something new add it
+ d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+ if(d==NULL)
+ {
+ printk(KERN_CRIT "Out of memory for I2O device data.\n");
+ return -ENOMEM;
+ }
+
+ d->controller = (void*)pHba;
+ d->next = NULL;
+
+ memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+
+ d->flags = 0;
+ adpt_i2o_report_hba_unit(pHba, d);
+ adpt_i2o_install_device(pHba, d);
+
+ if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
+ printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
+ continue;
+ }
+ pDev = pHba->channel[bus_no].device[scsi_id];
+ if( pDev == NULL){
+ pDev = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+ if(pDev == NULL) {
+ return -ENOMEM;
+ }
+ pHba->channel[bus_no].device[scsi_id] = pDev;
+ } else {
+ while (pDev->next_lun) {
+ pDev = pDev->next_lun;
+ }
+ pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+ if(pDev == NULL) {
+ return -ENOMEM;
+ }
+ }
+ memset(pDev,0,sizeof(struct adpt_device));
+ pDev->tid = d->lct_data.tid;
+ pDev->scsi_channel = bus_no;
+ pDev->scsi_id = scsi_id;
+ pDev->scsi_lun = scsi_lun;
+ pDev->pI2o_dev = d;
+ d->owner = pDev;
+ pDev->type = (buf[0])&0xff;
+ pDev->flags = (buf[0]>>8)&0xff;
+ // Too late, SCSI system has made up it's mind, but what the hey ...
+ if(scsi_id > pHba->top_scsi_id){
+ pHba->top_scsi_id = scsi_id;
+ }
+ if(scsi_lun > pHba->top_scsi_lun){
+ pHba->top_scsi_lun = scsi_lun;
+ }
+ continue;
+ } // end of new i2o device
+
+ // We found an old device - check it
+ while(pDev) {
+ if(pDev->scsi_lun == scsi_lun) {
+ if(pDev->pScsi_dev->online == FALSE) {
+ printk(KERN_WARNING"%s: Setting device (%d,%d,%d) back online\n",
+ pHba->name,bus_no,scsi_id,scsi_lun);
+ if (pDev->pScsi_dev) {
+ pDev->pScsi_dev->online = TRUE;
+ }
+ }
+ d = pDev->pI2o_dev;
+ if(d->lct_data.tid != tid) { // something changed
+ pDev->tid = tid;
+ memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
+ if (pDev->pScsi_dev) {
+ pDev->pScsi_dev->changed = TRUE;
+ pDev->pScsi_dev->removable = TRUE;
+ }
+ }
+ // Found it - mark it scanned
+ pDev->state = DPTI_DEV_ONLINE;
+ break;
+ }
+ pDev = pDev->next_lun;
+ }
+ }
+ }
+ for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
+ pDev =(struct adpt_device*) pI2o_dev->owner;
+ if(!pDev){
+ continue;
+ }
+ // Drive offline drives that previously existed but could not be found
+ // in the LCT table
+ if (pDev->state & DPTI_DEV_UNSCANNED){
+ pDev->state = DPTI_DEV_OFFLINE;
+ printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
+ if (pDev->pScsi_dev) {
+ pDev->pScsi_dev->online = FALSE;
+ if (pDev->pScsi_dev->access_count) {
+ // A drive that was mounted is no longer there... bad!
+ SCSI_LOG_ERROR_RECOVERY(1, printk ("%s:Rescan: Previously "
+ "mounted drive not found!\n",pHba->name));
+ printk(KERN_WARNING"%s:Mounted drive taken offline\n",pHba->name);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static void adpt_fail_posted_scbs(adpt_hba* pHba)
+{
+ Scsi_Cmnd* cmd = NULL;
+ Scsi_Device* d = NULL;
+
+ if( pHba->host->host_queue != NULL ) {
+ d = pHba->host->host_queue;
+ if(!d){
+ return;
+ }
+ while( d->next != NULL ){
+ for(cmd = d->device_queue; cmd ; cmd = cmd->next){
+ if(cmd->serial_number == 0){
+ continue;
+ }
+ cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
+ cmd->scsi_done(cmd);
+ }
+ d = d->next;
+ }
+ }
+}
+
+
+/*============================================================================
+ * Routines from i2o subsystem
+ *============================================================================
+ */
+
+
+
+/*
+ * Bring an I2O controller into HOLD state. See the spec.
+ */
+static int adpt_i2o_activate_hba(adpt_hba* pHba)
+{
+ int rcode;
+
+ if(pHba->initialized ) {
+ if (adpt_i2o_status_get(pHba) < 0) {
+ if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
+ printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
+ return rcode;
+ }
+ if (adpt_i2o_status_get(pHba) < 0) {
+ printk(KERN_INFO "HBA not responding.\n");
+ return -1;
+ }
+ }
+
+ if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
+ printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
+ return -1;
+ }
+
+ if (pHba->status_block->iop_state == ADAPTER_STATE_READY ||
+ pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
+ pHba->status_block->iop_state == ADAPTER_STATE_HOLD ||
+ pHba->status_block->iop_state == ADAPTER_STATE_FAILED) {
+ adpt_i2o_reset_hba(pHba);
+ if (adpt_i2o_status_get(pHba) < 0 || pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
+ printk(KERN_ERR "%s: Failed to initialize.\n", pHba->name);
+ return -1;
+ }
+ }
+ } else {
+ if((rcode = adpt_i2o_reset_hba(pHba) != 0)){
+ printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
+ return rcode;
+ }
+
+ }
+
+ if (adpt_i2o_init_outbound_q(pHba) < 0) {
+ return -1;
+ }
+
+ /* In HOLD state */
+
+ if (adpt_i2o_hrt_get(pHba) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Bring a controller online into OPERATIONAL state.
+ */
+
+static int adpt_i2o_online_hba(adpt_hba* pHba)
+{
+ if (adpt_i2o_systab_send(pHba) < 0) {
+ adpt_i2o_delete_hba(pHba);
+ return -1;
+ }
+ /* In READY state */
+
+ if (adpt_i2o_enable_hba(pHba) < 0) {
+ adpt_i2o_delete_hba(pHba);
+ return -1;
+ }
+
+ /* In OPERATIONAL state */
+ return 0;
+}
+
+static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
+{
+ u32 *msg;
+ ulong timeout = jiffies + 5*HZ;
+
+ while(m == EMPTY_QUEUE){
+ rmb();
+ m = readl(pHba->post_port);
+ if(m != EMPTY_QUEUE){
+ break;
+ }
+ if(time_after(jiffies,timeout)){
+ printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
+ return 2;
+ }
+ }
+ msg = (u32*)(pHba->msg_addr_virt + m);
+ writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
+ writel( I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0,&msg[1]);
+ writel( 0,&msg[2]);
+ wmb();
+
+ writel(m, pHba->post_port);
+ wmb();
+ return 0;
+}
+
+static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
+{
+ u8 *status;
+ u32 *msg = NULL;
+ int i;
+ ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
+ u32* ptr;
+ u32 outbound_frame; // This had to be a 32 bit address
+ u32 m;
+
+ do {
+ rmb();
+ m = readl(pHba->post_port);
+ if (m != EMPTY_QUEUE) {
+ break;
+ }
+
+ if(time_after(jiffies,timeout)){
+ printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
+ return -ETIMEDOUT;
+ }
+ } while(m == EMPTY_QUEUE);
+
+ msg=(u32 *)(pHba->msg_addr_virt+m);
+
+ status = kmalloc(4,GFP_KERNEL|ADDR32);
+ if (status==NULL) {
+ adpt_send_nop(pHba, m);
+ printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
+ pHba->name);
+ return -ENOMEM;
+ }
+ memset(status, 0, 4);
+
+ writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
+ writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
+ writel(0, &msg[2]);
+ writel(0x0106, &msg[3]); /* Transaction context */
+ writel(4096, &msg[4]); /* Host page frame size */
+ writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]); /* Outbound msg frame size and Initcode */
+ writel(0xD0000004, &msg[6]); /* Simple SG LE, EOB */
+ writel(virt_to_bus(status), &msg[7]);
+
+ writel(m, pHba->post_port);
+ wmb();
+
+ // Wait for the reply status to come back
+ do {
+ if (*status) {
+ if (*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
+ break;
+ }
+ }
+ rmb();
+ if(time_after(jiffies,timeout)){
+ printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
+ kfree((void*)status);
+ return -ETIMEDOUT;
+ }
+ } while (1);
+
+ // If the command was successful, fill the fifo with our reply
+ // message packets
+ if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
+ kfree((void*)status);
+ return -2;
+ }
+ kfree((void*)status);
+
+ if(pHba->reply_pool != NULL){
+ kfree(pHba->reply_pool);
+ }
+
+ pHba->reply_pool = (u32*)kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+ if(!pHba->reply_pool){
+ printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
+ return -1;
+ }
+ memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
+
+ ptr = pHba->reply_pool;
+ for(i = 0; i < pHba->reply_fifo_size; i++) {
+ outbound_frame = (u32)virt_to_bus(ptr);
+ writel(outbound_frame, pHba->reply_port);
+ wmb();
+ ptr += REPLY_FRAME_SIZE;
+ }
+ adpt_i2o_status_get(pHba);
+ return 0;
+}
+
+
+/*
+ * I2O System Table. Contains information about
+ * all the IOPs in the system. Used to inform IOPs
+ * about each other's existence.
+ *
+ * sys_tbl_ver is the CurrentChangeIndicator that is
+ * used by IOPs to track changes.
+ */
+
+
+
+static s32 adpt_i2o_status_get(adpt_hba* pHba)
+{
+ ulong timeout;
+ u32 m;
+ u32 *msg;
+ u8 *status_block=NULL;
+ ulong status_block_bus;
+
+ if(pHba->status_block == NULL) {
+ pHba->status_block = (i2o_status_block*)
+ kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
+ if(pHba->status_block == NULL) {
+ printk(KERN_ERR
+ "dpti%d: Get Status Block failed; Out of memory. \n",
+ pHba->unit);
+ return -ENOMEM;
+ }
+ }
+ memset(pHba->status_block, 0, sizeof(i2o_status_block));
+ status_block = (u8*)(pHba->status_block);
+ status_block_bus = virt_to_bus(pHba->status_block);
+ timeout = jiffies+TMOUT_GETSTATUS*HZ;
+ do {
+ rmb();
+ m = readl(pHba->post_port);
+ if (m != EMPTY_QUEUE) {
+ break;
+ }
+ if(time_after(jiffies,timeout)){
+ printk(KERN_ERR "%s: Timeout waiting for message !\n",
+ pHba->name);
+ return -ETIMEDOUT;
+ }
+ } while(m==EMPTY_QUEUE);
+
+
+ msg=(u32*)(pHba->msg_addr_virt+m);
+
+ writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
+ writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]);
+ writel(1, &msg[2]);
+ writel(0, &msg[3]);
+ writel(0, &msg[4]);
+ writel(0, &msg[5]);
+ writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
+ writel(0, &msg[7]);
+ writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
+
+ //post message
+ writel(m, pHba->post_port);
+ wmb();
+
+ while(status_block[87]!=0xff){
+ if(time_after(jiffies,timeout)){
+ printk(KERN_ERR"dpti%d: Get status timeout.\n",
+ pHba->unit);
+ return -ETIMEDOUT;
+ }
+ rmb();
+ }
+
+ // Set up our number of outbound and inbound messages
+ pHba->post_fifo_size = pHba->status_block->max_inbound_frames;
+ if (pHba->post_fifo_size > MAX_TO_IOP_MESSAGES) {
+ pHba->post_fifo_size = MAX_TO_IOP_MESSAGES;
+ }
+
+ pHba->reply_fifo_size = pHba->status_block->max_outbound_frames;
+ if (pHba->reply_fifo_size > MAX_FROM_IOP_MESSAGES) {
+ pHba->reply_fifo_size = MAX_FROM_IOP_MESSAGES;
+ }
+
+ // Calculate the Scatter Gather list size
+ pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element);
+ if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
+ pHba->sg_tablesize = SG_LIST_ELEMENTS;
+ }
+
+
+#ifdef DEBUG
+ printk("dpti%d: State = ",pHba->unit);
+ switch(pHba->status_block->iop_state) {
+ case 0x01:
+ printk("INIT\n");
+ break;
+ case 0x02:
+ printk("RESET\n");
+ break;
+ case 0x04:
+ printk("HOLD\n");
+ break;
+ case 0x05:
+ printk("READY\n");
+ break;
+ case 0x08:
+ printk("OPERATIONAL\n");
+ break;
+ case 0x10:
+ printk("FAILED\n");
+ break;
+ case 0x11:
+ printk("FAULTED\n");
+ break;
+ default:
+ printk("%x (unknown!!)\n",pHba->status_block->iop_state);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Get the IOP's Logical Configuration Table
+ */
+static int adpt_i2o_lct_get(adpt_hba* pHba)
+{
+ u32 msg[8];
+ int ret;
+ u32 buf[16];
+
+ if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
+ pHba->lct_size = pHba->status_block->expected_lct_size;
+ }
+ do {
+ if (pHba->lct == NULL) {
+ pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
+ if(pHba->lct == NULL) {
+ printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
+ pHba->name);
+ return -ENOMEM;
+ }
+ }
+ memset(pHba->lct, 0, pHba->lct_size);
+
+ msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
+ msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2] = 0;
+ msg[3] = 0;
+ msg[4] = 0xFFFFFFFF; /* All devices */
+ msg[5] = 0x00000000; /* Report now */
+ msg[6] = 0xD0000000|pHba->lct_size;
+ msg[7] = virt_to_bus(pHba->lct);
+
+ if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
+ printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n",
+ pHba->name, ret);
+ printk(KERN_ERR"Adaptec: Error Reading Hardware.\n");
+ return ret;
+ }
+
+ if ((pHba->lct->table_size << 2) > pHba->lct_size) {
+ pHba->lct_size = pHba->lct->table_size << 2;
+ kfree(pHba->lct);
+ pHba->lct = NULL;
+ }
+ } while (pHba->lct == NULL);
+
+ PDEBUG("%s: Hardware resource table read.\n", pHba->name);
+
+
+ // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
+ if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
+ pHba->FwDebugBufferSize = buf[1];
+ pHba->FwDebugBuffer_P = pHba->base_addr_virt + buf[0];
+ pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET;
+ pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET;
+ pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1;
+ pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET;
+ pHba->FwDebugBuffer_P += buf[2];
+ pHba->FwDebugFlags = 0;
+ }
+
+ return 0;
+}
+
+static int adpt_i2o_build_sys_table(void)
+{
+ adpt_hba* pHba = NULL;
+ int count = 0;
+
+ sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
+ (hba_count) * sizeof(struct i2o_sys_tbl_entry);
+
+ if(sys_tbl)
+ kfree(sys_tbl);
+
+ sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+ if(!sys_tbl) {
+ printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");
+ return -ENOMEM;
+ }
+ memset(sys_tbl, 0, sys_tbl_len);
+
+ sys_tbl->num_entries = hba_count;
+ sys_tbl->version = I2OVERSION;
+ sys_tbl->change_ind = sys_tbl_ind++;
+
+ for(pHba = hba_chain; pHba; pHba = pHba->next) {
+ // Get updated Status Block so we have the latest information
+ if (adpt_i2o_status_get(pHba)) {
+ sys_tbl->num_entries--;
+ continue; // try next one
+ }
+
+ sys_tbl->iops[count].org_id = pHba->status_block->org_id;
+ sys_tbl->iops[count].iop_id = pHba->unit + 2;
+ sys_tbl->iops[count].seg_num = 0;
+ sys_tbl->iops[count].i2o_version = pHba->status_block->i2o_version;
+ sys_tbl->iops[count].iop_state = pHba->status_block->iop_state;
+ sys_tbl->iops[count].msg_type = pHba->status_block->msg_type;
+ sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
+ sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
+ sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
+ sys_tbl->iops[count].inbound_low = (u32)virt_to_bus((void*)pHba->post_port);
+ sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus((void*)pHba->post_port)>>32);
+
+ count++;
+ }
+
+#ifdef DEBUG
+{
+ u32 *table = (u32*)sys_tbl;
+ printk(KERN_DEBUG"sys_tbl_len=%d in 32bit words\n",(sys_tbl_len >>2));
+ for(count = 0; count < (sys_tbl_len >>2); count++) {
+ printk(KERN_INFO "sys_tbl[%d] = %0#10x\n",
+ count, table[count]);
+ }
+}
+#endif
+
+ return 0;
+}
+
+
+/*
+ * Dump the information block associated with a given unit (TID)
+ */
+
+static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
+{
+ char buf[64];
+ int unit = d->lct_data.tid;
+
+ printk(KERN_INFO "TID %3.3d ", unit);
+
+ if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
+ {
+ buf[16]=0;
+ printk(" Vendor: %-12.12s", buf);
+ }
+ if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
+ {
+ buf[16]=0;
+ printk(" Device: %-12.12s", buf);
+ }
+ if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
+ {
+ buf[8]=0;
+ printk(" Rev: %-12.12s\n", buf);
+ }
+#ifdef DEBUG
+ printk(KERN_INFO "\tClass: %.21s\n", adpt_i2o_get_class_name(d->lct_data.class_id));
+ printk(KERN_INFO "\tSubclass: 0x%04X\n", d->lct_data.sub_class);
+ printk(KERN_INFO "\tFlags: ");
+
+ if(d->lct_data.device_flags&(1<<0))
+ printk("C"); // ConfigDialog requested
+ if(d->lct_data.device_flags&(1<<1))
+ printk("U"); // Multi-user capable
+ if(!(d->lct_data.device_flags&(1<<4)))
+ printk("P"); // Peer service enabled!
+ if(!(d->lct_data.device_flags&(1<<5)))
+ printk("M"); // Mgmt service enabled!
+ printk("\n");
+#endif
+}
+
+#ifdef DEBUG
+/*
+ * Do i2o class name lookup
+ */
+static const char *adpt_i2o_get_class_name(int class)
+{
+ int idx = 16;
+ static char *i2o_class_name[] = {
+ "Executive",
+ "Device Driver Module",
+ "Block Device",
+ "Tape Device",
+ "LAN Interface",
+ "WAN Interface",
+ "Fibre Channel Port",
+ "Fibre Channel Device",
+ "SCSI Device",
+ "ATE Port",
+ "ATE Device",
+ "Floppy Controller",
+ "Floppy Device",
+ "Secondary Bus Port",
+ "Peer Transport Agent",
+ "Peer Transport",
+ "Unknown"
+ };
+
+ switch(class&0xFFF) {
+ case I2O_CLASS_EXECUTIVE:
+ idx = 0; break;
+ case I2O_CLASS_DDM:
+ idx = 1; break;
+ case I2O_CLASS_RANDOM_BLOCK_STORAGE:
+ idx = 2; break;
+ case I2O_CLASS_SEQUENTIAL_STORAGE:
+ idx = 3; break;
+ case I2O_CLASS_LAN:
+ idx = 4; break;
+ case I2O_CLASS_WAN:
+ idx = 5; break;
+ case I2O_CLASS_FIBRE_CHANNEL_PORT:
+ idx = 6; break;
+ case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
+ idx = 7; break;
+ case I2O_CLASS_SCSI_PERIPHERAL:
+ idx = 8; break;
+ case I2O_CLASS_ATE_PORT:
+ idx = 9; break;
+ case I2O_CLASS_ATE_PERIPHERAL:
+ idx = 10; break;
+ case I2O_CLASS_FLOPPY_CONTROLLER:
+ idx = 11; break;
+ case I2O_CLASS_FLOPPY_DEVICE:
+ idx = 12; break;
+ case I2O_CLASS_BUS_ADAPTER_PORT:
+ idx = 13; break;
+ case I2O_CLASS_PEER_TRANSPORT_AGENT:
+ idx = 14; break;
+ case I2O_CLASS_PEER_TRANSPORT:
+ idx = 15; break;
+ }
+ return i2o_class_name[idx];
+}
+#endif
+
+
+static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
+{
+ u32 msg[6];
+ int ret, size = sizeof(i2o_hrt);
+
+ do {
+ if (pHba->hrt == NULL) {
+ pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
+ if (pHba->hrt == NULL) {
+ printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
+ return -ENOMEM;
+ }
+ }
+
+ msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
+ msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2]= 0;
+ msg[3]= 0;
+ msg[4]= (0xD0000000 | size); /* Simple transaction */
+ msg[5]= virt_to_bus(pHba->hrt); /* Dump it here */
+
+ if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
+ printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
+ return ret;
+ }
+
+ if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
+ size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
+ kfree(pHba->hrt);
+ pHba->hrt = NULL;
+ }
+ } while(pHba->hrt == NULL);
+ return 0;
+}
+
+/*
+ * Query one scalar group value or a whole scalar group.
+ */
+static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
+ int group, int field, void *buf, int buflen)
+{
+ u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
+ u8 resblk[8+buflen]; /* 8 bytes for header */
+ int size;
+
+ if (field == -1) /* whole group */
+ opblk[4] = -1;
+
+ size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid,
+ opblk, sizeof(opblk), resblk, sizeof(resblk));
+
+ memcpy(buf, resblk+8, buflen); /* cut off header */
+
+ if (size < 0)
+ return size;
+
+ return buflen;
+}
+
+
+/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
+ *
+ * This function can be used for all UtilParamsGet/Set operations.
+ * The OperationBlock is given in opblk-buffer,
+ * and results are returned in resblk-buffer.
+ * Note that the minimum sized resblk is 8 bytes and contains
+ * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
+ */
+static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
+ void *opblk, int oplen, void *resblk, int reslen)
+{
+ u32 msg[9];
+ u32 *res = (u32 *)resblk;
+ int wait_status;
+
+ msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
+ msg[1] = cmd << 24 | HOST_TID << 12 | tid;
+ msg[2] = 0;
+ msg[3] = 0;
+ msg[4] = 0;
+ msg[5] = 0x54000000 | oplen; /* OperationBlock */
+ msg[6] = virt_to_bus(opblk);
+ msg[7] = 0xD0000000 | reslen; /* ResultBlock */
+ msg[8] = virt_to_bus(resblk);
+
+ if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
+ return wait_status; /* -DetailedStatus */
+ }
+
+ if (res[1]&0x00FF0000) { /* BlockStatus != SUCCESS */
+ printk(KERN_WARNING "%s: %s - Error:\n ErrorInfoSize = 0x%02x, "
+ "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
+ pHba->name,
+ (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
+ : "PARAMS_GET",
+ res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
+ return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
+ }
+
+ return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */
+}
+
+
+static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
+{
+ u32 msg[4];
+ int ret;
+
+ adpt_i2o_status_get(pHba);
+
+ /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
+
+ if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
+ (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
+ return 0;
+ }
+
+ msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
+ msg[2] = 0;
+ msg[3] = 0;
+
+ if((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
+ printk(KERN_INFO"dpti%d: Unable to quiesce (status=%#x).\n",
+ pHba->unit, -ret);
+ } else {
+ printk(KERN_INFO"dpti%d: Quiesced.\n",pHba->unit);
+ }
+
+ adpt_i2o_status_get(pHba);
+ return ret;
+}
+
+
+/*
+ * Enable IOP. Allows the IOP to resume external operations.
+ */
+static int adpt_i2o_enable_hba(adpt_hba* pHba)
+{
+ u32 msg[4];
+ int ret;
+
+ adpt_i2o_status_get(pHba);
+ if(!pHba->status_block){
+ return -ENOMEM;
+ }
+ /* Enable only allowed on READY state */
+ if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
+ return 0;
+
+ if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
+ return -EINVAL;
+
+ msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
+ msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
+ msg[2]= 0;
+ msg[3]= 0;
+
+ if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
+ printk(KERN_WARNING"%s: Could not enable (status=%#10x).\n",
+ pHba->name, ret);
+ } else {
+ PDEBUG("%s: Enabled.\n", pHba->name);
+ }
+
+ adpt_i2o_status_get(pHba);
+ return ret;
+}
+
+
+static int adpt_i2o_systab_send(adpt_hba* pHba)
+{
+ u32 msg[12];
+ int ret;
+
+ msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
+ msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
+ msg[2] = 0;
+ msg[3] = 0;
+ msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
+ msg[5] = 0; /* Segment 0 */
+
+ /*
+ * Provide three SGL-elements:
+ * System table (SysTab), Private memory space declaration and
+ * Private i/o space declaration
+ */
+ msg[6] = 0x54000000 | sys_tbl_len;
+ msg[7] = virt_to_phys(sys_tbl);
+ msg[8] = 0x54000000 | 0;
+ msg[9] = 0;
+ msg[10] = 0xD4000000 | 0;
+ msg[11] = 0;
+
+ if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
+ printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n",
+ pHba->name, ret);
+ }
+#ifdef DEBUG
+ else {
+ PINFO("%s: SysTab set.\n", pHba->name);
+ }
+#endif
+
+ return ret;
+ }
+
+
+/*============================================================================
+ *
+ *============================================================================
+ */
+
+
+#ifdef UARTDELAY
+
+static static void adpt_delay(int millisec)
+{
+ int i;
+ for (i = 0; i < millisec; i++) {
+ udelay(1000); /* delay for one millisecond */
+ }
+}
+
+#endif
+
+static Scsi_Host_Template driver_template = DPT_I2O;
+#include "scsi_module.c"
+EXPORT_NO_SYMBOLS;
--- /dev/null
+/***************************************************************************
+ dpti.h - description
+ -------------------
+ begin : Thu Sep 7 2000
+ copyright : (C) 2001 by Adaptec
+ email : deanna_bonds@adaptec.com
+
+ See README.dpti for history, notes, license info, and credits
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _DPT_H
+#define _DPT_H
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,00)
+#define MAX_TO_IOP_MESSAGES (210)
+#else
+#define MAX_TO_IOP_MESSAGES (255)
+#endif
+#define MAX_FROM_IOP_MESSAGES (255)
+
+
+/*
+ * SCSI interface function Prototypes
+ */
+
+static int adpt_proc_info(char *buffer, char **start, off_t offset,
+ int length, int inode, int inout);
+static int adpt_detect(Scsi_Host_Template * sht);
+static int adpt_queue(Scsi_Cmnd * cmd, void (*cmdcomplete) (Scsi_Cmnd *));
+static int adpt_abort(Scsi_Cmnd * cmd);
+static int adpt_reset(Scsi_Cmnd* cmd);
+static int adpt_release(struct Scsi_Host *host);
+
+static const char *adpt_info(struct Scsi_Host *pSHost);
+static int adpt_bios_param(Disk * disk, kdev_t dev, int geom[]);
+
+static int adpt_bus_reset(Scsi_Cmnd* cmd);
+static int adpt_device_reset(Scsi_Cmnd* cmd);
+
+
+/*
+ * Scsi_Host_Template (see hosts.h)
+ */
+
+#define DPT_DRIVER_NAME "Adaptec I2O RAID"
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,00)
+#define DPT_I2O { \
+ proc_info: adpt_proc_info, \
+ detect: adpt_detect, \
+ release: adpt_release, \
+ info: adpt_info, \
+ queuecommand: adpt_queue, \
+ eh_abort_handler: adpt_abort, \
+ eh_device_reset_handler: adpt_device_reset, \
+ eh_bus_reset_handler: adpt_bus_reset, \
+ eh_host_reset_handler: adpt_reset, \
+ bios_param: adpt_bios_param, \
+ can_queue: MAX_TO_IOP_MESSAGES ,/* max simultaneous cmds */\
+ this_id: 7, /* scsi id of host adapter */\
+ sg_tablesize: 0, /* max scatter-gather cmds */\
+ cmd_per_lun: 256, /* cmds per lun (linked cmds) */\
+ use_clustering: ENABLE_CLUSTERING, \
+ use_new_eh_code: 1 \
+}
+
+#else /* KERNEL_VERSION > 2.2.16 */
+
+#define DPT_I2O { \
+ proc_info: adpt_proc_info, \
+ detect: adpt_detect, \
+ release: adpt_release, \
+ info: adpt_info, \
+ queuecommand: adpt_queue, \
+ eh_abort_handler: adpt_abort, \
+ eh_device_reset_handler: adpt_device_reset, \
+ eh_bus_reset_handler: adpt_bus_reset, \
+ eh_host_reset_handler: adpt_reset, \
+ bios_param: adpt_bios_param, \
+ can_queue: MAX_TO_IOP_MESSAGES, /* max simultaneous cmds */\
+ this_id: 7, /* scsi id of host adapter */\
+ sg_tablesize: 0, /* max scatter-gather cmds */\
+ cmd_per_lun: 256, /* cmds per lun (linked cmds) */\
+ use_clustering: ENABLE_CLUSTERING, \
+ use_new_eh_code: 1, \
+ proc_name: "dpt_i2o" /* this is the name of our proc node*/ \
+}
+#endif
+
+#ifndef HOSTS_C
+
+#include "dpt/sys_info.h"
+#include <linux/wait.h>
+#include "dpt/dpti_i2o.h"
+#include "dpt/dpti_ioctl.h"
+
+#define DPT_I2O_VERSION "2.4 Build 5"
+#define DPT_VERSION 2
+#define DPT_REVISION '4'
+#define DPT_SUBREVISION '5'
+#define DPT_BETA ""
+#define DPT_MONTH 8
+#define DPT_DAY 7
+#define DPT_YEAR (2001-1980)
+
+#define DPT_DRIVER "dpt_i2o"
+#define DPTI_I2O_MAJOR (151)
+#define DPT_ORGANIZATION_ID (0x1B) /* For Private Messages */
+#define DPTI_MAX_HBA (16)
+#define MAX_CHANNEL (5) // Maximum Channel # Supported
+#define MAX_ID (128) // Maximum Target ID Supported
+
+/* Sizes in 4 byte words */
+#define REPLY_FRAME_SIZE (17)
+#define MAX_MESSAGE_SIZE (128)
+#define SG_LIST_ELEMENTS (56)
+
+#define EMPTY_QUEUE 0xffffffff
+#define I2O_INTERRUPT_PENDING_B (0x08)
+
+#define PCI_DPT_VENDOR_ID (0x1044) // DPT PCI Vendor ID
+#define PCI_DPT_DEVICE_ID (0xA501) // DPT PCI I2O Device ID
+#define PCI_DPT_RAPTOR_DEVICE_ID (0xA511)
+
+//#define REBOOT_NOTIFIER 1
+/* Debugging macro from Linux Device Drivers - Rubini */
+#undef PDEBUG
+#ifdef DEBUG
+//TODO add debug level switch
+# define PDEBUG(fmt, args...) printk(KERN_DEBUG "dpti: " fmt, ##args)
+# define PDEBUGV(fmt, args...) printk(KERN_DEBUG "dpti: " fmt, ##args)
+#else
+# define PDEBUG(fmt, args...) /* not debugging: nothing */
+# define PDEBUGV(fmt, args...) /* not debugging: nothing */
+#endif
+
+#define PERROR(fmt, args...) printk(KERN_ERR fmt, ##args)
+#define PWARN(fmt, args...) printk(KERN_WARNING fmt, ##args)
+#define PINFO(fmt, args...) printk(KERN_INFO fmt, ##args)
+#define PCRIT(fmt, args...) printk(KERN_CRIT fmt, ##args)
+
+#define SHUTDOWN_SIGS (sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM))
+
+// Command timeouts
+#define FOREVER (0)
+#define TMOUT_INQUIRY (20)
+#define TMOUT_FLUSH (360/45)
+#define TMOUT_ABORT (30)
+#define TMOUT_SCSI (300)
+#define TMOUT_IOPRESET (360)
+#define TMOUT_GETSTATUS (15)
+#define TMOUT_INITOUTBOUND (15)
+#define TMOUT_LCT (360)
+
+
+#define I2O_SCSI_DEVICE_DSC_MASK 0x00FF
+
+#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x000A
+
+#define I2O_SCSI_DSC_MASK 0xFF00
+#define I2O_SCSI_DSC_SUCCESS 0x0000
+#define I2O_SCSI_DSC_REQUEST_ABORTED 0x0200
+#define I2O_SCSI_DSC_UNABLE_TO_ABORT 0x0300
+#define I2O_SCSI_DSC_COMPLETE_WITH_ERROR 0x0400
+#define I2O_SCSI_DSC_ADAPTER_BUSY 0x0500
+#define I2O_SCSI_DSC_REQUEST_INVALID 0x0600
+#define I2O_SCSI_DSC_PATH_INVALID 0x0700
+#define I2O_SCSI_DSC_DEVICE_NOT_PRESENT 0x0800
+#define I2O_SCSI_DSC_UNABLE_TO_TERMINATE 0x0900
+#define I2O_SCSI_DSC_SELECTION_TIMEOUT 0x0A00
+#define I2O_SCSI_DSC_COMMAND_TIMEOUT 0x0B00
+#define I2O_SCSI_DSC_MR_MESSAGE_RECEIVED 0x0D00
+#define I2O_SCSI_DSC_SCSI_BUS_RESET 0x0E00
+#define I2O_SCSI_DSC_PARITY_ERROR_FAILURE 0x0F00
+#define I2O_SCSI_DSC_AUTOSENSE_FAILED 0x1000
+#define I2O_SCSI_DSC_NO_ADAPTER 0x1100
+#define I2O_SCSI_DSC_DATA_OVERRUN 0x1200
+#define I2O_SCSI_DSC_UNEXPECTED_BUS_FREE 0x1300
+#define I2O_SCSI_DSC_SEQUENCE_FAILURE 0x1400
+#define I2O_SCSI_DSC_REQUEST_LENGTH_ERROR 0x1500
+#define I2O_SCSI_DSC_PROVIDE_FAILURE 0x1600
+#define I2O_SCSI_DSC_BDR_MESSAGE_SENT 0x1700
+#define I2O_SCSI_DSC_REQUEST_TERMINATED 0x1800
+#define I2O_SCSI_DSC_IDE_MESSAGE_SENT 0x3300
+#define I2O_SCSI_DSC_RESOURCE_UNAVAILABLE 0x3400
+#define I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT 0x3500
+#define I2O_SCSI_DSC_MESSAGE_RECEIVED 0x3600
+#define I2O_SCSI_DSC_INVALID_CDB 0x3700
+#define I2O_SCSI_DSC_LUN_INVALID 0x3800
+#define I2O_SCSI_DSC_SCSI_TID_INVALID 0x3900
+#define I2O_SCSI_DSC_FUNCTION_UNAVAILABLE 0x3A00
+#define I2O_SCSI_DSC_NO_NEXUS 0x3B00
+#define I2O_SCSI_DSC_SCSI_IID_INVALID 0x3C00
+#define I2O_SCSI_DSC_CDB_RECEIVED 0x3D00
+#define I2O_SCSI_DSC_LUN_ALREADY_ENABLED 0x3E00
+#define I2O_SCSI_DSC_BUS_BUSY 0x3F00
+#define I2O_SCSI_DSC_QUEUE_FROZEN 0x4000
+
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+#define HBA_FLAGS_INSTALLED_B 0x00000001 // Adapter Was Installed
+#define HBA_FLAGS_BLINKLED_B 0x00000002 // Adapter In Blink LED State
+#define HBA_FLAGS_IN_RESET 0x00000040 /* in reset */
+#define HBA_HOSTRESET_FAILED 0x00000080 /* adpt_resethost failed */
+
+
+// Device state flags
+#define DPTI_DEV_ONLINE 0x00
+#define DPTI_DEV_UNSCANNED 0x01
+#define DPTI_DEV_RESET 0x02
+#define DPTI_DEV_OFFLINE 0x04
+
+
+struct adpt_device {
+ struct adpt_device* next_lun;
+ u32 flags;
+ u32 type;
+ u32 capacity;
+ u32 block_size;
+ u8 scsi_channel;
+ u8 scsi_id;
+ u8 scsi_lun;
+ u8 state;
+ u16 tid;
+ struct i2o_device* pI2o_dev;
+ Scsi_Device *pScsi_dev;
+};
+
+struct adpt_channel {
+ struct adpt_device* device[MAX_ID]; /* used as an array of 128 scsi ids */
+ u8 scsi_id;
+ u8 type;
+ u16 tid;
+ u32 state;
+ struct i2o_device* pI2o_dev;
+};
+
+// HBA state flags
+#define DPTI_STATE_RESET (0x01)
+#define DPTI_STATE_IOCTL (0x02)
+
+typedef struct _adpt_hba {
+ struct _adpt_hba *next;
+ struct pci_dev *pDev;
+ struct Scsi_Host *host;
+ u32 state;
+ spinlock_t state_lock;
+ int unit;
+ int host_no; /* SCSI host number */
+ u8 initialized;
+ u8 in_use; /* is the management node open*/
+
+ char name[32];
+ char detail[55];
+
+ ulong base_addr_virt;
+ ulong msg_addr_virt;
+ ulong base_addr_phys;
+ ulong post_port;
+ ulong reply_port;
+ ulong irq_mask;
+ u16 post_count;
+ u32 post_fifo_size;
+ u32 reply_fifo_size;
+ u32* reply_pool;
+ u32 sg_tablesize; // Scatter/Gather List Size.
+ u8 top_scsi_channel;
+ u8 top_scsi_id;
+ u8 top_scsi_lun;
+
+ i2o_status_block* status_block;
+ i2o_hrt* hrt;
+ i2o_lct* lct;
+ uint lct_size;
+ struct i2o_device* devices;
+ struct adpt_channel channel[MAX_CHANNEL];
+ struct proc_dir_entry* proc_entry; /* /proc dir */
+
+ ulong FwDebugBuffer_P; // Virtual Address Of FW Debug Buffer
+ u32 FwDebugBufferSize; // FW Debug Buffer Size In Bytes
+ ulong FwDebugStrLength_P; // Virtual Addr Of FW Debug String Len
+ ulong FwDebugFlags_P; // Virtual Address Of FW Debug Flags
+ ulong FwDebugBLEDflag_P; // Virtual Addr Of FW Debug BLED
+ ulong FwDebugBLEDvalue_P; // Virtual Addr Of FW Debug BLED
+ u32 FwDebugFlags;
+} adpt_hba;
+
+struct sg_simple_element {
+ u32 flag_count;
+ u32 addr_bus;
+};
+
+/*
+ * Function Prototypes
+ */
+
+static void adpt_i2o_sys_shutdown(void);
+static int adpt_init(void);
+static int adpt_i2o_build_sys_table(void);
+static void adpt_isr(int irq, void *dev_id, struct pt_regs *regs);
+#ifdef REBOOT_NOTIFIER
+static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p);
+#endif
+
+static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d);
+static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
+ int group, int field, void *buf, int buflen);
+#ifdef DEBUG
+static const char *adpt_i2o_get_class_name(int class);
+#endif
+static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
+ void *opblk, int oplen, void *resblk, int reslen);
+static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout);
+static int adpt_i2o_lct_get(adpt_hba* pHba);
+static int adpt_i2o_parse_lct(adpt_hba* pHba);
+static int adpt_i2o_activate_hba(adpt_hba* pHba);
+static int adpt_i2o_enable_hba(adpt_hba* pHba);
+static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d);
+static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len);
+static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba);
+static s32 adpt_i2o_status_get(adpt_hba* pHba);
+static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba);
+static s32 adpt_i2o_hrt_get(adpt_hba* pHba);
+static s32 adpt_scsi_to_i2o(adpt_hba* pHba, Scsi_Cmnd* cmd, struct adpt_device* dptdevice);
+static s32 adpt_i2o_to_scsi(ulong reply, Scsi_Cmnd* cmd);
+static s32 adpt_scsi_register(adpt_hba* pHba,Scsi_Host_Template * sht);
+static s32 adpt_hba_reset(adpt_hba* pHba);
+static s32 adpt_i2o_reset_hba(adpt_hba* pHba);
+static s32 adpt_rescan(adpt_hba* pHba);
+static s32 adpt_i2o_reparse_lct(adpt_hba* pHba);
+static s32 adpt_send_nop(adpt_hba*pHba,u32 m);
+static void adpt_i2o_delete_hba(adpt_hba* pHba);
+static void adpt_select_queue_depths(struct Scsi_Host *host, Scsi_Device * devicelist);
+static void adpt_inquiry(adpt_hba* pHba);
+static void adpt_fail_posted_scbs(adpt_hba* pHba);
+static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun);
+static int adpt_install_hba(Scsi_Host_Template* sht, struct pci_dev* pDev) ;
+static int adpt_i2o_online_hba(adpt_hba* pHba);
+static void adpt_i2o_post_wait_complete(u32, int);
+static int adpt_i2o_systab_send(adpt_hba* pHba);
+
+static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
+static int adpt_open(struct inode *inode, struct file *file);
+static int adpt_close(struct inode *inode, struct file *file);
+
+
+#ifdef UARTDELAY
+static void adpt_delay(int millisec);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+static struct pci_dev* adpt_pci_find_device(uint vendor, struct pci_dev* from);
+#endif
+
+#if defined __ia64__
+static void adpt_ia64_info(sysInfo_S* si);
+#endif
+#if defined __sparc__
+static void adpt_sparc_info(sysInfo_S* si);
+#endif
+#if defined __alpha__
+static void adpt_sparc_info(sysInfo_S* si);
+#endif
+#if defined __i386__
+static void adpt_i386_info(sysInfo_S* si);
+#endif
+
+#define PRINT_BUFFER_SIZE 512
+
+#define HBA_FLAGS_DBG_FLAGS_MASK 0xffff0000 // Mask for debug flags
+#define HBA_FLAGS_DBG_KERNEL_PRINT_B 0x00010000 // Kernel Debugger Print
+#define HBA_FLAGS_DBG_FW_PRINT_B 0x00020000 // Firmware Debugger Print
+#define HBA_FLAGS_DBG_FUNCTION_ENTRY_B 0x00040000 // Function Entry Point
+#define HBA_FLAGS_DBG_FUNCTION_EXIT_B 0x00080000 // Function Exit
+#define HBA_FLAGS_DBG_ERROR_B 0x00100000 // Error Conditions
+#define HBA_FLAGS_DBG_INIT_B 0x00200000 // Init Prints
+#define HBA_FLAGS_DBG_OS_COMMANDS_B 0x00400000 // OS Command Info
+#define HBA_FLAGS_DBG_SCAN_B 0x00800000 // Device Scan
+
+#define FW_DEBUG_STR_LENGTH_OFFSET 0
+#define FW_DEBUG_FLAGS_OFFSET 4
+#define FW_DEBUG_BLED_OFFSET 8
+
+#define FW_DEBUG_FLAGS_NO_HEADERS_B 0x01
+#endif /* !HOSTS_C */
+#endif /* _DPT_H */
/************************************************************************
- * GDT ISA/EISA/PCI Disk Array Controller driver for Linux *
+ * Linux driver for *
+ * ICP vortex GmbH: GDT ISA/EISA/PCI Disk Array Controllers *
+ * Intel Corporation: Storage RAID Controllers *
* *
* gdth.c *
- * Copyright (C) 1995-01 ICP vortex Computersysteme GmbH, Achim Leubner *
+ * Copyright (C) 1995-01 ICP vortex, an Intel company, Achim Leubner *
* *
* <achim@vortex.de> *
* *
* along with this kernel; if not, write to the Free Software *
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
* *
- * Tested with Linux 1.2.13, ..., 2.2.18, ..., 2.4.2 *
+ * Tested with Linux 1.2.13, ..., 2.2.19, ..., 2.4.7 *
* *
* $Log: gdth.c,v $
+ * Revision 1.57 2001/08/21 11:16:35 achim
+ * Bugfix free_irq()
+ *
+ * Revision 1.56 2001/08/09 11:19:39 achim
+ * Scsi_Host_Template changes
+ *
+ * Revision 1.55 2001/08/09 10:11:28 achim
+ * Command HOST_UNFREEZE_IO before cache service init.
+ *
+ * Revision 1.54 2001/07/20 13:48:12 achim
+ * Expand: gdth_analyse_hdrive() removed
+ *
+ * Revision 1.53 2001/07/17 09:52:49 achim
+ * Small OEM related change
+ *
+ * Revision 1.52 2001/06/19 15:06:20 achim
+ * New host command GDT_UNFREEZE_IO added
+ *
+ * Revision 1.51 2001/05/22 06:42:37 achim
+ * PCI: Subdevice ID added
+ *
+ * Revision 1.50 2001/05/17 13:42:16 achim
+ * Support for Intel Storage RAID Controllers added
+ *
+ * Revision 1.50 2001/05/17 12:12:34 achim
+ * Support for Intel Storage RAID Controllers added
+ *
* Revision 1.49 2001/03/15 15:07:17 achim
* New __setup interface for boot command line options added
*
* Initial revision
*
************************************************************************/
-#ident "$Id: gdth.c,v 1.49 2001/03/15 15:07:17 achim Exp $"
+#ident "$Id: gdth.c,v 1.57 2001/08/21 11:16:35 achim Exp $"
/* All GDT Disk Array Controllers are fully supported by this driver.
* This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
#else
#include <linux/bios32.h>
#endif
-#if LINUX_VERSION_CODE >= 0x020126
-#include <linux/init.h>
-#endif
#include <asm/dma.h>
#include <asm/system.h>
static int gdth_search_eisa(ushort eisa_adr);
static int gdth_search_isa(ulong32 bios_adr);
static int gdth_search_pci(gdth_pci_str *pcistr);
+static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
+ ushort vendor, ushort dev);
static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt);
static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha);
static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha);
/* __initfunc, __initdata macros */
#if LINUX_VERSION_CODE >= 0x020322
#define GDTH_INITFUNC(type, func) type __init func
+#include <linux/init.h>
#elif LINUX_VERSION_CODE >= 0x020126
#define GDTH_INITFUNC(type, func) __initfunc(type func)
+#include <linux/init.h>
#else
#define GDTH_INITFUNC(type, func) type func
#define __initdata
GDTH_INITFUNC(static int, gdth_search_pci(gdth_pci_str *pcistr))
+{
+ ushort device, cnt;
+
+ TRACE(("gdth_search_pci()\n"));
+
+ cnt = 0;
+ for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
+ gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
+ for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP;
+ device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
+ gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
+ gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX,
+ PCI_DEVICE_ID_VORTEX_GDTNEWRX);
+ gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_SRC);
+ return cnt;
+}
+
+
+GDTH_INITFUNC(static void, gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
+ ushort vendor, ushort device))
{
ulong base0, base1, base2;
- ushort device_id, cnt;
#if LINUX_VERSION_CODE >= 0x2015C
struct pci_dev *pdev;
#else
ushort idx;
#endif
- TRACE(("gdth_search_pci()\n"));
+ TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
+ *cnt, vendor, device));
- cnt = 0;
- for (device_id = 0; device_id <= PCI_DEVICE_ID_VORTEX_GDTMAXRP;
- ++device_id) {
- if (device_id > PCI_DEVICE_ID_VORTEX_GDT6555 &&
- device_id < PCI_DEVICE_ID_VORTEX_GDT6x17RP)
- continue;
#if LINUX_VERSION_CODE >= 0x20363
- pdev = NULL;
- while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev))
- != NULL) {
- if (pci_enable_device(pdev))
+ pdev = NULL;
+ while ((pdev = pci_find_device(vendor, device, pdev))
+ != NULL) {
+ if (pci_enable_device(pdev))
+ continue;
+ if (*cnt >= MAXHA)
+ return;
+ /* GDT PCI controller found, resources are already in pdev */
+ pcistr[*cnt].pdev = pdev;
+ pcistr[*cnt].vendor_id = vendor;
+ pcistr[*cnt].device_id = device;
+ pcistr[*cnt].subdevice_id = pdev->subsystem_device;
+ pcistr[*cnt].bus = pdev->bus->number;
+ pcistr[*cnt].device_fn = pdev->devfn;
+ pcistr[*cnt].irq = pdev->irq;
+ base0 = pci_resource_flags(pdev, 0);
+ base1 = pci_resource_flags(pdev, 1);
+ base2 = pci_resource_flags(pdev, 2);
+ if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
+ device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
+ if (!(base0 & IORESOURCE_MEM))
continue;
- if (cnt >= MAXHA)
- return cnt;
- /* GDT PCI controller found, resources are already in pdev */
- pcistr[cnt].pdev = pdev;
- pcistr[cnt].device_id = device_id;
- pcistr[cnt].bus = pdev->bus->number;
- pcistr[cnt].device_fn = pdev->devfn;
- pcistr[cnt].irq = pdev->irq;
- base0 = pci_resource_flags(pdev, 0);
- base1 = pci_resource_flags(pdev, 1);
- base2 = pci_resource_flags(pdev, 2);
- if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
- device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
- if (!(base0 & IORESOURCE_MEM))
- continue;
- pcistr[cnt].dpmem = pci_resource_start(pdev, 0);
- } else { /* GDT6110, GDT6120, .. */
- if (!(base0 & IORESOURCE_MEM) ||
- !(base2 & IORESOURCE_MEM) ||
- !(base1 & IORESOURCE_IO))
- continue;
- pcistr[cnt].dpmem = pci_resource_start(pdev, 2);
- pcistr[cnt].io_mm = pci_resource_start(pdev, 0);
- pcistr[cnt].io = pci_resource_start(pdev, 1);
- }
- TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
- pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn),
- pcistr[cnt].irq, pcistr[cnt].dpmem));
- cnt++;
- }
+ pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
+ } else { /* GDT6110, GDT6120, .. */
+ if (!(base0 & IORESOURCE_MEM) ||
+ !(base2 & IORESOURCE_MEM) ||
+ !(base1 & IORESOURCE_IO))
+ continue;
+ pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
+ pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
+ pcistr[*cnt].io = pci_resource_start(pdev, 1);
+ }
+ TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+ pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn),
+ pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+ (*cnt)++;
+ }
#elif LINUX_VERSION_CODE >= 0x2015C
- pdev = NULL;
- while ((pdev = pci_find_device(PCI_VENDOR_ID_VORTEX,device_id,pdev))
- != NULL) {
- if (cnt >= MAXHA)
- return cnt;
- /* GDT PCI controller found, resources are already in pdev */
- pcistr[cnt].pdev = pdev;
- pcistr[cnt].device_id = device_id;
- pcistr[cnt].bus = pdev->bus->number;
- pcistr[cnt].device_fn = pdev->devfn;
- pcistr[cnt].irq = pdev->irq;
- base0 = pdev->base_address[0];
- base1 = pdev->base_address[1];
- base2 = pdev->base_address[2];
- if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
- device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
- if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_MEMORY)
- continue;
- pcistr[cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
- } else { /* GDT6110, GDT6120, .. */
- if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_MEMORY ||
- (base2 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_MEMORY ||
- (base1 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_IO)
- continue;
- pcistr[cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
- pcistr[cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
- pcistr[cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK;
- }
- TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
- pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn),
- pcistr[cnt].irq, pcistr[cnt].dpmem));
- cnt++;
- }
+ pdev = NULL;
+ while ((pdev = pci_find_device(vendor, device, pdev))
+ != NULL) {
+ if (*cnt >= MAXHA)
+ return;
+ /* GDT PCI controller found, resources are already in pdev */
+ pcistr[*cnt].pdev = pdev;
+ pcistr[*cnt].vendor_id = vendor;
+ pcistr[*cnt].device_id = device;
+ pcistr[*cnt].bus = pdev->bus->number;
+ pcistr[*cnt].device_fn = pdev->devfn;
+ pcibios_read_config_word(pcistr[*cnt].bus, pcistr[*cnt].device_fn,
+ PCI_SUBSYSTEM_ID, &pcistr[*cnt].subdevice_id);
+ pcistr[*cnt].irq = pdev->irq;
+ base0 = pdev->base_address[0];
+ base1 = pdev->base_address[1];
+ base2 = pdev->base_address[2];
+ if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
+ device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
+ if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY)
+ continue;
+ pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+ } else { /* GDT6110, GDT6120, .. */
+ if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY ||
+ (base2 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY ||
+ (base1 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_IO)
+ continue;
+ pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
+ pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+ pcistr[*cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK;
+ }
+ TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+ pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn),
+ pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+ (*cnt)++;
+ }
#else
- idx = 0;
- while (!pcibios_find_device(PCI_VENDOR_ID_VORTEX,device_id,idx++,
- &pcistr[cnt].bus,&pcistr[cnt].device_fn)) {
- if (cnt >= MAXHA)
- return cnt;
- /* GDT PCI ctr. found, now read resources from config space */
+ idx = 0;
+ while (!pcibios_find_device(vendor, device, idx++,
+ &pcistr[*cnt].bus,&pcistr[*cnt].device_fn)) {
+ if (*cnt >= MAXHA)
+ return;
+ /* GDT PCI ctr. found, now read resources from config space */
#if LINUX_VERSION_CODE >= 0x010300
#define GDTH_BASEP (int *)
#else
#define GDTH_BASEP
#endif
- if ((error = pcibios_read_config_dword(pcistr[cnt].bus,
- pcistr[cnt].device_fn,
- PCI_BASE_ADDRESS_0,
- GDTH_BASEP&base0)) ||
- (error = pcibios_read_config_dword(pcistr[cnt].bus,
- pcistr[cnt].device_fn,
- PCI_BASE_ADDRESS_1,
- GDTH_BASEP&base1)) ||
- (error = pcibios_read_config_dword(pcistr[cnt].bus,
- pcistr[cnt].device_fn,
- PCI_BASE_ADDRESS_2,
- GDTH_BASEP&base2)) ||
- (error = pcibios_read_config_byte(pcistr[cnt].bus,
- pcistr[cnt].device_fn,
- PCI_INTERRUPT_LINE,
- &pcistr[cnt].irq))) {
- printk("GDT-PCI: error %d reading configuration space", error);
+ if ((error = pcibios_read_config_dword(pcistr[*cnt].bus,
+ pcistr[*cnt].device_fn,
+ PCI_BASE_ADDRESS_0,
+ GDTH_BASEP&base0)) ||
+ (error = pcibios_read_config_dword(pcistr[*cnt].bus,
+ pcistr[*cnt].device_fn,
+ PCI_BASE_ADDRESS_1,
+ GDTH_BASEP&base1)) ||
+ (error = pcibios_read_config_dword(pcistr[*cnt].bus,
+ pcistr[*cnt].device_fn,
+ PCI_BASE_ADDRESS_2,
+ GDTH_BASEP&base2)) ||
+ (error = pcibios_read_config_word(pcistr[*cnt].bus,
+ pcistr[*cnt].device_fn,
+ PCI_SUBSYSTEM_ID,
+ &pcistr[*cnt].subdevice_id)) ||
+ (error = pcibios_read_config_byte(pcistr[*cnt].bus,
+ pcistr[*cnt].device_fn,
+ PCI_INTERRUPT_LINE,
+ &pcistr[*cnt].irq))) {
+ printk("GDT-PCI: error %d reading configuration space", error);
+ continue;
+ }
+ pcistr[*cnt].vendor_id = vendor;
+ pcistr[*cnt].device_id = device;
+ if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
+ device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
+ if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY)
continue;
- }
- pcistr[cnt].device_id = device_id;
- if (device_id <= PCI_DEVICE_ID_VORTEX_GDT6000B || /* GDT6000/B */
- device_id >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) { /* MPR */
- if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_MEMORY)
- continue;
- pcistr[cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
- } else { /* GDT6110, GDT6120, .. */
- if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_MEMORY ||
- (base2 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_MEMORY ||
- (base1 & PCI_BASE_ADDRESS_SPACE) !=
- PCI_BASE_ADDRESS_SPACE_IO)
- continue;
- pcistr[cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
- pcistr[cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
- pcistr[cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK;
- }
- TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
- pcistr[cnt].bus, PCI_SLOT(pcistr[cnt].device_fn),
- pcistr[cnt].irq, pcistr[cnt].dpmem));
- cnt++;
+ pcistr[*cnt].dpmem = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+ } else { /* GDT6110, GDT6120, .. */
+ if ((base0 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY ||
+ (base2 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_MEMORY ||
+ (base1 & PCI_BASE_ADDRESS_SPACE) !=
+ PCI_BASE_ADDRESS_SPACE_IO)
+ continue;
+ pcistr[*cnt].dpmem = base2 & PCI_BASE_ADDRESS_MEM_MASK;
+ pcistr[*cnt].io_mm = base0 & PCI_BASE_ADDRESS_MEM_MASK;
+ pcistr[*cnt].io = base1 & PCI_BASE_ADDRESS_IO_MASK;
}
+ TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
+ pcistr[*cnt].bus, PCI_SLOT(pcistr[*cnt].device_fn),
+ pcistr[*cnt].irq, pcistr[*cnt].dpmem));
+ (*cnt)++;
+ }
#endif
- }
- return cnt;
-}
+}
GDTH_INITFUNC(static void, gdth_sort_pci(gdth_pci_str *pcistr, int cnt))
/* detect IRQ */
if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) {
+ ha->oem_id = OEM_ID_ICP;
ha->type = GDT_EISA;
ha->stype = id;
outl(1,eisa_adr+MAILBOXREG+8);
if (eisacf > 4) /* level triggered */
eisacf -= 4;
ha->irq = gdth_irq_tab[eisacf];
+ ha->oem_id = OEM_ID_ICP;
ha->type = GDT_EISA;
ha->stype = id;
}
return 0;
}
+ ha->oem_id = OEM_ID_ICP;
ha->type = GDT_ISA;
ha->ic_all_size = sizeof(dp2_ptr->u);
ha->stype= GDT2_ID;
TRACE(("gdth_init_pci()\n"));
+ if (pcistr->vendor_id == PCI_VENDOR_ID_INTEL)
+ ha->oem_id = OEM_ID_INTEL;
+ else
+ ha->oem_id = OEM_ID_ICP;
ha->brd_phys = (pcistr->bus << 8) | (pcistr->device_fn & 0xf8);
- ha->stype = (ulong32)pcistr->device_id;
- ha->irq = pcistr->irq;
+ ha->stype = (ulong32)pcistr->device_id;
+ ha->subdevice_id = pcistr->subdevice_id;
+ ha->irq = pcistr->irq;
if (ha->stype <= PCI_DEVICE_ID_VORTEX_GDT6000B) { /* GDT6000/B */
TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
/* 3. send to controller firmware */
gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0],
*(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]);
-#endif
+#endif
+
+ /* unfreeze all IOs */
+ gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0);
/* initialize cache service */
if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0)) {
inq.version = 2;
inq.resp_aenc = 2;
inq.add_length= 32;
- strcpy(inq.vendor,"ICP ");
+ if (ha->oem_id == OEM_ID_INTEL)
+ strcpy(inq.vendor,"Intel ");
+ else
+ strcpy(inq.vendor,"ICP ");
sprintf(inq.product,"Host Drive #%02d",t);
strcpy(inq.revision," ");
gdth_copy_internal_data(scp,(char*)&inq,sizeof(gdth_inq_data));
if (ha->service == CACHESERVICE && ha->status == 56) {
TRACE2(("gdth_async_event(): new host drive %d created\n",
(ushort)ha->info));
- gdth_analyse_hdrive(hanum, (ushort)ha->info);
+ /* gdth_analyse_hdrive(hanum, (ushort)ha->info); */
}
}
return 1;
if (request_dma(ha->drq,"gdth")) {
printk("GDT-ISA: Unable to allocate DMA channel\n");
#if LINUX_VERSION_CODE >= 0x010346
- free_irq(ha->irq,NULL);
+ free_irq(ha->irq,ha);
#else
free_irq(ha->irq);
#endif
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif
#if LINUX_VERSION_CODE >= 0x010346
- free_irq(ha->irq,NULL);
+ free_irq(ha->irq,ha);
#else
free_irq(ha->irq);
#endif
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif
#if LINUX_VERSION_CODE >= 0x010346
- free_irq(ha->irq,NULL);
+ free_irq(ha->irq,ha);
#else
free_irq(ha->irq);
#endif
scsi_init_free((void *)ha->pscratch, GDTH_SCRATCH);
#endif
#if LINUX_VERSION_CODE >= 0x010346
- free_irq(ha->irq,NULL);
+ free_irq(ha->irq,ha);
#else
free_irq(ha->irq);
#endif
if (shp->irq) {
#if LINUX_VERSION_CODE >= 0x010346
- free_irq(shp->irq,NULL);
+ free_irq(shp->irq,ha);
#else
free_irq(shp->irq);
#endif
*
* <achim@vortex.de>
*
- * $Id: gdth.h,v 1.38 2001/03/15 15:06:23 achim Exp $
+ * $Id: gdth.h,v 1.44 2001/08/21 11:19:05 achim Exp $
*/
#include <linux/version.h>
/* defines, macros */
/* driver version */
-#define GDTH_VERSION_STR "1.28"
-#define GDTH_VERSION 1
-#define GDTH_SUBVERSION 28
+#define GDTH_VERSION_STR "2.03"
+#define GDTH_VERSION 2
+#define GDTH_SUBVERSION 3
/* protocol version */
#define PROTOCOL_VERSION 1
+/* OEM IDs */
+#define OEM_ID_ICP 0x941c
+#define OEM_ID_INTEL 0x8000
+
/* controller classes */
#define GDT_ISA 0x01 /* ISA controller */
#define GDT_EISA 0x02 /* EISA controller */
#ifndef PCI_VENDOR_ID_VORTEX
#define PCI_VENDOR_ID_VORTEX 0x1119 /* PCI controller vendor ID */
#endif
+#ifndef PCI_VENDOR_ID_INTEL
+#define PCI_VENDOR_ID_INTEL 0x8086
+#endif
#ifndef PCI_DEVICE_ID_VORTEX_GDT60x0
/* GDT_PCI */
#define PCI_DEVICE_ID_VORTEX_GDTMAXRP 0x2ff
#endif
+#ifndef PCI_DEVICE_ID_VORTEX_GDTNEWRX
+/* new GDT Rx Controller */
+#define PCI_DEVICE_ID_VORTEX_GDTNEWRX 0x300
+#endif
+
+#ifndef PCI_DEVICE_ID_INTEL_SRC
+/* Intel Storage RAID Controller */
+#define PCI_DEVICE_ID_INTEL_SRC 0x600
+#endif
+
/* limits */
#define GDTH_SCRATCH PAGE_SIZE /* 4KB scratch buffer */
#define GDTH_SCRATCH_ORD 0 /* order 0 means 1 page */
#define GDT_CLUST_INFO 22 /* cluster info */
#define GDT_RW_ATTRIBS 23 /* R/W attribs (write thru,..)*/
#define GDT_CLUST_RESET 24 /* releases the cluster drives*/
+#define GDT_FREEZE_IO 25 /* freezes all IOs */
+#define GDT_UNFREEZE_IO 26 /* unfreezes all IOs */
/* raw service commands */
#define GDT_RESERVE 14 /* reserve dev. to raw serv. */
#if LINUX_VERSION_CODE >= 0x02015C
struct pci_dev *pdev;
#endif
+ ushort vendor_id; /* vendor (ICP, Intel, ..) */
ushort device_id; /* device ID (0,..,9) */
+ ushort subdevice_id; /* sub device ID */
unchar bus; /* PCI bus */
unchar device_fn; /* PCI device/function no. */
ulong dpmem; /* DPRAM address */
/* controller information structure */
typedef struct {
+ ushort oem_id; /* OEM */
ushort type; /* controller class */
ushort raw_feat; /* feat. raw service (s/g,..) */
- ulong32 stype; /* controller subtype */
+ ulong32 stype; /* subtype (PCI: device ID) */
+ ushort subdevice_id; /* sub device ID (PCI) */
ushort fw_vers; /* firmware version */
ushort cache_feat; /* feat. cache serv. (s/g,..) */
ushort bmic; /* BMIC address (EISA) */
#define _GDTH_IOCTL_H
/* gdth_ioctl.h
- * $Id: gdth_ioctl.h,v 1.9 2001/01/10 14:39:37 achim Exp $
+ * $Id: gdth_ioctl.h,v 1.10 2001/05/22 06:28:59 achim Exp $
*/
/* IOCTLs */
ushort bios_ver; /* not used */
ushort access; /* not used */
ushort ext_type; /* extended type */
+ ushort device_id; /* device ID */
+ ushort sub_device_id; /* sub device ID */
} ctrtype;
struct {
unchar version; /* OS version */
/* gdth_proc.c
- * $Id: gdth_proc.c,v 1.27 2001/03/14 10:47:00 achim Exp $
+ * $Id: gdth_proc.c,v 1.33 2001/08/10 07:54:39 achim Exp $
*/
#include "gdth_ioctl.h"
+#if LINUX_VERSION_CODE >= 0x020407
#include <linux/completion.h>
+#endif
int gdth_proc_info(char *buffer,char **start,off_t offset,int length,
int hostno,int inout)
sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
scp = scsi_allocate_device(sdev, 1, FALSE);
if (!scp)
- return -ENOMEM;
+ return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
#else
}
if (wb_mode) {
- if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str)))
+ if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE))
return(-EBUSY);
pcpar = (gdth_cpar_str *)ha->pscratch;
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
#else
gdth_do_cmd(&scp, &gdtcmd, cmnd, 30);
#endif
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, ha->pscratch);
printk("Done.\n");
return(orig_length);
}
} else {
return(-EINVAL);
}
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2 ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str)+add_size+add_size2,
+ TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
break;
case GDTIOCTL_DRVERS:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_CTRTYPE:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
piord->status = S_OK;
if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
piord->iu.ctrtype.type = (unchar)((ha->stype>>20) - 0x10);
- } else if (ha->type != GDT_PCIMPR) {
- piord->iu.ctrtype.type = (unchar)((ha->stype<<8) + 6);
} else {
- piord->iu.ctrtype.type = 0xfe;
- piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+ if (ha->type != GDT_PCIMPR) {
+ piord->iu.ctrtype.type = (unchar)((ha->stype<<4) + 6);
+ } else {
+ piord->iu.ctrtype.type =
+ (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
+ if (ha->stype >= 0x300)
+ piord->iu.ctrtype.ext_type = 0x6000 | ha->subdevice_id;
+ else
+ piord->iu.ctrtype.ext_type = 0x6000 | ha->stype;
+ }
+ piord->iu.ctrtype.device_id = ha->stype;
+ piord->iu.ctrtype.sub_device_id = ha->subdevice_id;
}
piord->iu.ctrtype.info = ha->brd_phys;
- piord->iu.ctrtype.oem_id = (ushort)GDT3_ID;
+ piord->iu.ctrtype.oem_id = ha->oem_id;
break;
case GDTIOCTL_CTRCNT:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_OSVERS:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_LOCKDRV:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
for (i = 0; i < piowr->iu.lockdrv.drive_cnt; ++i) {
break;
case GDTIOCTL_LOCKCHN:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
i = piowr->iu.lockchn.channel;
if (i < ha->bus_cnt) {
break;
case GDTIOCTL_EVENT:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
if (piowr->iu.event.erase == 0xff) {
break;
case GDTIOCTL_SCSI:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_RESET_BUS:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_HDRLIST:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_RESCAN:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
break;
case GDTIOCTL_RESET_DRV:
- if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str) ))
+ if (!gdth_ioctl_alloc( hanum, sizeof(gdth_iord_str), TRUE ))
return(-EBUSY);
piord = (gdth_iord_str *)ha->pscratch;
piord->size = sizeof(gdth_iord_str);
char hrec[161];
struct timeval tv;
+ char *buf;
gdth_dskstat_str *pds;
gdth_diskinfo_str *pdi;
gdth_arrayinf_str *pai;
#if LINUX_VERSION_CODE >= 0x020322
sdev = scsi_get_host_dev(gdth_ctr_vtab[vh]);
scp = scsi_allocate_device(sdev, 1, FALSE);
+ if (!scp)
+ return -ENOMEM;
scp->cmd_len = 12;
scp->use_sg = 0;
#else
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < ha->bus_cnt; ++i) {
/* 2.a statistics (and retries/reassigns) */
TRACE2(("pdr_statistics() chn %d\n",i));
- pds = (gdth_dskstat_str *)(ha->pscratch + GDTH_SCRATCH/4);
+ pds = (gdth_dskstat_str *)(buf + GDTH_SCRATCH/4);
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pds);
/* 2.b drive info */
TRACE2(("scsi_drv_info() chn %d dev %d\n",
i, ha->raw[i].id_list[j]));
- pdi = (gdth_diskinfo_str *)ha->pscratch;
+ pdi = (gdth_diskinfo_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pdi);
/* 2.c grown defects */
TRACE2(("scsi_drv_defcnt() chn %d dev %d\n",
i, ha->raw[i].id_list[j]));
- pdef = (gdth_defcnt_str *)ha->pscratch;
+ pdef = (gdth_defcnt_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pdef);
goto stop_output;
}
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
if (!flag) {
size = sprintf(buffer+len, "\n --\n");
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!ha->hdr[i].is_logdrv)
do {
/* 3.a log. drive info */
TRACE2(("cache_drv_info() drive no %d\n",drv_no));
- pcdi = (gdth_cdrinfo_str *)ha->pscratch;
+ pcdi = (gdth_cdrinfo_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pcdi);
if (pos > offset + length)
goto stop_output;
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
if (!flag) {
size = sprintf(buffer+len, "\n --\n");
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
continue;
/* 4.a array drive info */
TRACE2(("array_info() drive no %d\n",i));
- pai = (gdth_arrayinf_str *)ha->pscratch;
+ pai = (gdth_arrayinf_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(pai);
goto stop_output;
}
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
if (!flag) {
size = sprintf(buffer+len, "\n --\n");
len += size; pos = begin + len;
flag = FALSE;
- if (!gdth_ioctl_alloc(hanum, GDTH_SCRATCH))
+ buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE);
+ if (!buf)
goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!ha->hdr[i].is_logdrv ||
continue;
/* 5.a get host drive list */
TRACE2(("host_get() drv_no %d\n",i));
- phg = (gdth_hget_str *)ha->pscratch;
+ phg = (gdth_hget_str *)buf;
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
gdtcmd.u.ioctl.p_param = virt_to_bus(phg);
}
}
}
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, buf);
for (i = 0; i < MAX_HDRIVES; ++i) {
if (!(ha->hdr[i].present))
goto stop_output;
length = piord->size;
memcpy(buffer+len, (char *)piord, length);
- gdth_ioctl_free(hanum);
+ gdth_ioctl_free(hanum, ha->pscratch);
len = length;
}
char *cmnd, int timeout)
{
unsigned bufflen;
+#if LINUX_VERSION_CODE >= 0x020407
DECLARE_COMPLETION(wait);
+#elif LINUX_VERSION_CODE >= 0x020322
+ DECLARE_MUTEX_LOCKED(sem);
+#else
+ struct semaphore sem = MUTEX_LOCKED;
+#endif
TRACE2(("gdth_do_cmd()\n"));
if (gdtcmd != NULL) {
bufflen = 0;
}
scp->request.rq_status = RQ_SCSI_BUSY;
+#if LINUX_VERSION_CODE >= 0x020407
scp->request.waiting = &wait;
+ scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
+ wait_for_completion(&wait);
+#else
+ scp->request.sem = &sem;
#if LINUX_VERSION_CODE >= 0x020322
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
#else
scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1);
GDTH_UNLOCK_SCSI_DOCMD();
#endif
- wait_for_completion(&wait);
+ down(&sem);
+#endif
}
void gdth_scsi_done(Scsi_Cmnd *scp)
scp->request.rq_status = RQ_SCSI_DONE;
+#if LINUX_VERSION_CODE >= 0x020407
if (scp->request.waiting != NULL)
complete(scp->request.waiting);
+#else
+ if (scp->request.sem != NULL)
+ up(scp->request.sem);
+#endif
}
-static int gdth_ioctl_alloc(int hanum, ushort size)
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch)
{
gdth_ha_str *ha;
ulong flags;
- int ret_val;
+ char *ret_val;
if (size == 0 || size > GDTH_SCRATCH)
return FALSE;
ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags);
- if (!ha->scratch_busy) {
- ha->scratch_busy = TRUE;
- ret_val = TRUE;
- } else
- ret_val = FALSE;
+ if (scratch) {
+ if (!ha->scratch_busy) {
+ ha->scratch_busy = TRUE;
+ ret_val = ha->pscratch;
+ } else
+ ret_val = NULL;
+ } else {
+#if LINUX_VERSION_CODE >= 0x020322
+ ret_val = (void *) __get_free_pages(GFP_ATOMIC | GFP_DMA,
+ GDTH_SCRATCH_ORD);
+#else
+ ret_val = scsi_init_malloc(GDTH_SCRATCH, GFP_ATOMIC | GFP_DMA);
+#endif
+ }
GDTH_UNLOCK_HA(ha, flags);
return ret_val;
}
-static void gdth_ioctl_free(int hanum)
+static void gdth_ioctl_free(int hanum, char *buf)
{
gdth_ha_str *ha;
ulong flags;
ha = HADATA(gdth_ctr_tab[hanum]);
GDTH_LOCK_HA(ha, flags);
- ha->scratch_busy = FALSE;
+ if (buf == ha->pscratch) {
+ ha->scratch_busy = FALSE;
+ } else {
+#if LINUX_VERSION_CODE >= 0x020322
+ free_pages((unsigned long)buf, GDTH_SCRATCH_ORD);
+#else
+ scsi_init_free((void *)buf, GDTH_SCRATCH);
+#endif
+ }
GDTH_UNLOCK_HA(ha, flags);
}
#define _GDTH_PROC_H
/* gdth_proc.h
- * $Id: gdth_proc.h,v 1.10 2000/07/24 09:30:01 achim Exp $
+ * $Id: gdth_proc.h,v 1.11 2001/07/25 15:37:40 achim Exp $
*/
static int gdth_set_info(char *buffer,int length,int vh,int hanum,int busnum);
static void gdth_do_cmd(Scsi_Cmnd *scp, gdth_cmd_str *cmd,
char *cmnd, int timeout);
-static int gdth_ioctl_alloc(int hanum, ushort size);
-static void gdth_ioctl_free(int hanum);
+static char *gdth_ioctl_alloc(int hanum, ushort size, int scratch);
+static void gdth_ioctl_free(int hanum, char *buf);
static int gdth_ioctl_check_bin(int hanum, ushort size);
static void gdth_wait_completion(int hanum, int busnum, int id);
static void gdth_stop_timeout(int hanum, int busnum, int id);
Ver.0.1 Initial version
This software may be used and distributed according to the terms of
- the GNU Public License.
+ the GNU General Public License.
======================================================================*/
By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
This software may be used and distributed according to the terms of
- the GNU Public License.
+ the GNU General Public License.
=========================================================================*/
/* $Id: nsp_debug.c,v 1.6 2001/07/04 14:43:53 elca Exp $ */
By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
This software may be used and distributed according to the terms of
- the GNU Public License.
+ the GNU General Public License.
*/
/* $Id: nsp_message.c,v 1.6 2001/07/05 10:56:37 elca Exp $ */
isp2200's firmware.
*/
-#define RELOAD_FIRMWARE 0
-
#define USE_NVRAM_DEFAULTS 1
#define ISP2x00_PORTDB 1
#define MBOX_SEND_CHANGE_REQUEST 0x0070
#define MBOX_PORT_LOGOUT 0x0071
-//#include "qlogicfc_asm.c"
+/*
+ * Firmware if needed (note this is a hack, it belongs in a seperate
+ * module.
+ */
+
+#ifdef CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+#include "qlogicfc_asm.c"
+#else
+static unsigned short risc_code_addr01 = 0x1000 ;
+#endif
/* Each element in mbox_param is an 8 bit bitmap where each bit indicates
if that mbox should be copied as input. For example 0x2 would mean
struct isp2x00_hostdata *hostdata;
int loop_count;
dma64_addr_t busaddr;
- unsigned short risc_code_addr01 = 0x1000 ;
ENTER("isp2x00_reset_hardware");
DEBUG(printk("qlogicfc%d : verifying checksum\n", hostdata->host_id));
-#if RELOAD_FIRMWARE
+#if defined(CONFIG_SCSI_QLOGIC_FC_FIRMWARE)
{
int i;
unsigned short * risc_code = NULL;
--- /dev/null
+/************************************************************************
+ * *
+ * --- ISP2100 Fabric Initiator/Target Firmware --- *
+ * with expanded LUN addressing *
+ * and FcTape (FCP-2) support *
+ * *
+ * *
+ ************************************************************************
+ Copyright (C) 2000 and 2001 Qlogic Corporation
+ (www.qlogic.com)
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+************************************************************************/
+
+/*
+ * Firmware Version 1.19.16 (10:36 Nov 02, 2000)
+ */
+
+unsigned short risc_code_addr01 = 0x1000 ;
+
+unsigned short risc_code_length2100 = 0x9260;
+unsigned short risc_code2100[] = {
+ 0x0078, 0x102d, 0x0000, 0x9260, 0x0000, 0x0001, 0x0013, 0x0010,
+ 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+ 0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
+ 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3231, 0x3030, 0x2046, 0x6972,
+ 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
+ 0x312e, 0x3139, 0x2020, 0x2020, 0x2400, 0x2091, 0x2000, 0x20c1,
+ 0x0021, 0x2039, 0xffff, 0x2019, 0xaaaa, 0x2760, 0x2069, 0x7fff,
+ 0x20c1, 0x0020, 0x2c2c, 0x2d34, 0x2762, 0x236a, 0x2c24, 0x2d04,
+ 0x266a, 0x2562, 0xa406, 0x00c0, 0x1052, 0x20c1, 0x0021, 0x2c2c,
+ 0x2362, 0x2c04, 0x2562, 0xa306, 0x0040, 0x1052, 0x20c1, 0x0020,
+ 0x2039, 0x8fff, 0x20a1, 0xaa00, 0x2708, 0x810d, 0x810d, 0x810d,
+ 0x810d, 0xa18c, 0x000f, 0x2001, 0x000a, 0xa112, 0xa00e, 0x21a8,
+ 0x41a4, 0x3400, 0x8211, 0x00c0, 0x105f, 0x2708, 0x3400, 0xa102,
+ 0x0040, 0x106f, 0x0048, 0x106f, 0x20a8, 0xa00e, 0x41a4, 0x20a1,
+ 0xa260, 0x2009, 0x0000, 0x20a9, 0x07a0, 0x41a4, 0x3400, 0x20c9,
+ 0xa7ff, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x255d,
+ 0x2051, 0xa300, 0x2a70, 0x775e, 0xa786, 0x8fff, 0x0040, 0x1092,
+ 0x705b, 0xca00, 0x7057, 0xc9f1, 0x7063, 0x0200, 0x7067, 0x0200,
+ 0x0078, 0x109a, 0x7057, 0xba01, 0x7063, 0x0100, 0x7067, 0x0100,
+ 0x705b, 0xba00, 0x1078, 0x12df, 0x1078, 0x13c0, 0x1078, 0x1569,
+ 0x1078, 0x1ca4, 0x1078, 0x4229, 0x1078, 0x74cf, 0x1078, 0x134b,
+ 0x1078, 0x2a3f, 0x1078, 0x4da2, 0x1078, 0x48b2, 0x1078, 0x57df,
+ 0x1078, 0x21f7, 0x1078, 0x5abf, 0x1078, 0x5369, 0x1078, 0x210d,
+ 0x1078, 0x21d4, 0x2091, 0x3009, 0x7823, 0x0000, 0x0090, 0x10cf,
+ 0x7820, 0xa086, 0x0002, 0x00c0, 0x10cf, 0x7823, 0x4000, 0x0068,
+ 0x10c7, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70,
+ 0x7003, 0x0000, 0x2001, 0x017f, 0x2003, 0x0000, 0x2a70, 0x7000,
+ 0xa08e, 0x0003, 0x00c0, 0x10ef, 0x1078, 0x35bc, 0x1078, 0x2a67,
+ 0x1078, 0x4df2, 0x1078, 0x4a75, 0x2009, 0x0100, 0x2104, 0xa082,
+ 0x0002, 0x0048, 0x10f3, 0x1078, 0x57fb, 0x0078, 0x10d6, 0x1079,
+ 0x10f7, 0x0078, 0x10dc, 0x1078, 0x6fa9, 0x0078, 0x10eb, 0x1101,
+ 0x1102, 0x11be, 0x10ff, 0x1246, 0x12dc, 0x12dd, 0x12de, 0x1078,
+ 0x1328, 0x007c, 0x127e, 0x0f7e, 0x2091, 0x8000, 0x7000, 0xa086,
+ 0x0001, 0x00c0, 0x1198, 0x1078, 0x3a43, 0x2079, 0x0100, 0x7844,
+ 0xa005, 0x00c0, 0x1198, 0x2011, 0x4129, 0x1078, 0x58d4, 0x1078,
+ 0x1ab1, 0x780f, 0x00ff, 0x7840, 0xa084, 0xfffb, 0x7842, 0x2011,
+ 0x8010, 0x73c0, 0x1078, 0x3579, 0x2001, 0xffff, 0x1078, 0x5975,
+ 0x7238, 0xc284, 0x723a, 0x2001, 0xa30c, 0x2014, 0xc2ac, 0x2202,
+ 0x1078, 0x6db5, 0x2011, 0x0004, 0x1078, 0x8a59, 0x1078, 0x47ce,
+ 0x1078, 0x4211, 0x0040, 0x1144, 0x7083, 0x0001, 0x70bb, 0x0000,
+ 0x1078, 0x3bf5, 0x0078, 0x1198, 0x1078, 0x4897, 0x0040, 0x114d,
+ 0x7a0c, 0xc2b4, 0x7a0e, 0x0078, 0x1159, 0x1078, 0x8ddf, 0x70c8,
+ 0xd09c, 0x00c0, 0x1159, 0x7094, 0xa005, 0x0040, 0x1159, 0x1078,
+ 0x41f5, 0x70d3, 0x0000, 0x70cf, 0x0000, 0x72c8, 0x2079, 0xa351,
+ 0x7804, 0xd0ac, 0x0040, 0x1165, 0xc295, 0x72ca, 0xa296, 0x0004,
+ 0x0040, 0x1186, 0x2011, 0x0001, 0x1078, 0x8a59, 0x708f, 0x0000,
+ 0x7093, 0xffff, 0x7003, 0x0002, 0x0f7f, 0x1078, 0x260d, 0x2011,
+ 0x0005, 0x1078, 0x6ef2, 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100,
+ 0x60e3, 0x0008, 0x0c7f, 0x127f, 0x0078, 0x119a, 0x708f, 0x0000,
+ 0x7093, 0xffff, 0x7003, 0x0002, 0x2011, 0x0005, 0x1078, 0x6ef2,
+ 0x1078, 0x6109, 0x0c7e, 0x2061, 0x0100, 0x60e3, 0x0008, 0x0c7f,
+ 0x0f7f, 0x127f, 0x007c, 0x0c7e, 0x20a9, 0x0082, 0x2009, 0x007e,
+ 0x017e, 0x027e, 0x037e, 0x2110, 0x027e, 0x2019, 0x0029, 0x1078,
+ 0x71e0, 0x027f, 0x1078, 0xa190, 0x037f, 0x027f, 0x017f, 0x1078,
+ 0x2921, 0x8108, 0x00f0, 0x11a0, 0x0c7f, 0x706b, 0x0000, 0x706c,
+ 0xa084, 0x00ff, 0x706e, 0x7097, 0x0000, 0x007c, 0x127e, 0x2091,
+ 0x8000, 0x7000, 0xa086, 0x0002, 0x00c0, 0x1244, 0x7090, 0xa086,
+ 0xffff, 0x0040, 0x11d1, 0x1078, 0x260d, 0x1078, 0x6109, 0x0078,
+ 0x1244, 0x70c8, 0xd09c, 0x0040, 0x11fd, 0xd084, 0x0040, 0x11fd,
+ 0x0f7e, 0x2079, 0x0100, 0x790c, 0xc1b5, 0x790e, 0x0f7f, 0xd08c,
+ 0x0040, 0x11fd, 0x70cc, 0xa086, 0xffff, 0x0040, 0x11f9, 0x1078,
+ 0x278a, 0x1078, 0x6109, 0x70c8, 0xd094, 0x00c0, 0x1244, 0x2011,
+ 0x0001, 0x2019, 0x0000, 0x1078, 0x27c2, 0x1078, 0x6109, 0x0078,
+ 0x1244, 0x70d0, 0xa005, 0x00c0, 0x1244, 0x708c, 0xa005, 0x00c0,
+ 0x1244, 0x1078, 0x4897, 0x00c0, 0x1244, 0x2001, 0xa352, 0x2004,
+ 0xd0ac, 0x0040, 0x1227, 0x157e, 0x0c7e, 0x20a9, 0x007f, 0x2009,
+ 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x121a, 0x6000, 0xd0ec,
+ 0x00c0, 0x1222, 0x017f, 0x8108, 0x00f0, 0x1211, 0x0c7f, 0x157f,
+ 0x0078, 0x1227, 0x017f, 0x0c7f, 0x157f, 0x0078, 0x1244, 0x7003,
+ 0x0003, 0x7093, 0xffff, 0x2001, 0x0000, 0x1078, 0x2480, 0x1078,
+ 0x35f7, 0x2001, 0xa5ac, 0x2004, 0xa086, 0x0005, 0x00c0, 0x123c,
+ 0x2011, 0x0000, 0x1078, 0x6ef2, 0x2011, 0x0000, 0x1078, 0x6efc,
+ 0x1078, 0x6109, 0x1078, 0x61d3, 0x127f, 0x007c, 0x017e, 0x0f7e,
+ 0x127e, 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0x00f7, 0x1078,
+ 0x41de, 0x7940, 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0040,
+ 0x125b, 0x7827, 0x0040, 0xd19c, 0x0040, 0x1260, 0x7827, 0x0008,
+ 0x007e, 0x037e, 0x157e, 0xa006, 0x1078, 0x5975, 0x7900, 0xa18a,
+ 0x0003, 0x0050, 0x1289, 0x7954, 0xd1ac, 0x00c0, 0x1289, 0x2009,
+ 0x00f8, 0x1078, 0x41de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+ 0x09c4, 0x7820, 0xd09c, 0x00c0, 0x1281, 0x7824, 0xd0ac, 0x00c0,
+ 0x12ca, 0x00f0, 0x1279, 0x2001, 0x0001, 0x1078, 0x2480, 0x0078,
+ 0x12d5, 0x7853, 0x0000, 0x782f, 0x0020, 0x20a9, 0x0050, 0x00e0,
+ 0x128f, 0x2091, 0x6000, 0x00f0, 0x128f, 0x7853, 0x0400, 0x782f,
+ 0x0000, 0x2009, 0x00f8, 0x1078, 0x41de, 0x20a9, 0x000e, 0x0005,
+ 0x00f0, 0x129f, 0x7853, 0x1400, 0x7843, 0x0090, 0x7843, 0x0010,
+ 0x2019, 0x61a8, 0x7854, 0x0005, 0x0005, 0xd08c, 0x0040, 0x12b4,
+ 0x7824, 0xd0ac, 0x00c0, 0x12ca, 0x8319, 0x00c0, 0x12aa, 0x2009,
+ 0xa331, 0x2104, 0x8000, 0x200a, 0xa084, 0xfff0, 0x0040, 0x12c4,
+ 0x200b, 0x0000, 0x1078, 0x251e, 0x2001, 0x0001, 0x1078, 0x2480,
+ 0x0078, 0x12d3, 0x2001, 0xa331, 0x2003, 0x0000, 0x7828, 0xc09d,
+ 0x782a, 0x7827, 0x0048, 0x7853, 0x0400, 0x157f, 0x037f, 0x007f,
+ 0x127f, 0x0f7f, 0x017f, 0x007c, 0x007c, 0x007c, 0x007c, 0x2a70,
+ 0x2009, 0x0100, 0x2104, 0xa082, 0x0002, 0x0048, 0x12eb, 0x704f,
+ 0xffff, 0x0078, 0x12ed, 0x704f, 0x0000, 0x7053, 0xffff, 0x706b,
+ 0x0000, 0x706f, 0x0000, 0x1078, 0x8ddf, 0x2061, 0xa58c, 0x6003,
+ 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200, 0x6013,
+ 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0, 0x2061,
+ 0xa594, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000, 0x600f,
+ 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001, 0x601f,
+ 0x0000, 0x2061, 0xa5a3, 0x6003, 0x514c, 0x6007, 0x4f47, 0x600b,
+ 0x4943, 0x600f, 0x2020, 0x2001, 0xa325, 0x2003, 0x0000, 0x007c,
+ 0x2091, 0x8000, 0x0068, 0x132a, 0x007e, 0x017e, 0x2079, 0x0000,
+ 0x7818, 0xd084, 0x00c0, 0x1330, 0x017f, 0x792e, 0x007f, 0x782a,
+ 0x007f, 0x7826, 0x3900, 0x783a, 0x7823, 0x8002, 0x781b, 0x0001,
+ 0x2091, 0x5000, 0x2091, 0x4080, 0x2079, 0xa300, 0x7803, 0x0005,
+ 0x0078, 0x1348, 0x007c, 0x2071, 0xa300, 0x7158, 0x712e, 0x2021,
+ 0x0001, 0xa190, 0x002d, 0xa298, 0x002d, 0x0048, 0x1361, 0x705c,
+ 0xa302, 0x00c8, 0x1361, 0x220a, 0x2208, 0x2310, 0x8420, 0x0078,
+ 0x1353, 0x200b, 0x0000, 0x74a6, 0x74aa, 0x007c, 0x0e7e, 0x127e,
+ 0x2091, 0x8000, 0x2071, 0xa300, 0x70a8, 0xa0ea, 0x0010, 0x00c8,
+ 0x1374, 0xa06e, 0x0078, 0x137e, 0x8001, 0x70aa, 0x702c, 0x2068,
+ 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f, 0x0e7f,
+ 0x007c, 0x0e7e, 0x2071, 0xa300, 0x127e, 0x2091, 0x8000, 0x70a8,
+ 0x8001, 0x00c8, 0x138e, 0xa06e, 0x0078, 0x1397, 0x70aa, 0x702c,
+ 0x2068, 0x2d04, 0x702e, 0x206b, 0x0000, 0x6807, 0x0000, 0x127f,
+ 0x0e7f, 0x007c, 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2071, 0xa300,
+ 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa, 0x127f,
+ 0x0e7f, 0x007c, 0x8dff, 0x0040, 0x13b6, 0x6804, 0x6807, 0x0000,
+ 0x007e, 0x1078, 0x139a, 0x0d7f, 0x0078, 0x13aa, 0x007c, 0x0e7e,
+ 0x2071, 0xa300, 0x70a8, 0xa08a, 0x0010, 0xa00d, 0x0e7f, 0x007c,
+ 0x0e7e, 0x2071, 0xa5d0, 0x7007, 0x0000, 0x701b, 0x0000, 0x701f,
+ 0x0000, 0x2071, 0x0000, 0x7010, 0xa085, 0x8004, 0x7012, 0x0e7f,
+ 0x007c, 0x0e7e, 0x2270, 0x700b, 0x0000, 0x2071, 0xa5d0, 0x7018,
+ 0xa088, 0xa5d9, 0x220a, 0x8000, 0xa084, 0x0007, 0x701a, 0x7004,
+ 0xa005, 0x00c0, 0x13e9, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa,
+ 0x0f7f, 0x0e7f, 0x007c, 0x0e7e, 0x2071, 0xa5d0, 0x7004, 0xa005,
+ 0x00c0, 0x13f8, 0x0f7e, 0x2079, 0x0010, 0x1078, 0x13fa, 0x0f7f,
+ 0x0e7f, 0x007c, 0x7000, 0x0079, 0x13fd, 0x1401, 0x146b, 0x1488,
+ 0x1488, 0x7018, 0x711c, 0xa106, 0x00c0, 0x1409, 0x7007, 0x0000,
+ 0x007c, 0x0d7e, 0xa180, 0xa5d9, 0x2004, 0x700a, 0x2068, 0x8108,
+ 0xa18c, 0x0007, 0x711e, 0x7803, 0x0026, 0x6824, 0x7832, 0x6828,
+ 0x7836, 0x682c, 0x783a, 0x6830, 0x783e, 0x6810, 0x700e, 0x680c,
+ 0x7016, 0x6804, 0x0d7f, 0xd084, 0x0040, 0x142b, 0x7007, 0x0001,
+ 0x1078, 0x1430, 0x007c, 0x7007, 0x0002, 0x1078, 0x1446, 0x007c,
+ 0x017e, 0x027e, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8,
+ 0x143b, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822, 0x7803,
+ 0x0020, 0x7803, 0x0041, 0x027f, 0x017f, 0x007c, 0x017e, 0x027e,
+ 0x137e, 0x147e, 0x157e, 0x7014, 0x2098, 0x20a1, 0x0014, 0x7803,
+ 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x00c8, 0x145a,
+ 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+ 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x157f, 0x147f, 0x137f,
+ 0x027f, 0x017f, 0x007c, 0x137e, 0x147e, 0x157e, 0x2099, 0xa3f9,
+ 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+ 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+ 0x7002, 0x700b, 0xa3f4, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+ 0x137e, 0x147e, 0x157e, 0x2001, 0xa428, 0x209c, 0x20a1, 0x0014,
+ 0x7803, 0x0026, 0x2001, 0xa429, 0x20ac, 0x53a6, 0x2099, 0xa42a,
+ 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x127e,
+ 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+ 0x7002, 0x700b, 0xa425, 0x127f, 0x157f, 0x147f, 0x137f, 0x007c,
+ 0x017e, 0x0e7e, 0x2071, 0xa5d0, 0x0f7e, 0x2079, 0x0010, 0x7904,
+ 0x7803, 0x0002, 0xd1fc, 0x0040, 0x14c2, 0xa18c, 0x0700, 0x7004,
+ 0x1079, 0x14c6, 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x13fa, 0x14ce,
+ 0x14fb, 0x1523, 0x1556, 0x14cc, 0x0078, 0x14cc, 0xa18c, 0x0700,
+ 0x00c0, 0x14f4, 0x137e, 0x147e, 0x157e, 0x7014, 0x20a0, 0x2099,
+ 0x0014, 0x7803, 0x0040, 0x7010, 0x20a8, 0x53a5, 0x3400, 0x7016,
+ 0x157f, 0x147f, 0x137f, 0x700c, 0xa005, 0x0040, 0x1510, 0x1078,
+ 0x1430, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007,
+ 0x0000, 0x1078, 0x13fa, 0x007c, 0x7008, 0xa080, 0x0002, 0x2003,
+ 0x0200, 0x0078, 0x14ef, 0xa18c, 0x0700, 0x00c0, 0x1506, 0x700c,
+ 0xa005, 0x0040, 0x1510, 0x1078, 0x1446, 0x007c, 0x7008, 0xa080,
+ 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x1078, 0x13fa, 0x007c,
+ 0x0d7e, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+ 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x0d7f, 0x7007, 0x0000,
+ 0x1078, 0x13fa, 0x007c, 0xa18c, 0x0700, 0x00c0, 0x1550, 0x137e,
+ 0x147e, 0x157e, 0x2001, 0xa3f7, 0x2004, 0xa080, 0x000d, 0x20a0,
+ 0x2099, 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001,
+ 0xa3f9, 0x2004, 0xd0bc, 0x0040, 0x1546, 0x2001, 0xa402, 0x2004,
+ 0xa080, 0x000d, 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x157f, 0x147f,
+ 0x137f, 0x7007, 0x0000, 0x1078, 0x4e9b, 0x1078, 0x13fa, 0x007c,
+ 0x2011, 0x8003, 0x1078, 0x3579, 0x0078, 0x1554, 0xa18c, 0x0700,
+ 0x00c0, 0x1563, 0x2001, 0xa427, 0x2003, 0x0100, 0x7007, 0x0000,
+ 0x1078, 0x13fa, 0x007c, 0x2011, 0x8004, 0x1078, 0x3579, 0x0078,
+ 0x1567, 0x127e, 0x2091, 0x2100, 0x2079, 0x0030, 0x2071, 0xa5e1,
+ 0x7803, 0x0004, 0x7003, 0x0000, 0x700f, 0xa5e7, 0x7013, 0xa5e7,
+ 0x780f, 0x0076, 0x7803, 0x0004, 0x127f, 0x007c, 0x6934, 0xa184,
+ 0x0007, 0x0079, 0x1583, 0x158b, 0x15d1, 0x158b, 0x158b, 0x158b,
+ 0x15b6, 0x159a, 0x158f, 0xa085, 0x0001, 0x0078, 0x15eb, 0x684c,
+ 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858,
+ 0x0078, 0x15d9, 0xa18c, 0x00ff, 0xa186, 0x001e, 0x00c0, 0x158b,
+ 0x684c, 0xd0bc, 0x0040, 0x158b, 0x6860, 0x682e, 0x685c, 0x682a,
+ 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+ 0x2015, 0x2004, 0x6832, 0x6858, 0x0078, 0x15e1, 0xa18c, 0x00ff,
+ 0xa186, 0x0015, 0x00c0, 0x158b, 0x684c, 0xd0ac, 0x0040, 0x158b,
+ 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+ 0x2015, 0x2004, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858, 0x0078,
+ 0x15e1, 0x684c, 0xd0ac, 0x0040, 0x158b, 0xa006, 0x682e, 0x682a,
+ 0x6858, 0xa18c, 0x000f, 0xa188, 0x2015, 0x210c, 0x6932, 0x2d08,
+ 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+ 0x6912, 0x6980, 0x6916, 0x007c, 0x20e1, 0x0007, 0x20e1, 0x2000,
+ 0x2001, 0x020a, 0x2004, 0x82ff, 0x0040, 0x160e, 0xa280, 0x0004,
+ 0x0d7e, 0x206c, 0x684c, 0xd0dc, 0x00c0, 0x160a, 0x1078, 0x157e,
+ 0x0040, 0x160a, 0x0d7f, 0xa280, 0x0000, 0x2003, 0x0002, 0xa016,
+ 0x0078, 0x160e, 0x6808, 0x8000, 0x680a, 0x0d7f, 0x127e, 0x047e,
+ 0x037e, 0x027e, 0x2091, 0x2100, 0x027f, 0x037f, 0x047f, 0x7000,
+ 0xa005, 0x00c0, 0x1622, 0x7206, 0x2001, 0x1643, 0x007e, 0x2260,
+ 0x0078, 0x17be, 0x710c, 0x220a, 0x8108, 0x230a, 0x8108, 0x240a,
+ 0x8108, 0xa182, 0xa602, 0x0048, 0x162f, 0x2009, 0xa5e7, 0x710e,
+ 0x7010, 0xa102, 0xa082, 0x0009, 0x0040, 0x163a, 0xa080, 0x001b,
+ 0x00c0, 0x163d, 0x2009, 0x0138, 0x200a, 0x7000, 0xa005, 0x00c0,
+ 0x1643, 0x1078, 0x179f, 0x127f, 0x007c, 0x127e, 0x027e, 0x037e,
+ 0x0c7e, 0x007e, 0x2091, 0x2100, 0x007f, 0x047f, 0x037f, 0x027f,
+ 0x0d7e, 0x0c7e, 0x2460, 0x6110, 0x2168, 0x6a62, 0x6b5e, 0xa005,
+ 0x0040, 0x16cf, 0x6808, 0xa005, 0x0040, 0x173c, 0x7000, 0xa005,
+ 0x00c0, 0x1664, 0x0078, 0x16c4, 0x700c, 0x7110, 0xa106, 0x00c0,
+ 0x1745, 0x7004, 0xa406, 0x00c0, 0x16c4, 0x2001, 0x0005, 0x2004,
+ 0xd08c, 0x0040, 0x1681, 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460,
+ 0x6010, 0xa080, 0x0002, 0x2004, 0xa005, 0x0040, 0x173c, 0x0078,
+ 0x165e, 0x2001, 0x0207, 0x2004, 0xd09c, 0x00c0, 0x166d, 0x7804,
+ 0xa084, 0x6000, 0x0040, 0x1692, 0xa086, 0x6000, 0x0040, 0x1692,
+ 0x0078, 0x166d, 0x7100, 0xa186, 0x0002, 0x00c0, 0x16b2, 0x0e7e,
+ 0x2b68, 0x6818, 0x2060, 0x1078, 0x1fea, 0x2804, 0xac70, 0x6034,
+ 0xd09c, 0x00c0, 0x16a7, 0x7108, 0x720c, 0x0078, 0x16a9, 0x7110,
+ 0x7214, 0x6810, 0xa100, 0x6812, 0x6814, 0xa201, 0x6816, 0x0e7f,
+ 0x0078, 0x16b6, 0xa186, 0x0001, 0x00c0, 0x16be, 0x7820, 0x6910,
+ 0xa100, 0x6812, 0x7824, 0x6914, 0xa101, 0x6816, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004, 0x00c0,
+ 0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0078, 0x1745, 0x6808,
+ 0xa005, 0x0040, 0x173c, 0x7000, 0xa005, 0x00c0, 0x16d9, 0x0078,
+ 0x173c, 0x700c, 0x7110, 0xa106, 0x00c0, 0x16e2, 0x7004, 0xa406,
+ 0x00c0, 0x173c, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0040, 0x16f6,
+ 0x047e, 0x1078, 0x18e2, 0x047f, 0x2460, 0x6010, 0xa080, 0x0002,
+ 0x2004, 0xa005, 0x0040, 0x173c, 0x0078, 0x16d3, 0x2001, 0x0207,
+ 0x2004, 0xd09c, 0x00c0, 0x16e2, 0x2001, 0x0005, 0x2004, 0xd08c,
+ 0x00c0, 0x16e8, 0x7804, 0xa084, 0x6000, 0x0040, 0x170d, 0xa086,
+ 0x6000, 0x0040, 0x170d, 0x0078, 0x16e2, 0x7007, 0x0000, 0xa016,
+ 0x2218, 0x7000, 0xa08e, 0x0001, 0x0040, 0x172e, 0xa08e, 0x0002,
+ 0x00c0, 0x173c, 0x0c7e, 0x0e7e, 0x6818, 0x2060, 0x1078, 0x1fea,
+ 0x2804, 0xac70, 0x6034, 0xd09c, 0x00c0, 0x172a, 0x7308, 0x720c,
+ 0x0078, 0x172c, 0x7310, 0x7214, 0x0e7f, 0x0c7f, 0x7820, 0xa318,
+ 0x7824, 0xa211, 0x6810, 0xa300, 0x6812, 0x6814, 0xa201, 0x6816,
+ 0x7803, 0x0004, 0x7003, 0x0000, 0x6100, 0xa18e, 0x0004, 0x00c0,
+ 0x1745, 0x2009, 0x0048, 0x1078, 0x756c, 0x0c7f, 0x0d7f, 0x127f,
+ 0x007c, 0x0f7e, 0x0e7e, 0x027e, 0x037e, 0x047e, 0x1078, 0x1af7,
+ 0x027e, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0000, 0x0040, 0x1790,
+ 0x7004, 0xac06, 0x00c0, 0x1781, 0x2079, 0x0030, 0x7000, 0xa086,
+ 0x0003, 0x0040, 0x1781, 0x7804, 0xd0fc, 0x00c0, 0x177d, 0x2001,
+ 0x0207, 0x2004, 0xd09c, 0x00c0, 0x1763, 0x7803, 0x0004, 0x7804,
+ 0xd0ac, 0x00c0, 0x176f, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003,
+ 0x0003, 0x7007, 0x0000, 0x0078, 0x1781, 0x1078, 0x18e2, 0x0078,
+ 0x1753, 0x157e, 0x20a9, 0x0009, 0x2009, 0xa5e7, 0x2104, 0xac06,
+ 0x00c0, 0x178b, 0x200a, 0xa188, 0x0003, 0x00f0, 0x1786, 0x157f,
+ 0x027f, 0x2001, 0x015d, 0x201c, 0x831a, 0x2302, 0x2001, 0x0138,
+ 0x2202, 0x047f, 0x037f, 0x027f, 0x0e7f, 0x0f7f, 0x007c, 0x700c,
+ 0x7110, 0xa106, 0x00c0, 0x17a7, 0x7003, 0x0000, 0x007c, 0x2104,
+ 0x7006, 0x2060, 0x8108, 0x211c, 0x8108, 0x2124, 0x8108, 0xa182,
+ 0xa602, 0x0048, 0x17b5, 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106,
+ 0x00c0, 0x17be, 0x2001, 0x0138, 0x2003, 0x0008, 0x8cff, 0x00c0,
+ 0x17c5, 0x1078, 0x1b22, 0x0078, 0x1823, 0x6010, 0x2068, 0x2d58,
+ 0x6828, 0xa406, 0x00c0, 0x17d0, 0x682c, 0xa306, 0x0040, 0x17fe,
+ 0x601c, 0xa086, 0x0008, 0x0040, 0x17fe, 0x6024, 0xd0f4, 0x00c0,
+ 0x17fa, 0xd0d4, 0x0040, 0x17f6, 0x6038, 0xa402, 0x6034, 0xa303,
+ 0x0040, 0x17e4, 0x00c8, 0x17f6, 0x643a, 0x6336, 0x6c2a, 0x6b2e,
+ 0x047e, 0x037e, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80,
+ 0xa303, 0x6816, 0x037f, 0x047f, 0x0078, 0x17fa, 0x1078, 0x8d8e,
+ 0x0040, 0x17c1, 0x1078, 0x2035, 0x00c0, 0x17c1, 0x0c7e, 0x7004,
+ 0x2060, 0x6024, 0xc0d4, 0x6026, 0x0c7f, 0x684c, 0xd0f4, 0x0040,
+ 0x180f, 0x6817, 0xffff, 0x6813, 0xffff, 0x0078, 0x17c1, 0x6824,
+ 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034, 0xa0cc, 0x000f,
+ 0x2009, 0x0011, 0x1078, 0x1824, 0x0040, 0x1822, 0x2009, 0x0001,
+ 0x1078, 0x1824, 0x2d58, 0x007c, 0x8aff, 0x0040, 0x18bb, 0xa03e,
+ 0x2730, 0x6850, 0xd0fc, 0x00c0, 0x1846, 0xd0f4, 0x00c0, 0x1856,
+ 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1836, 0x189d, 0x185d,
+ 0x185d, 0x189d, 0x189d, 0x1895, 0x189d, 0x185d, 0x189d, 0x1863,
+ 0x1863, 0x189d, 0x189d, 0x189d, 0x188c, 0x1863, 0xc0fc, 0x6852,
+ 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x0d7e, 0xd99c, 0x0040, 0x18a0,
+ 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0xc0f4, 0x6852,
+ 0x6b6c, 0x6a70, 0x0d7e, 0x0078, 0x18a7, 0x6b08, 0x6a0c, 0x6d00,
+ 0x6c04, 0x0078, 0x18a0, 0x7b0c, 0xd3bc, 0x0040, 0x1884, 0x7004,
+ 0x0e7e, 0x2070, 0x701c, 0x0e7f, 0xa086, 0x0008, 0x00c0, 0x1884,
+ 0x7b08, 0xa39c, 0x0fff, 0x2d20, 0x0d7f, 0x0d7e, 0x6a14, 0x82ff,
+ 0x00c0, 0x187f, 0x6810, 0xa302, 0x0048, 0x187f, 0x6b10, 0x2011,
+ 0x0000, 0x2468, 0x0078, 0x1886, 0x6b10, 0x6a14, 0x6d00, 0x6c04,
+ 0x6f08, 0x6e0c, 0x0078, 0x18a0, 0x0d7f, 0x0d7e, 0x6834, 0xa084,
+ 0x00ff, 0xa086, 0x001e, 0x00c0, 0x189d, 0x0d7f, 0x1078, 0x1fd1,
+ 0x00c0, 0x1824, 0xa00e, 0x0078, 0x18bb, 0x0d7f, 0x1078, 0x1328,
+ 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e, 0x7902, 0x7000,
+ 0x8000, 0x7002, 0x0d7f, 0x6828, 0xa300, 0x682a, 0x682c, 0xa201,
+ 0x682e, 0x2300, 0x6b10, 0xa302, 0x6812, 0x2200, 0x6a14, 0xa203,
+ 0x6816, 0x1078, 0x1fd1, 0x007c, 0x1078, 0x1328, 0x1078, 0x1c52,
+ 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x7003, 0x0000, 0x1078,
+ 0x1ac6, 0x1078, 0x8a44, 0x0040, 0x18db, 0x6808, 0x8001, 0x680a,
+ 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff, 0x682f, 0xffff,
+ 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758, 0x0078, 0x1aad,
+ 0x1078, 0x1328, 0x127e, 0x2091, 0x2100, 0x007e, 0x017e, 0x2b68,
+ 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184, 0x0700, 0x00c0,
+ 0x18be, 0xa184, 0x0003, 0xa086, 0x0003, 0x0040, 0x18e0, 0x7000,
+ 0x0079, 0x18fa, 0x1902, 0x1904, 0x1a06, 0x1a84, 0x1a9b, 0x1902,
+ 0x1902, 0x1902, 0x1078, 0x1328, 0x8001, 0x7002, 0xa184, 0x0880,
+ 0x00c0, 0x1919, 0x8aff, 0x0040, 0x199b, 0x2009, 0x0001, 0x1078,
+ 0x1824, 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078,
+ 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0xd1bc, 0x00c0, 0x1979,
+ 0x027e, 0x037e, 0x7808, 0xd0ec, 0x00c0, 0x1930, 0x7c20, 0x7d24,
+ 0x7e30, 0x7f34, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1932,
+ 0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x2400, 0x686e, 0xa31a, 0x2500,
+ 0x6872, 0xa213, 0x6b2a, 0x6a2e, 0x0c7e, 0x7004, 0x2060, 0x6024,
+ 0xd0f4, 0x00c0, 0x1945, 0x633a, 0x6236, 0x0c7f, 0x2400, 0x6910,
+ 0xa100, 0x6812, 0x2500, 0x6914, 0xa101, 0x6816, 0x037f, 0x027f,
+ 0x2600, 0x681e, 0x2700, 0x6822, 0x1078, 0x1fea, 0x2a00, 0x6826,
+ 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852, 0x6808,
+ 0x8001, 0x680a, 0x00c0, 0x196e, 0x684c, 0xd0e4, 0x0040, 0x196e,
+ 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x7000, 0xa086,
+ 0x0004, 0x0040, 0x1aad, 0x7003, 0x0000, 0x1078, 0x179f, 0x0078,
+ 0x1aad, 0x057e, 0x7d0c, 0xd5bc, 0x00c0, 0x1980, 0x1078, 0xa20c,
+ 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078, 0x4893,
+ 0x0040, 0x198d, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b, 0xffff,
+ 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912, 0x6980,
+ 0x6916, 0x0078, 0x1aad, 0x7004, 0x0c7e, 0x2060, 0x6024, 0x0c7f,
+ 0xd0f4, 0x0040, 0x19a8, 0x6808, 0x8001, 0x680a, 0x0078, 0x1aad,
+ 0x684c, 0xc0f5, 0x684e, 0x7814, 0xa005, 0x00c0, 0x19c0, 0x7003,
+ 0x0000, 0x6808, 0x8001, 0x680a, 0x00c0, 0x19bc, 0x7004, 0x2060,
+ 0x2009, 0x0048, 0x1078, 0x756c, 0x1078, 0x179f, 0x0078, 0x1aad,
+ 0x7814, 0x6910, 0xa102, 0x6812, 0x6914, 0xa183, 0x0000, 0x6816,
+ 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+ 0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+ 0x810b, 0x1078, 0x1b4d, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+ 0x0001, 0x7804, 0xd0fc, 0x0040, 0x19e1, 0x7803, 0x0002, 0x7803,
+ 0x0004, 0x780f, 0x0076, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009,
+ 0x0048, 0x1078, 0x756c, 0x1078, 0x1b81, 0x0040, 0x19bc, 0x7908,
+ 0xd1ec, 0x00c0, 0x19ff, 0x2009, 0x0009, 0x0078, 0x1a01, 0x2009,
+ 0x0019, 0x7902, 0x7003, 0x0003, 0x0078, 0x1aad, 0x8001, 0x7002,
+ 0xd194, 0x0040, 0x1a18, 0x7804, 0xd0fc, 0x00c0, 0x18ea, 0x8aff,
+ 0x0040, 0x1aad, 0x2009, 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad,
+ 0xa184, 0x0880, 0x00c0, 0x1a25, 0x8aff, 0x0040, 0x1aad, 0x2009,
+ 0x0001, 0x1078, 0x1824, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0xd1bc, 0x00c0, 0x1a65, 0x027e, 0x037e, 0x7808, 0xd0ec,
+ 0x00c0, 0x1a38, 0x7803, 0x0009, 0x7003, 0x0004, 0x0078, 0x1a3a,
+ 0x1078, 0x1b9f, 0x6b28, 0x6a2c, 0x1078, 0x1fea, 0x0d7e, 0x0f7e,
+ 0x2d78, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1a55, 0x6808,
+ 0x2008, 0xa31a, 0x680c, 0xa213, 0x7810, 0xa100, 0x7812, 0x690c,
+ 0x7814, 0xa101, 0x7816, 0x0078, 0x1a61, 0x6810, 0x2008, 0xa31a,
+ 0x6814, 0xa213, 0x7810, 0xa100, 0x7812, 0x6914, 0x7814, 0xa101,
+ 0x7816, 0x0f7f, 0x0d7f, 0x0078, 0x1934, 0x057e, 0x7d0c, 0x1078,
+ 0xa20c, 0x057f, 0x1078, 0x1ac6, 0x0f7e, 0x7004, 0x2078, 0x1078,
+ 0x4893, 0x0040, 0x1a76, 0x7824, 0xc0f5, 0x7826, 0x0f7f, 0x682b,
+ 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c, 0x6912,
+ 0x6980, 0x6916, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000,
+ 0x7004, 0xa00d, 0x0040, 0x1a97, 0x6808, 0x8001, 0x680a, 0x00c0,
+ 0x1a97, 0x7004, 0x2060, 0x2009, 0x0048, 0x1078, 0x756c, 0x1078,
+ 0x179f, 0x0078, 0x1aad, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004,
+ 0x2060, 0x6010, 0xa005, 0x0040, 0x1a97, 0x2068, 0x6808, 0x8000,
+ 0x680a, 0x6c28, 0x6b2c, 0x1078, 0x17be, 0x017f, 0x007f, 0x127f,
+ 0x007c, 0x127e, 0x2091, 0x2100, 0x7000, 0xa086, 0x0003, 0x00c0,
+ 0x1ac4, 0x700c, 0x7110, 0xa106, 0x0040, 0x1ac4, 0x20e1, 0x9028,
+ 0x700f, 0xa5e7, 0x7013, 0xa5e7, 0x127f, 0x007c, 0x0c7e, 0x1078,
+ 0x1af7, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x0040, 0x1aed,
+ 0x2104, 0xa005, 0x0040, 0x1ada, 0x2060, 0x6010, 0x2060, 0x6008,
+ 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xa602, 0x0048, 0x1ae2,
+ 0x2009, 0xa5e7, 0x7112, 0x700c, 0xa106, 0x00c0, 0x1acb, 0x2001,
+ 0x0138, 0x2003, 0x0008, 0x0078, 0x1acb, 0x2001, 0x015d, 0x200c,
+ 0x810a, 0x2102, 0x2001, 0x0138, 0x2202, 0x0c7f, 0x007c, 0x2001,
+ 0x0138, 0x2014, 0x2003, 0x0000, 0x2021, 0xb015, 0x2001, 0x0141,
+ 0x201c, 0xd3dc, 0x00c0, 0x1b14, 0x2001, 0x0109, 0x201c, 0xa39c,
+ 0x0048, 0x00c0, 0x1b14, 0x2001, 0x0111, 0x201c, 0x83ff, 0x00c0,
+ 0x1b14, 0x8421, 0x00c0, 0x1afe, 0x007c, 0x2011, 0x0201, 0x2009,
+ 0x003c, 0x2204, 0xa005, 0x00c0, 0x1b21, 0x8109, 0x00c0, 0x1b19,
+ 0x007c, 0x007c, 0x1078, 0x1b15, 0x0040, 0x1b4a, 0x7908, 0xd1ec,
+ 0x00c0, 0x1b3a, 0x1078, 0x1b81, 0x0040, 0x1b3a, 0x7803, 0x0009,
+ 0x7904, 0xd1fc, 0x0040, 0x1b30, 0x7803, 0x0006, 0x1078, 0x1b15,
+ 0x0040, 0x1b4a, 0x780c, 0xd0a4, 0x00c0, 0x1b4a, 0x7007, 0x0000,
+ 0x1078, 0x1b81, 0x0040, 0x1b4c, 0x7803, 0x0019, 0x7003, 0x0003,
+ 0x0078, 0x1b4c, 0x1078, 0x1ac6, 0x007c, 0x0e7e, 0x2071, 0x0200,
+ 0x7808, 0xa084, 0xf000, 0xa10d, 0x1078, 0x1af7, 0x2019, 0x5000,
+ 0x8319, 0x0040, 0x1b6b, 0x2001, 0xa602, 0x2004, 0xa086, 0x0000,
+ 0x0040, 0x1b6b, 0x2001, 0x0021, 0xd0fc, 0x0040, 0x1b58, 0x1078,
+ 0x1e5d, 0x0078, 0x1b56, 0x20e1, 0x7000, 0x7324, 0x7420, 0x7028,
+ 0x7028, 0x7426, 0x7037, 0x0001, 0x810f, 0x712e, 0x702f, 0x0100,
+ 0x7037, 0x0008, 0x7326, 0x7422, 0x2001, 0x0138, 0x2202, 0x0e7f,
+ 0x007c, 0x7908, 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0048, 0x1b8c,
+ 0xa085, 0x0001, 0x0078, 0x1b9e, 0x2001, 0x020a, 0x81ff, 0x0040,
+ 0x1b97, 0x20e1, 0x6000, 0x200c, 0x200c, 0x200c, 0x200c, 0x20e1,
+ 0x7000, 0x200c, 0x200c, 0x7003, 0x0000, 0xa006, 0x007c, 0x7c20,
+ 0x7d24, 0x7e30, 0x7f34, 0x700c, 0x7110, 0xa106, 0x0040, 0x1c24,
+ 0x7004, 0x017e, 0x210c, 0xa106, 0x017f, 0x0040, 0x1c24, 0x0d7e,
+ 0x0c7e, 0x216c, 0x2d00, 0xa005, 0x0040, 0x1c22, 0x6824, 0xd0d4,
+ 0x00c0, 0x1c22, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0040, 0x1bec,
+ 0x8108, 0x2104, 0x6b2c, 0xa306, 0x00c0, 0x1c22, 0x8108, 0x2104,
+ 0x6a28, 0xa206, 0x00c0, 0x1c22, 0x6850, 0xc0fc, 0xc0f5, 0x6852,
+ 0x686c, 0x7822, 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836,
+ 0x6818, 0x2060, 0x6034, 0xd09c, 0x0040, 0x1be7, 0x6830, 0x2004,
+ 0xac68, 0x6808, 0x783a, 0x680c, 0x783e, 0x0078, 0x1c20, 0xa006,
+ 0x783a, 0x783e, 0x0078, 0x1c20, 0x8108, 0x2104, 0xa005, 0x00c0,
+ 0x1c22, 0x8108, 0x2104, 0xa005, 0x00c0, 0x1c22, 0x6850, 0xc0f5,
+ 0x6852, 0x6830, 0x2004, 0x6918, 0xa160, 0xa180, 0x000d, 0x2004,
+ 0xd09c, 0x00c0, 0x1c12, 0x6008, 0x7822, 0x686e, 0x600c, 0x7826,
+ 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006, 0x783a, 0x783e,
+ 0x0078, 0x1c20, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826, 0x6872,
+ 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c, 0x783e,
+ 0x7803, 0x0011, 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e, 0x017e,
+ 0x027e, 0x2071, 0xa5e1, 0x2079, 0x0030, 0x2011, 0x0050, 0x7000,
+ 0xa086, 0x0000, 0x0040, 0x1c4d, 0x8211, 0x0040, 0x1c4b, 0x2001,
+ 0x0005, 0x2004, 0xd08c, 0x0040, 0x1c34, 0x7904, 0xa18c, 0x0780,
+ 0x017e, 0x1078, 0x18e2, 0x017f, 0x81ff, 0x00c0, 0x1c4b, 0x2011,
+ 0x0050, 0x0078, 0x1c2f, 0xa085, 0x0001, 0x027f, 0x017f, 0x0e7f,
+ 0x0f7f, 0x007c, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+ 0x0040, 0x1ca3, 0x8109, 0x00c0, 0x1c56, 0x2009, 0x0100, 0x210c,
+ 0xa18a, 0x0003, 0x1048, 0x1328, 0x1078, 0x1f75, 0x0e7e, 0x0f7e,
+ 0x2071, 0xa5d0, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0040,
+ 0x1c9b, 0x7800, 0x007e, 0x7820, 0x007e, 0x7830, 0x007e, 0x7834,
+ 0x007e, 0x7838, 0x007e, 0x783c, 0x007e, 0x7803, 0x0004, 0x7823,
+ 0x0000, 0x0005, 0x0005, 0x2079, 0x0030, 0x7804, 0xd0ac, 0x10c0,
+ 0x1328, 0x2079, 0x0010, 0x007f, 0x783e, 0x007f, 0x783a, 0x007f,
+ 0x7836, 0x007f, 0x7832, 0x007f, 0x7822, 0x007f, 0x7802, 0x0f7f,
+ 0x0e7f, 0x0078, 0x1ca1, 0x0f7f, 0x0e7f, 0x7804, 0xd0ac, 0x10c0,
+ 0x1328, 0x1078, 0x61d3, 0x007c, 0x0e7e, 0x2071, 0xa602, 0x7003,
+ 0x0000, 0x0e7f, 0x007c, 0x0d7e, 0xa280, 0x0004, 0x206c, 0x694c,
+ 0xd1dc, 0x00c0, 0x1d26, 0x6934, 0xa184, 0x0007, 0x0079, 0x1cb8,
+ 0x1cc0, 0x1d11, 0x1cc0, 0x1cc0, 0x1cc0, 0x1cf6, 0x1cd3, 0x1cc2,
+ 0x1078, 0x1328, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+ 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+ 0x6958, 0x0078, 0x1d19, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+ 0x00c0, 0x1cc0, 0x684c, 0xd0b4, 0x0040, 0x1e34, 0x6860, 0x682e,
+ 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880, 0x680e,
+ 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+ 0x2015, 0x2004, 0x6832, 0x6958, 0x0078, 0x1d22, 0xa18c, 0x00ff,
+ 0xa186, 0x0015, 0x00c0, 0x1d26, 0x684c, 0xd0b4, 0x0040, 0x1e34,
+ 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080,
+ 0x2015, 0x2004, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0078,
+ 0x1d22, 0x684c, 0xd0b4, 0x0040, 0x18bc, 0x6958, 0xa006, 0x682e,
+ 0x682a, 0x2d00, 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2015,
+ 0x2004, 0x6832, 0x6926, 0x684c, 0xc0dd, 0x684e, 0x0d7f, 0x007c,
+ 0x0f7e, 0x2079, 0x0020, 0x7804, 0xd0fc, 0x10c0, 0x1e5d, 0x0e7e,
+ 0x0d7e, 0x2071, 0xa602, 0x7000, 0xa005, 0x00c0, 0x1dab, 0x0c7e,
+ 0x7206, 0xa280, 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004,
+ 0x6818, 0x0d7e, 0x2068, 0x686c, 0x7812, 0x6890, 0x0f7e, 0x20e1,
+ 0x9040, 0x2079, 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6,
+ 0x0f7f, 0x0d7f, 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+ 0x2040, 0x6034, 0xa0cc, 0x000f, 0x6908, 0x2001, 0x04fd, 0x2004,
+ 0xa086, 0x0007, 0x0040, 0x1d6d, 0xa184, 0x0007, 0x0040, 0x1d6d,
+ 0x017e, 0x2009, 0x0008, 0xa102, 0x017f, 0xa108, 0x791a, 0x7116,
+ 0x701e, 0x680c, 0xa081, 0x0000, 0x781e, 0x701a, 0xa006, 0x700e,
+ 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x00c0, 0x1d84, 0x6928,
+ 0x6810, 0xa106, 0x0040, 0x1d91, 0x037e, 0x047e, 0x6b14, 0x6c10,
+ 0x1078, 0x2035, 0x047f, 0x037f, 0x0040, 0x1d91, 0x0c7f, 0x0078,
+ 0x1dab, 0x8aff, 0x00c0, 0x1d99, 0x0c7f, 0xa085, 0x0001, 0x0078,
+ 0x1dab, 0x127e, 0x2091, 0x8000, 0x2079, 0x0020, 0x2009, 0x0001,
+ 0x1078, 0x1daf, 0x0040, 0x1da8, 0x2009, 0x0001, 0x1078, 0x1daf,
+ 0x127f, 0x0c7f, 0xa006, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x077e,
+ 0x067e, 0x057e, 0x047e, 0x037e, 0x027e, 0x8aff, 0x0040, 0x1e2d,
+ 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0048, 0x1e2c,
+ 0xa705, 0x0040, 0x1e2c, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x00c0,
+ 0x1ddf, 0x0d7e, 0x2804, 0xac68, 0x2900, 0x0079, 0x1dcf, 0x1e0e,
+ 0x1def, 0x1def, 0x1e0e, 0x1e0e, 0x1e06, 0x1e0e, 0x1def, 0x1e0e,
+ 0x1df5, 0x1df5, 0x1e0e, 0x1e0e, 0x1e0e, 0x1dfd, 0x1df5, 0xc0fc,
+ 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0040, 0x1e12,
+ 0x0d7e, 0x2804, 0xac68, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x6b08,
+ 0x6a0c, 0x6d00, 0x6c04, 0x0078, 0x1e11, 0x6b10, 0x6a14, 0x6d00,
+ 0x6c04, 0x6f08, 0x6e0c, 0x0078, 0x1e11, 0x0d7f, 0x0d7e, 0x6834,
+ 0xa084, 0x00ff, 0xa086, 0x001e, 0x00c0, 0x1e0e, 0x0d7f, 0x1078,
+ 0x1fd1, 0x00c0, 0x1db5, 0xa00e, 0x0078, 0x1e2d, 0x0d7f, 0x1078,
+ 0x1328, 0x0d7f, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a, 0x7e3e,
+ 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a, 0x682c,
+ 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201, 0x7012,
+ 0x1078, 0x1fd1, 0x0078, 0x1e2d, 0xa006, 0x027f, 0x037f, 0x047f,
+ 0x057f, 0x067f, 0x077f, 0x007c, 0x1078, 0x1328, 0x027e, 0x2001,
+ 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0x7004, 0x2060, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44,
+ 0x0040, 0x1e4d, 0x6850, 0xc0bd, 0x6852, 0x0d7f, 0x1078, 0x8758,
+ 0x20e1, 0x9040, 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc,
+ 0x1078, 0x61d3, 0x027f, 0x0078, 0x1f29, 0x127e, 0x2091, 0x2200,
+ 0x007e, 0x017e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x2079, 0x0020,
+ 0x2071, 0xa602, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002,
+ 0xa184, 0x0700, 0x00c0, 0x1e36, 0x7000, 0x0079, 0x1e77, 0x1f29,
+ 0x1e7b, 0x1ef6, 0x1f27, 0x8001, 0x7002, 0xd19c, 0x00c0, 0x1e8f,
+ 0x8aff, 0x0040, 0x1eae, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0040,
+ 0x1f29, 0x2009, 0x0001, 0x1078, 0x1daf, 0x0078, 0x1f29, 0x7803,
+ 0x0004, 0xd194, 0x0040, 0x1e9f, 0x6850, 0xc0fc, 0x6852, 0x8aff,
+ 0x00c0, 0x1ea4, 0x684c, 0xc0f5, 0x684e, 0x0078, 0x1ea4, 0x1078,
+ 0x1fea, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826, 0x2c00, 0x681a,
+ 0x2800, 0x6832, 0x7003, 0x0000, 0x0078, 0x1f29, 0x711c, 0x81ff,
+ 0x0040, 0x1ec4, 0x7918, 0x7922, 0x7827, 0x0000, 0x7803, 0x0001,
+ 0x7000, 0x8000, 0x7002, 0x700c, 0xa100, 0x700e, 0x7010, 0xa081,
+ 0x0000, 0x7012, 0x0078, 0x1f29, 0x0f7e, 0x027e, 0x781c, 0x007e,
+ 0x7818, 0x007e, 0x2079, 0x0100, 0x7a14, 0xa284, 0x0004, 0xa085,
+ 0x0012, 0x7816, 0x037e, 0x2019, 0x1000, 0x8319, 0x1040, 0x1328,
+ 0x7820, 0xd0bc, 0x00c0, 0x1ed5, 0x037f, 0x79c8, 0x007f, 0xa102,
+ 0x017f, 0x007e, 0x017e, 0x79c4, 0x007f, 0xa103, 0x78c6, 0x007f,
+ 0x78ca, 0xa284, 0x0004, 0xa085, 0x0012, 0x7816, 0x027f, 0x0f7f,
+ 0x7803, 0x0008, 0x7003, 0x0000, 0x0078, 0x1f29, 0x8001, 0x7002,
+ 0xd194, 0x0040, 0x1f0b, 0x7804, 0xd0fc, 0x00c0, 0x1e6d, 0xd19c,
+ 0x00c0, 0x1f25, 0x8aff, 0x0040, 0x1f29, 0x2009, 0x0001, 0x1078,
+ 0x1daf, 0x0078, 0x1f29, 0x027e, 0x037e, 0x6b28, 0x6a2c, 0x1078,
+ 0x1fea, 0x0d7e, 0x2804, 0xac68, 0x6034, 0xd09c, 0x00c0, 0x1f1e,
+ 0x6808, 0xa31a, 0x680c, 0xa213, 0x0078, 0x1f22, 0x6810, 0xa31a,
+ 0x6814, 0xa213, 0x0d7f, 0x0078, 0x1e9f, 0x0078, 0x1e9f, 0x1078,
+ 0x1328, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x017f, 0x007f, 0x127f,
+ 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0xa602, 0x7000, 0xa086, 0x0000,
+ 0x0040, 0x1f72, 0x2079, 0x0020, 0x017e, 0x2009, 0x0207, 0x210c,
+ 0xd194, 0x0040, 0x1f4f, 0x2009, 0x020c, 0x210c, 0xa184, 0x0003,
+ 0x0040, 0x1f4f, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102, 0x2009,
+ 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x00c0, 0x1f5a,
+ 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0040, 0x1f3d, 0x1078, 0x1e5d,
+ 0x7000, 0xa086, 0x0000, 0x00c0, 0x1f3d, 0x017f, 0x7803, 0x0004,
+ 0x7804, 0xd0ac, 0x00c0, 0x1f68, 0x20e1, 0x9040, 0x7803, 0x0002,
+ 0x7003, 0x0000, 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x0c7e, 0x0d7e,
+ 0x0e7e, 0x0f7e, 0x2071, 0xa602, 0x2079, 0x0020, 0x7000, 0xa086,
+ 0x0000, 0x0040, 0x1fae, 0x7004, 0x2060, 0x6010, 0x2068, 0x1078,
+ 0x8a44, 0x0040, 0x1f98, 0x6850, 0xc0b5, 0x6852, 0x680c, 0x7a1c,
+ 0xa206, 0x00c0, 0x1f98, 0x6808, 0x7a18, 0xa206, 0x0040, 0x1fb4,
+ 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0x7004, 0x2060, 0x1078, 0x8758, 0x20e1, 0x9040,
+ 0x1078, 0x719a, 0x2011, 0x0000, 0x1078, 0x6efc, 0x0f7f, 0x0e7f,
+ 0x0d7f, 0x0c7f, 0x027f, 0x007c, 0x6810, 0x6a14, 0xa205, 0x00c0,
+ 0x1f98, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x1078, 0x1cab, 0x2001,
+ 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0x2069, 0xa5ab, 0x6833, 0x0000, 0x683f, 0x0000, 0x0078,
+ 0x1fae, 0x8840, 0x2804, 0xa005, 0x00c0, 0x1fe5, 0x6004, 0xa005,
+ 0x0040, 0x1fe7, 0x681a, 0x2060, 0x6034, 0xa084, 0x000f, 0xa080,
+ 0x2015, 0x2044, 0x88ff, 0x1040, 0x1328, 0x8a51, 0x007c, 0x2051,
+ 0x0000, 0x007c, 0x8a50, 0x8841, 0x2804, 0xa005, 0x00c0, 0x2004,
+ 0x2c00, 0xad06, 0x0040, 0x1ff9, 0x6000, 0xa005, 0x00c0, 0x1ff9,
+ 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080, 0x2025,
+ 0x2044, 0x88ff, 0x1040, 0x1328, 0x007c, 0x0000, 0x0011, 0x0015,
+ 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f, 0x0015,
+ 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x200a, 0x2006,
+ 0x0000, 0x0000, 0x2014, 0x0000, 0x200a, 0x0000, 0x2011, 0x200e,
+ 0x0000, 0x0000, 0x0000, 0x2014, 0x2011, 0x0000, 0x200c, 0x200c,
+ 0x0000, 0x0000, 0x2014, 0x0000, 0x200c, 0x0000, 0x2012, 0x2012,
+ 0x0000, 0x0000, 0x0000, 0x2014, 0x2012, 0x0a7e, 0x097e, 0x087e,
+ 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0040, 0x20d8, 0x2d60, 0x6034,
+ 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0xa986, 0x0007, 0x0040, 0x2050,
+ 0xa986, 0x000e, 0x0040, 0x2050, 0xa986, 0x000f, 0x00c0, 0x2054,
+ 0x605c, 0xa422, 0x6060, 0xa31a, 0x2804, 0xa045, 0x00c0, 0x2062,
+ 0x0050, 0x205c, 0x0078, 0x20d8, 0x6004, 0xa065, 0x0040, 0x20d8,
+ 0x0078, 0x203f, 0x2804, 0xa005, 0x0040, 0x2080, 0xac68, 0xd99c,
+ 0x00c0, 0x2070, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0078, 0x2074,
+ 0x6810, 0xa422, 0x6814, 0xa31b, 0x0048, 0x209f, 0x2300, 0xa405,
+ 0x0040, 0x2086, 0x8a51, 0x0040, 0x20d8, 0x8840, 0x0078, 0x2062,
+ 0x6004, 0xa065, 0x0040, 0x20d8, 0x0078, 0x203f, 0x8a51, 0x0040,
+ 0x20d8, 0x8840, 0x2804, 0xa005, 0x00c0, 0x2099, 0x6004, 0xa065,
+ 0x0040, 0x20d8, 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2015, 0x2804,
+ 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852, 0x0078, 0x20cc, 0x8422,
+ 0x8420, 0x831a, 0xa399, 0x0000, 0x0d7e, 0x2b68, 0x6c6e, 0x6b72,
+ 0x0d7f, 0xd99c, 0x00c0, 0x20ba, 0x6908, 0x2400, 0xa122, 0x690c,
+ 0x2300, 0xa11b, 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319,
+ 0x0078, 0x20c6, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+ 0x1048, 0x1328, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+ 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+ 0x2a00, 0x6826, 0x007f, 0x007f, 0x007f, 0xa006, 0x0078, 0x20dd,
+ 0x087f, 0x097f, 0x0a7f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0005,
+ 0x2004, 0xa084, 0x0007, 0x0079, 0x20e5, 0x20ed, 0x20ee, 0x20f1,
+ 0x20f4, 0x20f9, 0x20fc, 0x2101, 0x2106, 0x007c, 0x1078, 0x1e5d,
+ 0x007c, 0x1078, 0x18e2, 0x007c, 0x1078, 0x18e2, 0x1078, 0x1e5d,
+ 0x007c, 0x1078, 0x14b0, 0x007c, 0x1078, 0x1e5d, 0x1078, 0x14b0,
+ 0x007c, 0x1078, 0x18e2, 0x1078, 0x14b0, 0x007c, 0x1078, 0x18e2,
+ 0x1078, 0x1e5d, 0x1078, 0x14b0, 0x007c, 0x127e, 0x2091, 0x2300,
+ 0x2079, 0x0200, 0x2071, 0xa880, 0x2069, 0xa300, 0x2009, 0x0004,
+ 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5, 0x781b, 0x0002, 0x20e1,
+ 0x8700, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x781c, 0xa084,
+ 0x0007, 0x0079, 0x212b, 0x214f, 0x2133, 0x2137, 0x213b, 0x2141,
+ 0x2145, 0x2149, 0x214d, 0x1078, 0x5372, 0x0078, 0x214f, 0x1078,
+ 0x53b3, 0x0078, 0x214f, 0x1078, 0x5372, 0x1078, 0x53b3, 0x0078,
+ 0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x0078,
+ 0x214f, 0x1078, 0x2151, 0x0078, 0x214f, 0x1078, 0x2151, 0x127f,
+ 0x007c, 0x007e, 0x017e, 0x027e, 0x7930, 0xa184, 0x0003, 0x0040,
+ 0x215d, 0x20e1, 0x9040, 0x0078, 0x2186, 0xa184, 0x0030, 0x0040,
+ 0x216e, 0x6a00, 0xa286, 0x0003, 0x00c0, 0x2168, 0x0078, 0x216a,
+ 0x1078, 0x4171, 0x20e1, 0x9010, 0x0078, 0x2186, 0xa184, 0x00c0,
+ 0x0040, 0x2180, 0x0e7e, 0x037e, 0x047e, 0x057e, 0x2071, 0xa5e1,
+ 0x1078, 0x1ac6, 0x057f, 0x047f, 0x037f, 0x0e7f, 0x0078, 0x2186,
+ 0xa184, 0x0300, 0x0040, 0x2186, 0x20e1, 0x9020, 0x7932, 0x027f,
+ 0x017f, 0x007f, 0x007c, 0x017e, 0x0e7e, 0x0f7e, 0x2071, 0xa300,
+ 0x7128, 0x2001, 0xa58f, 0x2102, 0x2001, 0xa597, 0x2102, 0xa182,
+ 0x0211, 0x00c8, 0x219f, 0x2009, 0x0008, 0x0078, 0x21c9, 0xa182,
+ 0x0259, 0x00c8, 0x21a7, 0x2009, 0x0007, 0x0078, 0x21c9, 0xa182,
+ 0x02c1, 0x00c8, 0x21af, 0x2009, 0x0006, 0x0078, 0x21c9, 0xa182,
+ 0x0349, 0x00c8, 0x21b7, 0x2009, 0x0005, 0x0078, 0x21c9, 0xa182,
+ 0x0421, 0x00c8, 0x21bf, 0x2009, 0x0004, 0x0078, 0x21c9, 0xa182,
+ 0x0581, 0x00c8, 0x21c7, 0x2009, 0x0003, 0x0078, 0x21c9, 0x2009,
+ 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x1078, 0x24b5,
+ 0x0f7f, 0x0e7f, 0x017f, 0x007c, 0x127e, 0x2091, 0x2200, 0x2061,
+ 0x0100, 0x2071, 0xa300, 0x6024, 0x6026, 0x6053, 0x0030, 0x6033,
+ 0x00ef, 0x60e7, 0x0000, 0x60eb, 0x00ef, 0x60e3, 0x0008, 0x604b,
+ 0xf7f7, 0x6043, 0x0000, 0x602f, 0x0080, 0x602f, 0x0000, 0x6007,
+ 0x0eaf, 0x600f, 0x00ff, 0x602b, 0x002f, 0x127f, 0x007c, 0x2001,
+ 0xa32f, 0x2003, 0x0000, 0x2001, 0xa32e, 0x2003, 0x0001, 0x007c,
+ 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e, 0x6124, 0xa184,
+ 0x002c, 0x00c0, 0x220f, 0xa184, 0x0007, 0x0079, 0x2215, 0xa195,
+ 0x0004, 0xa284, 0x0007, 0x0079, 0x2215, 0x2241, 0x221d, 0x2221,
+ 0x2225, 0x222b, 0x222f, 0x2235, 0x223b, 0x1078, 0x5ad2, 0x0078,
+ 0x2241, 0x1078, 0x5bc1, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+ 0x5ad2, 0x0078, 0x2241, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078,
+ 0x5ad2, 0x1078, 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078,
+ 0x2246, 0x0078, 0x2241, 0x1078, 0x5bc1, 0x1078, 0x5ad2, 0x1078,
+ 0x2246, 0x027f, 0x017f, 0x007f, 0x127f, 0x007c, 0x6124, 0xd1ac,
+ 0x0040, 0x2342, 0x017e, 0x047e, 0x0c7e, 0x644c, 0xa486, 0xf0f0,
+ 0x00c0, 0x2259, 0x2061, 0x0100, 0x644a, 0x6043, 0x0090, 0x6043,
+ 0x0010, 0x74c2, 0xa48c, 0xff00, 0x7034, 0xd084, 0x0040, 0x2271,
+ 0xa186, 0xf800, 0x00c0, 0x2271, 0x7038, 0xd084, 0x00c0, 0x2271,
+ 0xc085, 0x703a, 0x037e, 0x2418, 0x2011, 0x8016, 0x1078, 0x3579,
+ 0x037f, 0xa196, 0xff00, 0x0040, 0x22b3, 0x6030, 0xa084, 0x00ff,
+ 0x810f, 0xa116, 0x0040, 0x22b3, 0x7130, 0xd184, 0x00c0, 0x22b3,
+ 0x2011, 0xa352, 0x2214, 0xd2ec, 0x0040, 0x228e, 0xc18d, 0x7132,
+ 0x2011, 0xa352, 0x2214, 0xd2ac, 0x00c0, 0x22b3, 0x6240, 0xa294,
+ 0x0010, 0x0040, 0x229a, 0x6248, 0xa294, 0xff00, 0xa296, 0xff00,
+ 0x0040, 0x22b3, 0x7030, 0xd08c, 0x0040, 0x2305, 0x7034, 0xd08c,
+ 0x00c0, 0x22aa, 0x2001, 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305,
+ 0xc1ad, 0x2102, 0x037e, 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579,
+ 0x037f, 0x0078, 0x2305, 0x7034, 0xd08c, 0x00c0, 0x22bf, 0x2001,
+ 0xa30c, 0x200c, 0xd1ac, 0x00c0, 0x2305, 0xc1ad, 0x2102, 0x037e,
+ 0x73c0, 0x2011, 0x8013, 0x1078, 0x3579, 0x037f, 0x7130, 0xc185,
+ 0x7132, 0x2011, 0xa352, 0x220c, 0xd1a4, 0x0040, 0x22e9, 0x017e,
+ 0x2009, 0x0001, 0x2011, 0x0100, 0x1078, 0x5a6d, 0x2019, 0x000e,
+ 0x1078, 0x9e3b, 0xa484, 0x00ff, 0xa080, 0x293f, 0x200c, 0xa18c,
+ 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x1078, 0x9ec0,
+ 0x017f, 0xd1ac, 0x00c0, 0x22f6, 0x017e, 0x2009, 0x0000, 0x2019,
+ 0x0004, 0x1078, 0x27e2, 0x017f, 0x0078, 0x2305, 0x157e, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x1078, 0x4501, 0x00c0, 0x2301, 0x1078,
+ 0x4235, 0x8108, 0x00f0, 0x22fb, 0x157f, 0x0c7f, 0x047f, 0x0f7e,
+ 0x2079, 0xa5be, 0x783c, 0xa086, 0x0000, 0x0040, 0x2317, 0x6027,
+ 0x0004, 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x0000, 0x0f7f,
+ 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011, 0x0002, 0x1078, 0x6efc,
+ 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e, 0x2019, 0x0000, 0x1078,
+ 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x017f, 0x2001, 0xa300, 0x2014,
+ 0xa296, 0x0004, 0x00c0, 0x233a, 0xd19c, 0x00c0, 0x233a, 0x6228,
+ 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xa321, 0x2003, 0x0000,
+ 0x6027, 0x0020, 0xd194, 0x0040, 0x2426, 0x0f7e, 0x2079, 0xa5be,
+ 0x783c, 0xa086, 0x0001, 0x00c0, 0x2366, 0x017e, 0x6027, 0x0004,
+ 0x783f, 0x0000, 0x2079, 0x0140, 0x7803, 0x1000, 0x7803, 0x0000,
+ 0x2079, 0xa5ab, 0x7807, 0x0000, 0x7833, 0x0000, 0x1078, 0x6109,
+ 0x1078, 0x61d3, 0x017f, 0x0f7f, 0x0078, 0x2426, 0x0f7f, 0x017e,
+ 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x2371, 0x017e, 0x1078, 0x728a,
+ 0x017f, 0x6220, 0xd2b4, 0x0040, 0x23dc, 0x1078, 0x595a, 0x1078,
+ 0x6c41, 0x6027, 0x0004, 0x0f7e, 0x2019, 0xa5b4, 0x2304, 0xa07d,
+ 0x0040, 0x23b2, 0x7804, 0xa086, 0x0032, 0x00c0, 0x23b2, 0x0d7e,
+ 0x0c7e, 0x0e7e, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+ 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x00c0,
+ 0x2396, 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e,
+ 0x628a, 0x1078, 0x6010, 0x1078, 0x6109, 0x7810, 0x2070, 0x7037,
+ 0x0103, 0x2f60, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0d7f, 0x0f7f,
+ 0x017f, 0x007c, 0x0f7f, 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084,
+ 0x4000, 0x0040, 0x23bf, 0x6803, 0x1000, 0x6803, 0x0000, 0x0d7f,
+ 0x0c7e, 0x2061, 0xa5ab, 0x6028, 0xa09a, 0x00c8, 0x00c8, 0x23cf,
+ 0x8000, 0x602a, 0x0c7f, 0x1078, 0x6c33, 0x0078, 0x2425, 0x2019,
+ 0xa5b4, 0x2304, 0xa065, 0x0040, 0x23d9, 0x2009, 0x0027, 0x1078,
+ 0x756c, 0x0c7f, 0x0078, 0x2425, 0xd2bc, 0x0040, 0x2425, 0x1078,
+ 0x5967, 0x6017, 0x0010, 0x6027, 0x0004, 0x0d7e, 0x2069, 0x0140,
+ 0x6804, 0xa084, 0x4000, 0x0040, 0x23f1, 0x6803, 0x1000, 0x6803,
+ 0x0000, 0x0d7f, 0x0c7e, 0x2061, 0xa5ab, 0x6044, 0xa09a, 0x00c8,
+ 0x00c8, 0x2414, 0x8000, 0x6046, 0x603c, 0x0c7f, 0xa005, 0x0040,
+ 0x2425, 0x2009, 0x07d0, 0x1078, 0x595f, 0xa080, 0x0007, 0x2004,
+ 0xa086, 0x0006, 0x00c0, 0x2410, 0x6017, 0x0012, 0x0078, 0x2425,
+ 0x6017, 0x0016, 0x0078, 0x2425, 0x037e, 0x2019, 0x0001, 0x1078,
+ 0x6e6c, 0x037f, 0x2019, 0xa5ba, 0x2304, 0xa065, 0x0040, 0x2424,
+ 0x2009, 0x004f, 0x1078, 0x756c, 0x0c7f, 0x017f, 0xd19c, 0x0040,
+ 0x247c, 0x7034, 0xd0ac, 0x00c0, 0x2457, 0x017e, 0x157e, 0x6027,
+ 0x0008, 0x602f, 0x0020, 0x20a9, 0x000a, 0x00f0, 0x2435, 0x602f,
+ 0x0000, 0x6150, 0xa185, 0x1400, 0x6052, 0x20a9, 0x0320, 0x00e0,
+ 0x243f, 0x2091, 0x6000, 0x6020, 0xd09c, 0x00c0, 0x244e, 0x157f,
+ 0x6152, 0x017f, 0x6027, 0x0008, 0x0078, 0x247c, 0x1078, 0x250d,
+ 0x00f0, 0x243f, 0x157f, 0x6152, 0x017f, 0x6027, 0x0008, 0x017e,
+ 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x1078, 0x6ef2, 0x2011,
+ 0x0002, 0x1078, 0x6efc, 0x1078, 0x6dda, 0x1078, 0x595a, 0x037e,
+ 0x2019, 0x0000, 0x1078, 0x6e6c, 0x037f, 0x60e3, 0x0000, 0x1078,
+ 0xa22a, 0x1078, 0xa248, 0x2001, 0xa300, 0x2003, 0x0004, 0x6027,
+ 0x0008, 0x1078, 0x1246, 0x017f, 0xa18c, 0xffd0, 0x6126, 0x007c,
+ 0x007e, 0x017e, 0x027e, 0x0e7e, 0x0f7e, 0x127e, 0x2091, 0x8000,
+ 0x2071, 0xa300, 0x71b8, 0x70ba, 0xa116, 0x0040, 0x24ae, 0x81ff,
+ 0x0040, 0x2498, 0x2011, 0x8011, 0x1078, 0x3579, 0x0078, 0x24ae,
+ 0x2011, 0x8012, 0x1078, 0x3579, 0x2001, 0xa371, 0x2004, 0xd0fc,
+ 0x00c0, 0x24ae, 0x037e, 0x0c7e, 0x2061, 0x0100, 0x2019, 0x0028,
+ 0x2009, 0x0000, 0x1078, 0x27e2, 0x0c7f, 0x037f, 0x127f, 0x0f7f,
+ 0x0e7f, 0x027f, 0x017f, 0x007f, 0x007c, 0x0c7e, 0x0f7e, 0x007e,
+ 0x027e, 0x2061, 0x0100, 0xa190, 0x24d1, 0x2204, 0x60f2, 0x2011,
+ 0x24de, 0x6000, 0xa082, 0x0003, 0x00c8, 0x24ca, 0x2001, 0x00ff,
+ 0x0078, 0x24cb, 0x2204, 0x60ee, 0x027f, 0x007f, 0x0f7f, 0x0c7f,
+ 0x007c, 0x0840, 0x0840, 0x0840, 0x0580, 0x0420, 0x0348, 0x02c0,
+ 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8, 0x01a8, 0x0140, 0x00f8,
+ 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c, 0x00ff, 0x2130, 0xa094,
+ 0xff00, 0x00c0, 0x24ee, 0x81ff, 0x0040, 0x24f2, 0x1078, 0x5623,
+ 0x0078, 0x24f9, 0xa080, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+ 0xa006, 0x007c, 0xa080, 0x293f, 0x200c, 0xa18c, 0x00ff, 0x007c,
+ 0x0c7e, 0x2061, 0xa300, 0x6030, 0x0040, 0x2509, 0xc09d, 0x0078,
+ 0x250a, 0xc09c, 0x6032, 0x0c7f, 0x007c, 0x007e, 0x157e, 0x0f7e,
+ 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854, 0xd08c, 0x00c0, 0x251a,
+ 0x00f0, 0x2514, 0x0f7f, 0x157f, 0x007f, 0x007c, 0x0c7e, 0x007e,
+ 0x2061, 0x0100, 0x6030, 0x007e, 0x6048, 0x007e, 0x60e4, 0x007e,
+ 0x60e8, 0x007e, 0x6050, 0x007e, 0x60f0, 0x007e, 0x60ec, 0x007e,
+ 0x600c, 0x007e, 0x6004, 0x007e, 0x6028, 0x007e, 0x60e0, 0x007e,
+ 0x602f, 0x0100, 0x602f, 0x0000, 0x0005, 0x0005, 0x0005, 0x0005,
+ 0x602f, 0x0040, 0x602f, 0x0000, 0x007f, 0x60e2, 0x007f, 0x602a,
+ 0x007f, 0x6006, 0x007f, 0x600e, 0x007f, 0x60ee, 0x007f, 0x60f2,
+ 0x007f, 0x6052, 0x007f, 0x60ea, 0x007f, 0x60e6, 0x007f, 0x604a,
+ 0x007f, 0x6032, 0x007f, 0x0c7f, 0x007c, 0x257d, 0x2581, 0x2585,
+ 0x258b, 0x2591, 0x2597, 0x259d, 0x25a5, 0x25ad, 0x25b3, 0x25b9,
+ 0x25c1, 0x25c9, 0x25d1, 0x25d9, 0x25e3, 0x25ed, 0x25ed, 0x25ed,
+ 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed,
+ 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x25ed, 0x107e, 0x007e, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+ 0x2200, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e,
+ 0x007e, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+ 0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+ 0x2200, 0x1078, 0x20de, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078,
+ 0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2123, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x2123, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x1078, 0x20de, 0x1078, 0x2123, 0x0078,
+ 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078, 0x20de, 0x1078,
+ 0x2123, 0x0078, 0x2606, 0x107e, 0x007e, 0x1078, 0x2200, 0x1078,
+ 0x20de, 0x1078, 0x2123, 0x0078, 0x2606, 0x0005, 0x0078, 0x25ed,
+ 0xb084, 0x003c, 0x8004, 0x8004, 0x0079, 0x25f6, 0x2606, 0x2583,
+ 0x2587, 0x258d, 0x2593, 0x2599, 0x259f, 0x25a7, 0x25af, 0x25b5,
+ 0x25bb, 0x25c3, 0x25cb, 0x25d3, 0x25db, 0x25e5, 0x0008, 0x25f0,
+ 0x007f, 0x107f, 0x2091, 0x8001, 0x007c, 0x0c7e, 0x027e, 0x047e,
+ 0x2021, 0x0000, 0x1078, 0x4897, 0x00c0, 0x2705, 0x70c8, 0xd09c,
+ 0x0040, 0x2624, 0xd084, 0x00c0, 0x2624, 0xd0bc, 0x00c0, 0x2705,
+ 0x1078, 0x2709, 0x0078, 0x2705, 0xd094, 0x0040, 0x262b, 0x7093,
+ 0xffff, 0x0078, 0x2705, 0x2001, 0x010c, 0x203c, 0x7280, 0xd284,
+ 0x0040, 0x2694, 0xd28c, 0x00c0, 0x2694, 0x037e, 0x7390, 0xa38e,
+ 0xffff, 0x0040, 0x263e, 0x83ff, 0x00c0, 0x2640, 0x2019, 0x0001,
+ 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xa38c, 0x0001, 0x0040, 0x264d,
+ 0xa084, 0xff00, 0x8007, 0x0078, 0x264f, 0xa084, 0x00ff, 0xa70e,
+ 0x0040, 0x2689, 0xa08e, 0x0000, 0x0040, 0x2689, 0xa08e, 0x00ff,
+ 0x00c0, 0x2666, 0x7230, 0xd284, 0x00c0, 0x268f, 0x7280, 0xc28d,
+ 0x7282, 0x7093, 0xffff, 0x037f, 0x0078, 0x2694, 0x2009, 0x0000,
+ 0x1078, 0x24e3, 0x1078, 0x4499, 0x00c0, 0x268c, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2683, 0x7030, 0xd08c, 0x0040,
+ 0x267d, 0x6000, 0xd0bc, 0x0040, 0x2683, 0x1078, 0x271f, 0x0040,
+ 0x268c, 0x0078, 0x2689, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+ 0x268c, 0x8318, 0x0078, 0x2640, 0x7392, 0x0078, 0x2691, 0x7093,
+ 0xffff, 0x037f, 0x0078, 0x2705, 0xa780, 0x293f, 0x203c, 0xa7bc,
+ 0xff00, 0x873f, 0x2041, 0x007e, 0x7090, 0xa096, 0xffff, 0x00c0,
+ 0x26a6, 0x2009, 0x0000, 0x28a8, 0x0078, 0x26b2, 0xa812, 0x0048,
+ 0x26ae, 0x2008, 0xa802, 0x20a8, 0x0078, 0x26b2, 0x7093, 0xffff,
+ 0x0078, 0x2705, 0x2700, 0x157e, 0x017e, 0xa106, 0x0040, 0x26f9,
+ 0xc484, 0x1078, 0x4501, 0x0040, 0x26c3, 0x1078, 0x4499, 0x00c0,
+ 0x2702, 0x0078, 0x26c4, 0xc485, 0x6004, 0xa084, 0x00ff, 0xa086,
+ 0x0006, 0x00c0, 0x26d3, 0x7030, 0xd08c, 0x0040, 0x26f1, 0x6000,
+ 0xd0bc, 0x00c0, 0x26f1, 0x7280, 0xd28c, 0x0040, 0x26e9, 0x6004,
+ 0xa084, 0x00ff, 0xa082, 0x0006, 0x0048, 0x26f9, 0xd484, 0x00c0,
+ 0x26e5, 0x1078, 0x44bc, 0x0078, 0x26e7, 0x1078, 0x2921, 0x0078,
+ 0x26f9, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040, 0x2702, 0x0078,
+ 0x26f9, 0x1078, 0x28ec, 0x0040, 0x26f9, 0x1078, 0x271f, 0x0040,
+ 0x2702, 0x017f, 0x8108, 0x157f, 0x00f0, 0x26b2, 0x7093, 0xffff,
+ 0x0078, 0x2705, 0x017f, 0x157f, 0x7192, 0x047f, 0x027f, 0x0c7f,
+ 0x007c, 0x0c7e, 0x017e, 0x7093, 0x0000, 0x2009, 0x007e, 0x1078,
+ 0x4499, 0x00c0, 0x271c, 0x1078, 0x2857, 0x1078, 0x274c, 0x0040,
+ 0x271c, 0x70c8, 0xc0bd, 0x70ca, 0x017f, 0x0c7f, 0x007c, 0x017e,
+ 0x077e, 0x0d7e, 0x0c7e, 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084,
+ 0x00ff, 0x6842, 0x1078, 0x74d7, 0x0040, 0x2747, 0x2d00, 0x601a,
+ 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0000,
+ 0x1078, 0x443f, 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e,
+ 0x127f, 0x2009, 0x0004, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f,
+ 0x0d7f, 0x077f, 0x017f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e,
+ 0x2c68, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x1078,
+ 0x74d7, 0x0040, 0x2785, 0x2d00, 0x601a, 0x6800, 0xc0c4, 0x6802,
+ 0x68a0, 0xa086, 0x007e, 0x0040, 0x276e, 0x6804, 0xa084, 0x00ff,
+ 0xa086, 0x0006, 0x00c0, 0x276e, 0x1078, 0x2813, 0x601f, 0x0001,
+ 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+ 0x127e, 0x2091, 0x8000, 0x708c, 0x8000, 0x708e, 0x127f, 0x2009,
+ 0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+ 0x017f, 0x007c, 0x0c7e, 0x027e, 0x2009, 0x0080, 0x1078, 0x4499,
+ 0x00c0, 0x2798, 0x1078, 0x279b, 0x0040, 0x2798, 0x70cf, 0xffff,
+ 0x027f, 0x0c7f, 0x007c, 0x017e, 0x077e, 0x0d7e, 0x0c7e, 0x2c68,
+ 0x1078, 0x74d7, 0x0040, 0x27bd, 0x2d00, 0x601a, 0x601f, 0x0001,
+ 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f,
+ 0x127e, 0x2091, 0x8000, 0x70d0, 0x8000, 0x70d2, 0x127f, 0x2009,
+ 0x0002, 0x1078, 0x756c, 0xa085, 0x0001, 0x0c7f, 0x0d7f, 0x077f,
+ 0x017f, 0x007c, 0x0c7e, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2009,
+ 0x007f, 0x1078, 0x4499, 0x00c0, 0x27de, 0x2c68, 0x1078, 0x74d7,
+ 0x0040, 0x27de, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+ 0x2009, 0x0022, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0d7f,
+ 0x0c7f, 0x007c, 0x0e7e, 0x0c7e, 0x067e, 0x037e, 0x027e, 0x1078,
+ 0x5d60, 0x1078, 0x5d02, 0x1078, 0x7ddf, 0x2130, 0x81ff, 0x0040,
+ 0x27f7, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0078, 0x27fb, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0, 0x2804,
+ 0x1078, 0x471b, 0x1078, 0x4235, 0x017f, 0x8108, 0x00f0, 0x27fb,
+ 0x86ff, 0x00c0, 0x280d, 0x1078, 0x119b, 0x027f, 0x037f, 0x067f,
+ 0x0c7f, 0x0e7f, 0x007c, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e,
+ 0x6218, 0x2270, 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53,
+ 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38,
+ 0x077f, 0x017f, 0x2e60, 0x1078, 0x471b, 0x6210, 0x6314, 0x1078,
+ 0x4235, 0x6212, 0x6316, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+ 0x007c, 0x0e7e, 0x007e, 0x6018, 0xa080, 0x0028, 0x2004, 0xd0bc,
+ 0x00c0, 0x284d, 0x2071, 0xa300, 0x708c, 0xa005, 0x0040, 0x284a,
+ 0x8001, 0x708e, 0x007f, 0x0e7f, 0x007c, 0x2071, 0xa300, 0x70d0,
+ 0xa005, 0x0040, 0x284a, 0x8001, 0x70d2, 0x0078, 0x284a, 0x6000,
+ 0xc08c, 0x6002, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x037e, 0x027e,
+ 0x017e, 0x157e, 0x2178, 0x81ff, 0x00c0, 0x286a, 0x20a9, 0x0001,
+ 0x0078, 0x2885, 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x2881,
+ 0xd0a4, 0x0040, 0x2881, 0x047e, 0x6018, 0xa080, 0x0028, 0x2024,
+ 0xa4a4, 0x00ff, 0x8427, 0xa006, 0x2009, 0x002d, 0x1078, 0x9ec0,
+ 0x047f, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x027e, 0xa28e, 0x007e,
+ 0x0040, 0x28c9, 0xa28e, 0x007f, 0x0040, 0x28c9, 0xa28e, 0x0080,
+ 0x0040, 0x28c9, 0xa288, 0xa434, 0x210c, 0x81ff, 0x0040, 0x28c9,
+ 0x8fff, 0x1040, 0x28d5, 0x0c7e, 0x2160, 0x2001, 0x0001, 0x1078,
+ 0x48a2, 0x0c7f, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+ 0x0000, 0x1078, 0x5c78, 0x0c7e, 0x027e, 0x2160, 0x6204, 0xa294,
+ 0x00ff, 0xa286, 0x0006, 0x00c0, 0x28b9, 0x6007, 0x0404, 0x0078,
+ 0x28be, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206, 0x027f, 0x0c7f,
+ 0x017e, 0x2c08, 0x1078, 0x9c38, 0x017f, 0x077f, 0x2160, 0x1078,
+ 0x471b, 0x027f, 0x8210, 0x00f0, 0x2885, 0x157f, 0x017f, 0x027f,
+ 0x037f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x047e, 0x027e, 0x017e,
+ 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x28e8, 0xd0a4, 0x0040,
+ 0x28e8, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x1078, 0x9ec0,
+ 0x017f, 0x027f, 0x047f, 0x007c, 0x017e, 0x027e, 0x037e, 0x0c7e,
+ 0x7280, 0x82ff, 0x0040, 0x291a, 0xa290, 0xa352, 0x2214, 0xd2ac,
+ 0x00c0, 0x291a, 0x2100, 0x1078, 0x24fa, 0x81ff, 0x0040, 0x291c,
+ 0x2019, 0x0001, 0x8314, 0xa2e0, 0xa9c0, 0x2c04, 0xd384, 0x0040,
+ 0x290e, 0xa084, 0xff00, 0x8007, 0x0078, 0x2910, 0xa084, 0x00ff,
+ 0xa116, 0x0040, 0x291c, 0xa096, 0x00ff, 0x0040, 0x291a, 0x8318,
+ 0x0078, 0x2902, 0xa085, 0x0001, 0x0c7f, 0x037f, 0x027f, 0x017f,
+ 0x007c, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0xa180, 0xa434,
+ 0x2004, 0xa065, 0x0040, 0x293b, 0x017e, 0x0c7e, 0x1078, 0x8ec0,
+ 0x017f, 0x1040, 0x1328, 0x611a, 0x1078, 0x2813, 0x1078, 0x753d,
+ 0x017f, 0x1078, 0x44bc, 0x127f, 0x0c7f, 0x017f, 0x007c, 0x7eef,
+ 0x7de8, 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9,
+ 0x80d6, 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd,
+ 0x80cc, 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3,
+ 0x80bc, 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2,
+ 0x80b1, 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7,
+ 0x6da6, 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098,
+ 0x6797, 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080,
+ 0x617c, 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072,
+ 0x8071, 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067,
+ 0x5a66, 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055,
+ 0x5454, 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b,
+ 0x4e4a, 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a,
+ 0x8039, 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e,
+ 0x472d, 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025,
+ 0x4123, 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010,
+ 0x3b0f, 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800,
+ 0x3700, 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000,
+ 0x8000, 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000,
+ 0x8000, 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000,
+ 0x2700, 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000,
+ 0x2100, 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000,
+ 0x1b00, 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000,
+ 0x1400, 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000,
+ 0x0e00, 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000,
+ 0x0800, 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500,
+ 0x0400, 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071,
+ 0xa381, 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e,
+ 0x7033, 0xa391, 0x7037, 0xa391, 0x7007, 0x0001, 0x2061, 0xa3d1,
+ 0x6003, 0x0002, 0x007c, 0x0090, 0x2a66, 0x0068, 0x2a66, 0x2071,
+ 0xa381, 0x2b78, 0x7818, 0xd084, 0x00c0, 0x2a66, 0x2a60, 0x7820,
+ 0xa08e, 0x0069, 0x00c0, 0x2b56, 0x0079, 0x2aea, 0x007c, 0x2071,
+ 0xa381, 0x7004, 0x0079, 0x2a6c, 0x2a70, 0x2a71, 0x2a7b, 0x2a8d,
+ 0x007c, 0x0090, 0x2a7a, 0x0068, 0x2a7a, 0x2b78, 0x7818, 0xd084,
+ 0x0040, 0x2a99, 0x007c, 0x2b78, 0x2061, 0xa3d1, 0x6008, 0xa08e,
+ 0x0100, 0x0040, 0x2a88, 0xa086, 0x0200, 0x0040, 0x2b4e, 0x007c,
+ 0x7014, 0x2068, 0x2a60, 0x7018, 0x007a, 0x7010, 0x2068, 0x6834,
+ 0xa086, 0x0103, 0x0040, 0x2a95, 0x007c, 0x2a60, 0x2b78, 0x7018,
+ 0x007a, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x00c8, 0x2aa2, 0x61b8,
+ 0x0079, 0x2aaa, 0x2100, 0xa08a, 0x003f, 0x00c8, 0x2b4a, 0x61b8,
+ 0x0079, 0x2aea, 0x2b2c, 0x2b5e, 0x2b66, 0x2b6a, 0x2b72, 0x2b78,
+ 0x2b7c, 0x2b88, 0x2b8c, 0x2b96, 0x2b9a, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b9e, 0x2b4a, 0x2bae, 0x2bc5, 0x2bdc, 0x2c58, 0x2c5d, 0x2c8a,
+ 0x2ce4, 0x2cf5, 0x2d13, 0x2d54, 0x2d5e, 0x2d6b, 0x2d7e, 0x2d9d,
+ 0x2da6, 0x2de3, 0x2de9, 0x2b4a, 0x2e05, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x2b4a, 0x2e0c, 0x2e16, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2e1e, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x2b4a, 0x2e30, 0x2e47, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x2b4a, 0x2e59, 0x2eb0, 0x2f0e, 0x2f1f, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x38f1, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x2b4a, 0x2b96, 0x2b9a, 0x2f36, 0x2b4a, 0x2f43, 0x397d,
+ 0x39da, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a,
+ 0x2b4a, 0x2b4a, 0x2f90, 0x30c5, 0x30e1, 0x30ed, 0x3150, 0x31a9,
+ 0x31b4, 0x31f3, 0x3202, 0x3211, 0x3214, 0x2f47, 0x3238, 0x3284,
+ 0x3291, 0x33a2, 0x34cd, 0x34f7, 0x3604, 0x3614, 0x3621, 0x365b,
+ 0x372a, 0x2b4a, 0x2b4a, 0x2b4a, 0x2b4a, 0x3792, 0x37ae, 0x3828,
+ 0x38e2, 0x713c, 0x0078, 0x2b2c, 0x2021, 0x4000, 0x1078, 0x3553,
+ 0x127e, 0x2091, 0x8000, 0x0068, 0x2b39, 0x7818, 0xd084, 0x0040,
+ 0x2b3c, 0x127f, 0x0078, 0x2b30, 0x7c22, 0x7926, 0x7a2a, 0x7b2e,
+ 0x781b, 0x0001, 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000,
+ 0x127f, 0x007c, 0x2021, 0x4001, 0x0078, 0x2b2e, 0x2021, 0x4002,
+ 0x0078, 0x2b2e, 0x2021, 0x4003, 0x0078, 0x2b2e, 0x2021, 0x4005,
+ 0x0078, 0x2b2e, 0x2021, 0x4006, 0x0078, 0x2b2e, 0xa02e, 0x2520,
+ 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0078, 0x3562, 0x7823, 0x0004,
+ 0x7824, 0x007a, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930,
+ 0x0078, 0x3566, 0x7924, 0x7828, 0x2114, 0x200a, 0x0078, 0x2b2c,
+ 0x7924, 0x2114, 0x0078, 0x2b2c, 0x2099, 0x0009, 0x20a1, 0x0009,
+ 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0078, 0x2b2c,
+ 0x7824, 0x2060, 0x0078, 0x2ba0, 0x2009, 0x0001, 0x2011, 0x0013,
+ 0x2019, 0x0010, 0x783b, 0x0017, 0x0078, 0x2b2c, 0x7d38, 0x7c3c,
+ 0x0078, 0x2b60, 0x7d38, 0x7c3c, 0x0078, 0x2b6c, 0x2061, 0x1000,
+ 0x610c, 0xa006, 0x2c14, 0xa200, 0x8c60, 0x8109, 0x00c0, 0x2ba2,
+ 0x2010, 0xa005, 0x0040, 0x2b2c, 0x0078, 0x2b52, 0x2069, 0xa351,
+ 0x7824, 0x7930, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a,
+ 0x684a, 0x6942, 0x782c, 0x6852, 0x7828, 0x6856, 0xa006, 0x685a,
+ 0x685e, 0x1078, 0x4dbd, 0x0078, 0x2b2c, 0x2069, 0xa351, 0x7824,
+ 0x7934, 0xa11a, 0x00c8, 0x2b5a, 0x8019, 0x0040, 0x2b5a, 0x684e,
+ 0x6946, 0x782c, 0x6862, 0x7828, 0x6866, 0xa006, 0x686a, 0x686e,
+ 0x1078, 0x494d, 0x0078, 0x2b2c, 0xa02e, 0x2520, 0x81ff, 0x00c0,
+ 0x2b56, 0x7924, 0x7b28, 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xa388,
+ 0x41a1, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0020, 0x1078,
+ 0x3562, 0x701b, 0x2bf4, 0x007c, 0x6834, 0x2008, 0xa084, 0x00ff,
+ 0xa096, 0x0011, 0x0040, 0x2c00, 0xa096, 0x0019, 0x00c0, 0x2b56,
+ 0x810f, 0xa18c, 0x00ff, 0x0040, 0x2b56, 0x710e, 0x700c, 0x8001,
+ 0x0040, 0x2c31, 0x700e, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+ 0x0020, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530, 0xa290,
+ 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x1078,
+ 0x3562, 0x701b, 0x2c24, 0x007c, 0x6834, 0xa084, 0x00ff, 0xa096,
+ 0x0002, 0x0040, 0x2c2f, 0xa096, 0x000a, 0x00c0, 0x2b56, 0x0078,
+ 0x2c06, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x436e,
+ 0x00c0, 0x2c3f, 0x7007, 0x0003, 0x701b, 0x2c41, 0x007c, 0x1078,
+ 0x4a60, 0x127e, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xa388,
+ 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+ 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x127f, 0x0078, 0x3566,
+ 0x61a0, 0x7824, 0x60a2, 0x0078, 0x2b2c, 0x2091, 0x8000, 0x7823,
+ 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009,
+ 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200,
+ 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd,
+ 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
+ 0x2071, 0x0010, 0x20c1, 0x00f0, 0xa08a, 0x0003, 0x00c8, 0x0427,
+ 0x0078, 0x0423, 0x81ff, 0x00c0, 0x2b56, 0x7924, 0x810f, 0xa18c,
+ 0x00ff, 0x1078, 0x4501, 0x00c0, 0x2b5a, 0x7e38, 0xa684, 0x3fff,
+ 0xa082, 0x4000, 0x0048, 0x2c9e, 0x0078, 0x2b5a, 0x7c28, 0x7d2c,
+ 0x1078, 0x46d6, 0xd28c, 0x00c0, 0x2ca9, 0x1078, 0x466a, 0x0078,
+ 0x2cab, 0x1078, 0x46a4, 0x00c0, 0x2cd5, 0x2061, 0xaa00, 0x127e,
+ 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0040, 0x2cc3, 0x6010,
+ 0xa06d, 0x0040, 0x2cc3, 0x683c, 0xa406, 0x00c0, 0x2cc3, 0x6840,
+ 0xa506, 0x0040, 0x2cce, 0x127f, 0xace0, 0x0010, 0x2001, 0xa315,
+ 0x2004, 0xac02, 0x00c8, 0x2b56, 0x0078, 0x2caf, 0x1078, 0x8758,
+ 0x127f, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0xa00e, 0x2001, 0x0005,
+ 0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cc0, 0x1078,
+ 0x4982, 0x127f, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+ 0x3530, 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078,
+ 0x46e4, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+ 0x1078, 0x3542, 0x0040, 0x2b5a, 0x1078, 0x475f, 0x0040, 0x2b56,
+ 0x2019, 0x0005, 0x1078, 0x4705, 0x0040, 0x2b56, 0x7828, 0xa08a,
+ 0x1000, 0x00c8, 0x2b5a, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078,
+ 0x58e1, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x81ff, 0x0040,
+ 0x2d1d, 0x2009, 0x0001, 0x0078, 0x2d4e, 0x2029, 0x00ff, 0x644c,
+ 0x2400, 0xa506, 0x0040, 0x2d48, 0x2508, 0x1078, 0x4501, 0x00c0,
+ 0x2d48, 0x1078, 0x475f, 0x00c0, 0x2d33, 0x2009, 0x0002, 0x62a8,
+ 0x2518, 0x0078, 0x2d4e, 0x2019, 0x0004, 0x1078, 0x4705, 0x00c0,
+ 0x2d3d, 0x2009, 0x0006, 0x0078, 0x2d4e, 0x7824, 0xa08a, 0x1000,
+ 0x00c8, 0x2d51, 0x8003, 0x800b, 0x810b, 0xa108, 0x1078, 0x58e1,
+ 0x8529, 0x00c8, 0x2d20, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078,
+ 0x2b56, 0x127f, 0x0078, 0x2b5a, 0x1078, 0x3530, 0x0040, 0x2b5a,
+ 0x1078, 0x461b, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0,
+ 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a, 0x1078, 0x460a, 0x1078,
+ 0x46d6, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+ 0x0040, 0x2b5a, 0x1078, 0x46a7, 0x0040, 0x2b56, 0x1078, 0x43c1,
+ 0x1078, 0x4663, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530,
+ 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x62a0, 0x2019,
+ 0x0005, 0x0c7e, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e,
+ 0x2039, 0x0000, 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38,
+ 0x077f, 0x1078, 0x46d6, 0x0078, 0x2b2c, 0x1078, 0x3530, 0x0040,
+ 0x2b5a, 0x1078, 0x46d6, 0x2208, 0x0078, 0x2b2c, 0x157e, 0x0d7e,
+ 0x0e7e, 0x2069, 0xa413, 0x6810, 0x6914, 0xa10a, 0x00c8, 0x2db2,
+ 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019, 0x0000, 0x20a9,
+ 0x00ff, 0x2069, 0xa434, 0x2d04, 0xa075, 0x0040, 0x2dc7, 0x704c,
+ 0x1078, 0x2dd1, 0xa210, 0x7080, 0x1078, 0x2dd1, 0xa318, 0x8d68,
+ 0x00f0, 0x2dbb, 0x2300, 0xa218, 0x0e7f, 0x0d7f, 0x157f, 0x0078,
+ 0x2b2c, 0x0f7e, 0x017e, 0xa07d, 0x0040, 0x2de0, 0x2001, 0x0000,
+ 0x8000, 0x2f0c, 0x81ff, 0x0040, 0x2de0, 0x2178, 0x0078, 0x2dd8,
+ 0x017f, 0x0f7f, 0x007c, 0x2069, 0xa413, 0x6910, 0x62a4, 0x0078,
+ 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x614c, 0xa190, 0x293f, 0x2214,
+ 0xa294, 0x00ff, 0x606c, 0xa084, 0xff00, 0xa215, 0x6368, 0x67c8,
+ 0xd79c, 0x0040, 0x2dff, 0x2031, 0x0001, 0x0078, 0x2e01, 0x2031,
+ 0x0000, 0x7e3a, 0x7f3e, 0x0078, 0x2b2c, 0x613c, 0x6240, 0x2019,
+ 0xa5a0, 0x231c, 0x0078, 0x2b2c, 0x127e, 0x2091, 0x8000, 0x6134,
+ 0xa006, 0x2010, 0x2018, 0x127f, 0x0078, 0x2b2c, 0x1078, 0x3542,
+ 0x0040, 0x2b5a, 0x6244, 0x6338, 0x0078, 0x2b2c, 0x613c, 0x6240,
+ 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xa351, 0x831f, 0xa305,
+ 0x6816, 0x782c, 0x2069, 0xa5a0, 0x2d1c, 0x206a, 0x0078, 0x2b2c,
+ 0x017e, 0x127e, 0x2091, 0x8000, 0x7824, 0x6036, 0xd094, 0x0040,
+ 0x2e43, 0x7828, 0xa085, 0x0001, 0x2009, 0xa5a9, 0x200a, 0x2001,
+ 0xffff, 0x1078, 0x5975, 0x127f, 0x017f, 0x0078, 0x2b2c, 0x1078,
+ 0x3542, 0x0040, 0x2b5a, 0x7828, 0xa00d, 0x0040, 0x2b5a, 0x782c,
+ 0xa005, 0x0040, 0x2b5a, 0x6244, 0x6146, 0x6338, 0x603a, 0x0078,
+ 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56,
+ 0x0c7e, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196,
+ 0x00ff, 0x00c0, 0x2e70, 0x6030, 0xa085, 0xff00, 0x0078, 0x2e7f,
+ 0xa182, 0x007f, 0x00c8, 0x2ea9, 0xa188, 0x293f, 0x210c, 0xa18c,
+ 0x00ff, 0x6030, 0xa116, 0x0040, 0x2ea9, 0x810f, 0xa105, 0x127e,
+ 0x2091, 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2ea5,
+ 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040,
+ 0x2eac, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032,
+ 0x1078, 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078,
+ 0x2b56, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2ea5,
+ 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0c7e,
+ 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff,
+ 0x00c0, 0x2ec7, 0x6030, 0xa085, 0xff00, 0x0078, 0x2ed6, 0xa182,
+ 0x007f, 0x00c8, 0x2f00, 0xa188, 0x293f, 0x210c, 0xa18c, 0x00ff,
+ 0x6030, 0xa116, 0x0040, 0x2f00, 0x810f, 0xa105, 0x127e, 0x2091,
+ 0x8000, 0x007e, 0x1078, 0x74d7, 0x007f, 0x0040, 0x2efc, 0x601a,
+ 0x600b, 0xbc05, 0x601f, 0x0001, 0x1078, 0x3518, 0x0040, 0x2f03,
+ 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x701b, 0x2f07, 0x2d00, 0x6012, 0x2009, 0x0032, 0x1078,
+ 0x756c, 0x127f, 0x0c7f, 0x007c, 0x127f, 0x0c7f, 0x0078, 0x2b56,
+ 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x753d, 0x0078, 0x2efc, 0x6830,
+ 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x2061, 0xa62d,
+ 0x127e, 0x2091, 0x8000, 0x6000, 0xd084, 0x0040, 0x2f1c, 0x6104,
+ 0x6208, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x81ff,
+ 0x00c0, 0x2b56, 0x127e, 0x2091, 0x8000, 0x6244, 0x6060, 0xa202,
+ 0x0048, 0x2f33, 0xa085, 0x0001, 0x1078, 0x2500, 0x1078, 0x3bf5,
+ 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b5a, 0x127e, 0x2091,
+ 0x8000, 0x20a9, 0x0011, 0x2001, 0xa340, 0x20a0, 0xa006, 0x40a4,
+ 0x127f, 0x0078, 0x2b2c, 0x7d38, 0x7c3c, 0x0078, 0x2bde, 0x7824,
+ 0xa09c, 0x00ff, 0xa39a, 0x0003, 0x00c8, 0x2b56, 0x624c, 0xa084,
+ 0xff00, 0x8007, 0xa206, 0x00c0, 0x2f5f, 0x2001, 0xa340, 0x2009,
+ 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566, 0x81ff,
+ 0x00c0, 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518,
+ 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+ 0x1078, 0x8b85, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x2f81,
+ 0x007c, 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0xad80, 0x000e,
+ 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078, 0x3566,
+ 0x1078, 0x3518, 0x0040, 0x2b56, 0x1078, 0x421a, 0x2009, 0x001c,
+ 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x2fa1,
+ 0x007c, 0xade8, 0x000d, 0x6800, 0xa005, 0x0040, 0x2b5a, 0x6804,
+ 0xd0ac, 0x0040, 0x2fae, 0xd0a4, 0x0040, 0x2b5a, 0xd094, 0x0040,
+ 0x2fb9, 0x0c7e, 0x2061, 0x0100, 0x6104, 0xa18c, 0xffdf, 0x6106,
+ 0x0c7f, 0xd08c, 0x0040, 0x2fc4, 0x0c7e, 0x2061, 0x0100, 0x6104,
+ 0xa18d, 0x0010, 0x6106, 0x0c7f, 0x2009, 0x0100, 0x210c, 0xa18a,
+ 0x0002, 0x0048, 0x2fd9, 0xd084, 0x0040, 0x2fd9, 0x6a28, 0xa28a,
+ 0x007f, 0x00c8, 0x2b5a, 0xa288, 0x293f, 0x210c, 0xa18c, 0x00ff,
+ 0x6152, 0xd0dc, 0x0040, 0x2fe2, 0x6828, 0xa08a, 0x007f, 0x00c8,
+ 0x2b5a, 0x604e, 0x6808, 0xa08a, 0x0100, 0x0048, 0x2b5a, 0xa08a,
+ 0x0841, 0x00c8, 0x2b5a, 0xa084, 0x0007, 0x00c0, 0x2b5a, 0x680c,
+ 0xa005, 0x0040, 0x2b5a, 0x6810, 0xa005, 0x0040, 0x2b5a, 0x6848,
+ 0x6940, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x684c,
+ 0x6944, 0xa10a, 0x00c8, 0x2b5a, 0x8001, 0x0040, 0x2b5a, 0x6804,
+ 0xd0fc, 0x0040, 0x3038, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009,
+ 0x0014, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0xa290, 0x0038, 0xa399,
+ 0x0000, 0x1078, 0x3562, 0x701b, 0x301e, 0x007c, 0xade8, 0x000d,
+ 0x20a9, 0x0014, 0x2d98, 0x2069, 0xa36d, 0x2da0, 0x53a3, 0x7010,
+ 0xa0e8, 0x000d, 0x2001, 0xa371, 0x200c, 0xd1e4, 0x0040, 0x3038,
+ 0x0c7e, 0x2061, 0x0100, 0x6004, 0xa085, 0x0b00, 0x6006, 0x0c7f,
+ 0x20a9, 0x001c, 0x2d98, 0x2069, 0xa351, 0x2da0, 0x53a3, 0x6814,
+ 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084, 0x00ff, 0x6042, 0x1078,
+ 0x4dbd, 0x1078, 0x48dd, 0x1078, 0x494d, 0x6000, 0xa086, 0x0000,
+ 0x00c0, 0x30c3, 0x6808, 0x602a, 0x1078, 0x218b, 0x6818, 0x691c,
+ 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+ 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0040, 0x3070, 0x6830, 0x6934,
+ 0x6a38, 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0078, 0x3072,
+ 0xa084, 0xf0ff, 0x6006, 0x610a, 0x620e, 0x6312, 0x1078, 0x59a8,
+ 0x6904, 0xd1fc, 0x0040, 0x30a5, 0x0c7e, 0x2009, 0x0000, 0x20a9,
+ 0x0001, 0x6b70, 0xd384, 0x0040, 0x30a2, 0x0078, 0x308c, 0x839d,
+ 0x00c8, 0x30a2, 0x3508, 0x8109, 0x1078, 0x5364, 0x6878, 0x6016,
+ 0x6874, 0x2008, 0xa084, 0xff00, 0x8007, 0x600a, 0xa184, 0x00ff,
+ 0x6006, 0x8108, 0x00c0, 0x30a0, 0x6003, 0x0003, 0x0078, 0x30a2,
+ 0x6003, 0x0001, 0x00f0, 0x3087, 0x0c7f, 0x0c7e, 0x2061, 0x0100,
+ 0x602f, 0x0040, 0x602f, 0x0000, 0x0c7f, 0x1078, 0x3784, 0x0040,
+ 0x30b3, 0x1078, 0x2500, 0x60bc, 0xa005, 0x0040, 0x30bf, 0x6003,
+ 0x0001, 0x2091, 0x301d, 0x1078, 0x4171, 0x0078, 0x30c3, 0x6003,
+ 0x0004, 0x2091, 0x301d, 0x0078, 0x2b2c, 0x6000, 0xa086, 0x0000,
+ 0x0040, 0x2b56, 0x2069, 0xa351, 0x7830, 0x6842, 0x7834, 0x6846,
+ 0x6804, 0xd0fc, 0x0040, 0x30d8, 0x2009, 0x0030, 0x0078, 0x30da,
+ 0x2009, 0x001c, 0x2d00, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+ 0x3566, 0xa006, 0x1078, 0x2500, 0x81ff, 0x00c0, 0x2b56, 0x1078,
+ 0x421a, 0x1078, 0x4171, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56,
+ 0x6180, 0x81ff, 0x0040, 0x3107, 0x703f, 0x0000, 0x2001, 0xa9c0,
+ 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x127e, 0x2091,
+ 0x8000, 0x1078, 0x3566, 0x701b, 0x2b29, 0x127f, 0x007c, 0x703f,
+ 0x0001, 0x0d7e, 0x2069, 0xa9c0, 0x20a9, 0x0040, 0x20a1, 0xa9c0,
+ 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x293f, 0x210c, 0xa18c,
+ 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100, 0xa506, 0x0040,
+ 0x3139, 0x1078, 0x4501, 0x00c0, 0x3139, 0x6014, 0x821c, 0x0048,
+ 0x3131, 0xa398, 0xa9c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0078,
+ 0x3138, 0xa398, 0xa9c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a,
+ 0x8210, 0x8108, 0xa182, 0x0080, 0x00c8, 0x3140, 0x0078, 0x311d,
+ 0x8201, 0x8007, 0x2d0c, 0xa105, 0x206a, 0x0d7f, 0x20a9, 0x0040,
+ 0x20a1, 0xa9c0, 0x2099, 0xa9c0, 0x1078, 0x41be, 0x0078, 0x30f6,
+ 0x1078, 0x3542, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f,
+ 0x00c0, 0x315e, 0x2009, 0x0002, 0x0078, 0x2b56, 0x2001, 0xa352,
+ 0x2004, 0xd0b4, 0x0040, 0x3185, 0x6000, 0xd08c, 0x00c0, 0x3185,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x3185, 0x6837,
+ 0x0000, 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x317c,
+ 0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3181,
+ 0x007c, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x20a9, 0x002b, 0x2c98,
+ 0xade8, 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006,
+ 0x2098, 0xad80, 0x0006, 0x20a0, 0x1078, 0x41be, 0x20a9, 0x0004,
+ 0xac80, 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x1078, 0x41be,
+ 0x2d00, 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0078,
+ 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040, 0x2b5a,
+ 0x1078, 0x46ef, 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x7828,
+ 0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x1078, 0x3542, 0x0040, 0x2b5a,
+ 0x1078, 0x475f, 0x0040, 0x2b56, 0x2019, 0x0004, 0x1078, 0x4705,
+ 0x7924, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x0078, 0x2b2c, 0xa186,
+ 0x00ff, 0x0040, 0x31d7, 0x1078, 0x31e7, 0x0078, 0x31e6, 0x2029,
+ 0x007e, 0x2061, 0xa300, 0x644c, 0x2400, 0xa506, 0x0040, 0x31e3,
+ 0x2508, 0x1078, 0x31e7, 0x8529, 0x00c8, 0x31dc, 0x007c, 0x1078,
+ 0x4501, 0x00c0, 0x31f2, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108,
+ 0x1078, 0x58e1, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530,
+ 0x0040, 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46fa,
+ 0x0078, 0x2b2c, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+ 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x46e4, 0x0078,
+ 0x2b2c, 0x6100, 0x0078, 0x2b2c, 0x1078, 0x3542, 0x0040, 0x2b5a,
+ 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x0d7e,
+ 0xace8, 0x000a, 0x7924, 0xd184, 0x0040, 0x3228, 0xace8, 0x0006,
+ 0x680c, 0x8007, 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f,
+ 0x6a00, 0x8217, 0x0d7f, 0x6100, 0xa18c, 0x0200, 0x0078, 0x2b2c,
+ 0xa006, 0x1078, 0x2500, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+ 0x0040, 0x3245, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x421a, 0x7828,
+ 0xa08a, 0x1000, 0x00c8, 0x2b5a, 0x7924, 0xa18c, 0xff00, 0x810f,
+ 0xa186, 0x00ff, 0x0040, 0x325b, 0xa182, 0x007f, 0x00c8, 0x2b5a,
+ 0x2100, 0x1078, 0x24fa, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000,
+ 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0x0100,
+ 0x6030, 0xa084, 0x00ff, 0x810f, 0xa105, 0x604a, 0x6043, 0x0090,
+ 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078, 0x596c,
+ 0x7924, 0xa18c, 0xff00, 0x810f, 0x7a28, 0x1078, 0x31cf, 0x127f,
+ 0x0c7f, 0x027f, 0x0078, 0x2b2c, 0x7924, 0xa18c, 0xff00, 0x810f,
+ 0x0c7e, 0x1078, 0x4499, 0x2c08, 0x0c7f, 0x00c0, 0x2b5a, 0x0078,
+ 0x2b2c, 0x81ff, 0x0040, 0x3298, 0x2009, 0x0001, 0x0078, 0x2b56,
+ 0x60c8, 0xd09c, 0x00c0, 0x32a0, 0x2009, 0x0005, 0x0078, 0x2b56,
+ 0x1078, 0x3518, 0x00c0, 0x32a8, 0x2009, 0x0002, 0x0078, 0x2b56,
+ 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b,
+ 0x32b2, 0x007c, 0x2009, 0x0080, 0x1078, 0x4501, 0x00c0, 0x32bf,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x32c3, 0x2021,
+ 0x400a, 0x0078, 0x2b2e, 0x0d7e, 0xade8, 0x000d, 0x6900, 0x6a08,
+ 0x6b0c, 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0040,
+ 0x3336, 0xa0be, 0x0112, 0x0040, 0x3336, 0xa0be, 0x0113, 0x0040,
+ 0x3336, 0xa0be, 0x0114, 0x0040, 0x3336, 0xa0be, 0x0117, 0x0040,
+ 0x3336, 0xa0be, 0x011a, 0x0040, 0x3336, 0xa0be, 0x0121, 0x0040,
+ 0x332c, 0xa0be, 0x0131, 0x0040, 0x332c, 0xa0be, 0x0171, 0x0040,
+ 0x3336, 0xa0be, 0x0173, 0x0040, 0x3336, 0xa0be, 0x01a1, 0x00c0,
+ 0x32fe, 0x6830, 0x8007, 0x6832, 0x0078, 0x333c, 0xa0be, 0x0212,
+ 0x0040, 0x3332, 0xa0be, 0x0213, 0x0040, 0x3332, 0xa0be, 0x0214,
+ 0x0040, 0x3324, 0xa0be, 0x0217, 0x0040, 0x331e, 0xa0be, 0x021a,
+ 0x00c0, 0x3317, 0x6838, 0x8007, 0x683a, 0x0078, 0x3336, 0xa0be,
+ 0x0300, 0x0040, 0x3336, 0x0d7f, 0x0078, 0x2b5a, 0xad80, 0x0010,
+ 0x20a9, 0x0007, 0x1078, 0x337e, 0xad80, 0x000e, 0x20a9, 0x0001,
+ 0x1078, 0x337e, 0x0078, 0x3336, 0xad80, 0x000c, 0x1078, 0x338c,
+ 0x0078, 0x333c, 0xad80, 0x000e, 0x1078, 0x338c, 0xad80, 0x000c,
+ 0x20a9, 0x0001, 0x1078, 0x337e, 0x0c7e, 0x1078, 0x3518, 0x0040,
+ 0x336f, 0x6838, 0xc0fd, 0x683a, 0x6837, 0x0119, 0x6853, 0x0000,
+ 0x684f, 0x0020, 0x685b, 0x0001, 0x810b, 0x697e, 0x6883, 0x0000,
+ 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996, 0x689b, 0x0000, 0x0c7f,
+ 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+ 0x6804, 0x2068, 0x1078, 0x8ba1, 0x00c0, 0x336a, 0x2009, 0x0003,
+ 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3375, 0x007c, 0x0c7f,
+ 0x0d7f, 0x2009, 0x0002, 0x0078, 0x2b56, 0x6820, 0xa086, 0x8001,
+ 0x00c0, 0x2b2c, 0x2009, 0x0004, 0x0078, 0x2b56, 0x017e, 0x2008,
+ 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108, 0x280a, 0x8108,
+ 0x00f0, 0x3380, 0x017f, 0x007c, 0x017e, 0x0a7e, 0x0b7e, 0x2008,
+ 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000, 0x205c, 0x2b0a,
+ 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a, 0x0b7f, 0x0a7f,
+ 0x017f, 0x007c, 0x81ff, 0x0040, 0x33a9, 0x2009, 0x0001, 0x0078,
+ 0x2b56, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080,
+ 0x0048, 0x2b5a, 0xa182, 0x00ff, 0x00c8, 0x2b5a, 0x7a2c, 0x7b28,
+ 0x6068, 0xa306, 0x00c0, 0x33c4, 0x606c, 0xa24e, 0x0040, 0x2b5a,
+ 0xa9cc, 0xff00, 0x0040, 0x2b5a, 0x0c7e, 0x1078, 0x346d, 0x2c68,
+ 0x0c7f, 0x0040, 0x33fc, 0xa0c6, 0x4000, 0x00c0, 0x33e2, 0x0c7e,
+ 0x007e, 0x2d60, 0x2009, 0x0000, 0x1078, 0x47cb, 0x00c0, 0x33d9,
+ 0xc185, 0x6000, 0xd0bc, 0x0040, 0x33de, 0xc18d, 0x007f, 0x0c7f,
+ 0x0078, 0x33f9, 0xa0c6, 0x4007, 0x00c0, 0x33e9, 0x2408, 0x0078,
+ 0x33f9, 0xa0c6, 0x4008, 0x00c0, 0x33f1, 0x2708, 0x2610, 0x0078,
+ 0x33f9, 0xa0c6, 0x4009, 0x00c0, 0x33f7, 0x0078, 0x33f9, 0x2001,
+ 0x4006, 0x2020, 0x0078, 0x2b2e, 0x2d00, 0x7022, 0x017e, 0x0b7e,
+ 0x0c7e, 0x0e7e, 0x2c70, 0x1078, 0x74d7, 0x0040, 0x3442, 0x2d00,
+ 0x601a, 0x2001, 0xa356, 0x2004, 0xa084, 0x00ff, 0x6842, 0x2e58,
+ 0x0e7f, 0x0e7e, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2b70, 0x00c0,
+ 0x3423, 0x1078, 0x753d, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x2009,
+ 0x0002, 0x0078, 0x2b56, 0x6837, 0x0000, 0x2d00, 0x6012, 0x6833,
+ 0x0000, 0x6838, 0xc0fd, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078,
+ 0x2813, 0x127f, 0x601f, 0x0001, 0x2001, 0x0000, 0x1078, 0x442b,
+ 0x2001, 0x0002, 0x1078, 0x443f, 0x2009, 0x0002, 0x1078, 0x756c,
+ 0xa085, 0x0001, 0x0e7f, 0x0c7f, 0x0b7f, 0x017f, 0x00c0, 0x344c,
+ 0x2009, 0x0003, 0x0078, 0x2b56, 0x7007, 0x0003, 0x701b, 0x3451,
+ 0x007c, 0x6830, 0xa086, 0x0100, 0x7020, 0x2060, 0x00c0, 0x345f,
+ 0x2009, 0x0004, 0x6204, 0xa294, 0x00ff, 0x0078, 0x2b56, 0x2009,
+ 0x0000, 0x1078, 0x47cb, 0x00c0, 0x3466, 0xc185, 0x6000, 0xd0bc,
+ 0x0040, 0x346b, 0xc18d, 0x0078, 0x2b2c, 0x0e7e, 0x0d7e, 0x2029,
+ 0x0000, 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xa4b4, 0x2e04,
+ 0xa005, 0x00c0, 0x3482, 0x2100, 0xa406, 0x00c0, 0x34b3, 0x2428,
+ 0x0078, 0x34b3, 0x2068, 0x6f10, 0x2700, 0xa306, 0x00c0, 0x34a4,
+ 0x6e14, 0x2600, 0xa206, 0x00c0, 0x34a4, 0x2400, 0xa106, 0x00c0,
+ 0x34a0, 0x2d60, 0xd884, 0x0040, 0x34c8, 0x6004, 0xa084, 0x00ff,
+ 0xa086, 0x0006, 0x00c0, 0x34c8, 0x2001, 0x4000, 0x0078, 0x34c9,
+ 0x2001, 0x4007, 0x0078, 0x34c9, 0x2400, 0xa106, 0x00c0, 0x34b3,
+ 0x6e14, 0x87ff, 0x00c0, 0x34af, 0x86ff, 0x0040, 0x347f, 0x2001,
+ 0x4008, 0x0078, 0x34c9, 0x8420, 0x8e70, 0x00f0, 0x3477, 0x85ff,
+ 0x00c0, 0x34c2, 0x2001, 0x4009, 0x0078, 0x34c9, 0x2001, 0x0001,
+ 0x0078, 0x34c9, 0x1078, 0x4499, 0x00c0, 0x34be, 0x6312, 0x6216,
+ 0xa006, 0xa005, 0x0d7f, 0x0e7f, 0x007c, 0x81ff, 0x00c0, 0x2b56,
+ 0x1078, 0x3518, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x7824, 0xa005, 0x0040, 0x2b5a, 0xa096, 0x00ff, 0x0040,
+ 0x34e5, 0xa092, 0x0004, 0x00c8, 0x2b5a, 0x2010, 0x2d18, 0x1078,
+ 0x27c2, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x34f0, 0x007c,
+ 0x6830, 0xa086, 0x0100, 0x0040, 0x2b56, 0x0078, 0x2b2c, 0x7924,
+ 0xa18c, 0xff00, 0x810f, 0xa182, 0x0080, 0x0048, 0x2b5a, 0xa182,
+ 0x00ff, 0x00c8, 0x2b5a, 0x127e, 0x2091, 0x8000, 0x1078, 0x8a89,
+ 0x00c0, 0x3515, 0xa190, 0xa434, 0x2204, 0xa065, 0x0040, 0x3515,
+ 0x1078, 0x4235, 0x127f, 0x0078, 0x2b2c, 0x127f, 0x0078, 0x2b56,
+ 0x1078, 0x1381, 0x0040, 0x352f, 0xa006, 0x6802, 0x7010, 0xa005,
+ 0x00c0, 0x3527, 0x2d00, 0x7012, 0x7016, 0x0078, 0x352d, 0x7014,
+ 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80, 0x000d, 0x007c,
+ 0x7924, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501, 0x00c0, 0x353f,
+ 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0048, 0x3540, 0xa066,
+ 0x8cff, 0x007c, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+ 0x00c0, 0x3550, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0048, 0x3551,
+ 0xa066, 0x8cff, 0x007c, 0x017e, 0x7110, 0x81ff, 0x0040, 0x355e,
+ 0x2168, 0x6904, 0x1078, 0x139a, 0x0078, 0x3555, 0x7112, 0x7116,
+ 0x017f, 0x007c, 0x2031, 0x0001, 0x0078, 0x3568, 0x2031, 0x0000,
+ 0x2061, 0xa3d1, 0x6606, 0x6112, 0x600e, 0x6226, 0x632a, 0x642e,
+ 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x2b2c,
+ 0x007c, 0x0f7e, 0x127e, 0x2091, 0x8000, 0x2079, 0x0000, 0x2001,
+ 0xa38f, 0x2004, 0xa005, 0x00c0, 0x3594, 0x0068, 0x3594, 0x7818,
+ 0xd084, 0x00c0, 0x3594, 0x7a22, 0x7b26, 0x7c2a, 0x781b, 0x0001,
+ 0x2091, 0x4080, 0x0078, 0x35b9, 0x017e, 0x0c7e, 0x0e7e, 0x2071,
+ 0xa381, 0x7138, 0xa182, 0x0008, 0x0048, 0x35a2, 0x7030, 0x2060,
+ 0x0078, 0x35b3, 0x7030, 0xa0e0, 0x0008, 0xac82, 0xa3d1, 0x0048,
+ 0x35ab, 0x2061, 0xa391, 0x2c00, 0x7032, 0x81ff, 0x00c0, 0x35b1,
+ 0x7036, 0x8108, 0x713a, 0x2262, 0x6306, 0x640a, 0x0e7f, 0x0c7f,
+ 0x017f, 0x127f, 0x0f7f, 0x007c, 0x0e7e, 0x2071, 0xa381, 0x7038,
+ 0xa005, 0x0040, 0x35f5, 0x127e, 0x2091, 0x8000, 0x0068, 0x35f4,
+ 0x0f7e, 0x2079, 0x0000, 0x7818, 0xd084, 0x00c0, 0x35f3, 0x0c7e,
+ 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826, 0x6008, 0x782a,
+ 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001, 0x703a, 0xa005,
+ 0x00c0, 0x35e9, 0x7033, 0xa391, 0x7037, 0xa391, 0x0c7f, 0x0078,
+ 0x35f3, 0xac80, 0x0008, 0xa0fa, 0xa3d1, 0x0048, 0x35f1, 0x2001,
+ 0xa391, 0x7036, 0x0c7f, 0x0f7f, 0x127f, 0x0e7f, 0x007c, 0x027e,
+ 0x2001, 0xa352, 0x2004, 0xd0c4, 0x0040, 0x3602, 0x2011, 0x8014,
+ 0x1078, 0x3579, 0x027f, 0x007c, 0x81ff, 0x00c0, 0x2b56, 0x127e,
+ 0x2091, 0x8000, 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x1078,
+ 0x4171, 0x127f, 0x0078, 0x2b2c, 0x7824, 0x2008, 0xa18c, 0xfffd,
+ 0x00c0, 0x361f, 0x61d4, 0xa10d, 0x61d6, 0x0078, 0x2b2c, 0x0078,
+ 0x2b5a, 0x81ff, 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x00c0,
+ 0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x2b56, 0x1078,
+ 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+ 0x00c0, 0x363e, 0x7828, 0xa005, 0x0040, 0x2b2c, 0x0c7e, 0x1078,
+ 0x3518, 0x0c7f, 0x0040, 0x2b56, 0x6837, 0x0000, 0x6833, 0x0000,
+ 0x6838, 0xc0fd, 0x683a, 0x1078, 0x8c4d, 0x0040, 0x2b56, 0x7007,
+ 0x0003, 0x701b, 0x3654, 0x007c, 0x6830, 0xa086, 0x0100, 0x0040,
+ 0x2b56, 0x0078, 0x2b2c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003,
+ 0x00c0, 0x2b56, 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x1078,
+ 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023,
+ 0x0000, 0x702f, 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x1078,
+ 0x4501, 0x00c0, 0x36d8, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006,
+ 0x0040, 0x3688, 0xa0c4, 0xff00, 0xa8c6, 0x0600, 0x00c0, 0x36d8,
+ 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x3695, 0x1078, 0x47cb,
+ 0x00c0, 0x3695, 0xd79c, 0x0040, 0x36d8, 0xd794, 0x00c0, 0x369b,
+ 0xd784, 0x0040, 0x36a7, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+ 0x0004, 0x53a3, 0x1078, 0x338c, 0xd794, 0x0040, 0x36b0, 0xac80,
+ 0x000a, 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x1078, 0x338c,
+ 0x21a2, 0xd794, 0x0040, 0x36d0, 0xac80, 0x0000, 0x2098, 0x94a0,
+ 0x20a9, 0x0002, 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80,
+ 0x0004, 0x2098, 0x3400, 0x20a9, 0x0002, 0x53a3, 0x1078, 0x337e,
+ 0xac80, 0x0026, 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0078, 0x36d1,
+ 0x94a0, 0xd794, 0x0040, 0x36d6, 0xa6b0, 0x000b, 0xa6b0, 0x0005,
+ 0x8108, 0xd78c, 0x0040, 0x36e2, 0xa186, 0x0100, 0x0040, 0x36f3,
+ 0x0078, 0x36e6, 0xa186, 0x007e, 0x0040, 0x36f3, 0xd794, 0x0040,
+ 0x36ed, 0xa686, 0x0020, 0x0078, 0x36ef, 0xa686, 0x0028, 0x0040,
+ 0x36fc, 0x0078, 0x3677, 0x86ff, 0x00c0, 0x36fa, 0x7120, 0x810b,
+ 0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa600, 0x7022,
+ 0x772a, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6612, 0x7024, 0x600e,
+ 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x1078, 0x13d1, 0x7007,
+ 0x0002, 0x701b, 0x3714, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3726,
+ 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031, 0x0000, 0x2061, 0xa3d1,
+ 0x6224, 0x6328, 0x642c, 0x6530, 0x0078, 0x3677, 0x7120, 0x810b,
+ 0x0078, 0x2b2c, 0x2029, 0x007e, 0x7924, 0x7a28, 0x7b2c, 0x7c38,
+ 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502,
+ 0x0048, 0x2b5a, 0xa184, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+ 0xa502, 0x0048, 0x2b5a, 0xa284, 0xff00, 0x8007, 0xa0e2, 0x0020,
+ 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa284, 0x00ff, 0xa0e2,
+ 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0xa384, 0xff00,
+ 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048, 0x2b5a,
+ 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0048, 0x2b5a, 0xa502, 0x0048,
+ 0x2b5a, 0xa484, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0048, 0x2b5a,
+ 0xa502, 0x0048, 0x2b5a, 0xa484, 0x00ff, 0xa0e2, 0x0020, 0x0048,
+ 0x2b5a, 0xa502, 0x0048, 0x2b5a, 0x2061, 0xa5a3, 0x6102, 0x6206,
+ 0x630a, 0x640e, 0x0078, 0x2b2c, 0x007e, 0x2001, 0xa352, 0x2004,
+ 0xd0cc, 0x007f, 0x007c, 0x007e, 0x2001, 0xa371, 0x2004, 0xd0bc,
+ 0x007f, 0x007c, 0x6160, 0x7a24, 0x6300, 0x82ff, 0x00c0, 0x379b,
+ 0x7926, 0x0078, 0x2b2c, 0x83ff, 0x00c0, 0x2b5a, 0x2001, 0xfff0,
+ 0xa200, 0x00c8, 0x2b5a, 0x2019, 0xffff, 0x6064, 0xa302, 0xa200,
+ 0x0048, 0x2b5a, 0x7926, 0x6262, 0x0078, 0x2b2c, 0x2001, 0xa300,
+ 0x2004, 0xa086, 0x0003, 0x00c0, 0x2b56, 0x7c28, 0x7d24, 0x7e38,
+ 0x7f2c, 0x1078, 0x3518, 0x0040, 0x2b56, 0x2009, 0x0000, 0x2019,
+ 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80, 0x0003, 0x7026,
+ 0x20a0, 0xa1e0, 0xa434, 0x2c64, 0x8cff, 0x0040, 0x37e8, 0x6004,
+ 0xa084, 0x00ff, 0xa086, 0x0006, 0x0040, 0x37dd, 0x6004, 0xa084,
+ 0xff00, 0xa086, 0x0600, 0x00c0, 0x37e8, 0x6014, 0x20a2, 0x94a0,
+ 0x6010, 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002,
+ 0x8108, 0xa182, 0x00ff, 0x0040, 0x37f3, 0xa386, 0x002a, 0x0040,
+ 0x37fc, 0x0078, 0x37c9, 0x83ff, 0x00c0, 0x37fa, 0x7120, 0x810c,
+ 0x0078, 0x2b2c, 0x702f, 0x0001, 0x711e, 0x7020, 0xa300, 0x7022,
+ 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6312, 0x7024, 0x600e, 0x6426,
+ 0x652a, 0x662e, 0x6732, 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002,
+ 0x701b, 0x3813, 0x007c, 0x702c, 0xa005, 0x00c0, 0x3824, 0x711c,
+ 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xa3d1, 0x6424, 0x6528,
+ 0x662c, 0x6730, 0x0078, 0x37c9, 0x7120, 0x810c, 0x0078, 0x2b2c,
+ 0x81ff, 0x00c0, 0x2b56, 0x60c8, 0xd09c, 0x0040, 0x2b56, 0x1078,
+ 0x3518, 0x0040, 0x2b56, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x1078, 0x3562, 0x701b, 0x383d, 0x007c, 0x0d7e, 0xade8, 0x000d,
+ 0x6828, 0xa0be, 0x7000, 0x0040, 0x3850, 0xa0be, 0x7100, 0x0040,
+ 0x3850, 0xa0be, 0x7200, 0x0040, 0x3850, 0x0d7f, 0x0078, 0x2b5a,
+ 0x6820, 0x6924, 0x1078, 0x24e3, 0x00c0, 0x387b, 0x1078, 0x4499,
+ 0x00c0, 0x387b, 0x7122, 0x6612, 0x6516, 0x6e18, 0x0c7e, 0x1078,
+ 0x3518, 0x0040, 0x387b, 0x1078, 0x3518, 0x0040, 0x387b, 0x0c7f,
+ 0x0d7f, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000,
+ 0x6804, 0x2068, 0x1078, 0x8bbd, 0x0040, 0x2b56, 0x7007, 0x0003,
+ 0x701b, 0x387e, 0x007c, 0x0d7f, 0x0078, 0x2b56, 0x7120, 0x1078,
+ 0x2921, 0x6820, 0xa086, 0x8001, 0x0040, 0x2b56, 0x2d00, 0x701e,
+ 0x6804, 0xa080, 0x0002, 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0,
+ 0x1078, 0x41be, 0x007f, 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10,
+ 0x6d14, 0x2061, 0xa3d1, 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6,
+ 0x7000, 0x00c0, 0x38a5, 0x0078, 0x38a9, 0xa7c6, 0x7100, 0x00c0,
+ 0x38b1, 0xa6c2, 0x0004, 0x0048, 0x2b5a, 0x2009, 0x0004, 0x0078,
+ 0x3566, 0xa7c6, 0x7200, 0x00c0, 0x2b5a, 0xa6c2, 0x0054, 0x0048,
+ 0x2b5a, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a, 0x642e, 0x6532,
+ 0x2c10, 0x1078, 0x13d1, 0x7007, 0x0002, 0x701b, 0x38c8, 0x007c,
+ 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002,
+ 0x007e, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x1078, 0x41be, 0x007f,
+ 0x2009, 0x002a, 0x2061, 0xa3d1, 0x6224, 0x6328, 0x642c, 0x6530,
+ 0x0078, 0x3566, 0x81ff, 0x00c0, 0x2b56, 0x1078, 0x3530, 0x0040,
+ 0x2b5a, 0x1078, 0x45a7, 0x0040, 0x2b56, 0x1078, 0x4710, 0x0078,
+ 0x2b2c, 0x7824, 0xd084, 0x0040, 0x3150, 0x1078, 0x3542, 0x0040,
+ 0x2b5a, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x00c0, 0x3903, 0x2009,
+ 0x0002, 0x0078, 0x2b56, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006,
+ 0x0040, 0x3910, 0xa08e, 0x0004, 0x0040, 0x3910, 0xa08e, 0x0005,
+ 0x00c0, 0x3934, 0x2001, 0xa352, 0x2004, 0xd0b4, 0x0040, 0x3185,
+ 0x6000, 0xd08c, 0x00c0, 0x3185, 0x6837, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x1078, 0x8bd9, 0x00c0, 0x3929, 0x2009, 0x0003, 0x0078,
+ 0x2b56, 0x7007, 0x0003, 0x701b, 0x392e, 0x007c, 0x1078, 0x3542,
+ 0x0040, 0x2b5a, 0x0078, 0x3185, 0x2009, 0xa32e, 0x210c, 0x81ff,
+ 0x0040, 0x393e, 0x2009, 0x0001, 0x0078, 0x2b56, 0x2001, 0xa300,
+ 0x2004, 0xa086, 0x0003, 0x0040, 0x3949, 0x2009, 0x0007, 0x0078,
+ 0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x0040, 0x3953, 0x2009,
+ 0x0008, 0x0078, 0x2b56, 0x609c, 0xd0a4, 0x00c0, 0x395a, 0xd0ac,
+ 0x00c0, 0x3185, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x1078, 0x8c4d, 0x00c0, 0x3969, 0x2009, 0x0003, 0x0078,
+ 0x2b56, 0x7007, 0x0003, 0x701b, 0x396e, 0x007c, 0x6830, 0xa086,
+ 0x0100, 0x00c0, 0x3977, 0x2009, 0x0004, 0x0078, 0x2b56, 0x1078,
+ 0x3542, 0x0040, 0x2b5a, 0x0078, 0x3912, 0x81ff, 0x2009, 0x0001,
+ 0x00c0, 0x2b56, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0,
+ 0x2b56, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x00c0,
+ 0x2b56, 0x1078, 0x3542, 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff,
+ 0xa086, 0x0006, 0x2009, 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078,
+ 0x3518, 0x0c7f, 0x2009, 0x0002, 0x0040, 0x2b56, 0x6837, 0x0000,
+ 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00,
+ 0xa18c, 0x00ff, 0xa006, 0x82ff, 0x00c0, 0x39bc, 0xc0ed, 0x6952,
+ 0x792c, 0x6956, 0x0078, 0x39c5, 0xa28e, 0x0100, 0x00c0, 0x2b5a,
+ 0xc0e5, 0x6853, 0x0000, 0x6857, 0x0000, 0x683e, 0x1078, 0x8df6,
+ 0x2009, 0x0003, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b, 0x39d1,
+ 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040, 0x2b56,
+ 0x0078, 0x2b2c, 0x81ff, 0x2009, 0x0001, 0x00c0, 0x2b56, 0x6000,
+ 0xa086, 0x0003, 0x2009, 0x0007, 0x00c0, 0x2b56, 0x1078, 0x3542,
+ 0x0040, 0x2b5a, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009,
+ 0x0009, 0x00c0, 0x2b56, 0x0c7e, 0x1078, 0x3518, 0x0c7f, 0x2009,
+ 0x0002, 0x0040, 0x2b56, 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c,
+ 0x7b28, 0x7c3c, 0x7d38, 0x1078, 0x3562, 0x701b, 0x3a08, 0x007c,
+ 0x0d7e, 0xade8, 0x000f, 0x6800, 0xa086, 0x0500, 0x00c0, 0x3a1b,
+ 0x6804, 0xa005, 0x00c0, 0x3a1b, 0x6808, 0xa084, 0xff00, 0x00c0,
+ 0x3a1b, 0x0078, 0x3a1e, 0x0d7f, 0x00c0, 0x2b5a, 0x0d7f, 0x6837,
+ 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x0c7e, 0x1078,
+ 0x3542, 0x00c0, 0x3a2e, 0x0c7f, 0x0078, 0x2b5a, 0x1078, 0x8e52,
+ 0x2009, 0x0003, 0x0c7f, 0x0040, 0x2b56, 0x7007, 0x0003, 0x701b,
+ 0x3a3a, 0x007c, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0040,
+ 0x2b56, 0x0078, 0x2b2c, 0x127e, 0x0c7e, 0x0e7e, 0x2061, 0x0100,
+ 0x2071, 0xa300, 0x6044, 0xd0a4, 0x00c0, 0x3a6c, 0xd084, 0x0040,
+ 0x3a55, 0x1078, 0x3bcc, 0x0078, 0x3a68, 0xd08c, 0x0040, 0x3a5c,
+ 0x1078, 0x3ae3, 0x0078, 0x3a68, 0xd094, 0x0040, 0x3a63, 0x1078,
+ 0x3ab7, 0x0078, 0x3a68, 0xd09c, 0x0040, 0x3a68, 0x1078, 0x3a76,
+ 0x0e7f, 0x0c7f, 0x127f, 0x007c, 0x017e, 0x6128, 0xd19c, 0x00c0,
+ 0x3a73, 0xc19d, 0x612a, 0x017f, 0x0078, 0x3a68, 0x624c, 0xa286,
+ 0xf0f0, 0x00c0, 0x3a87, 0x6048, 0xa086, 0xf0f0, 0x0040, 0x3a87,
+ 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0078, 0x3ab6, 0xa294,
+ 0xff00, 0xa296, 0xf700, 0x0040, 0x3a9c, 0x7134, 0xd1a4, 0x00c0,
+ 0x3a9c, 0x6240, 0xa294, 0x0010, 0x0040, 0x3a9c, 0x2009, 0x00f7,
+ 0x1078, 0x41de, 0x0078, 0x3ab6, 0x6043, 0x0040, 0x6043, 0x0000,
+ 0x7073, 0x0000, 0x708b, 0x0001, 0x70af, 0x0000, 0x70cb, 0x0000,
+ 0x2009, 0xa9c0, 0x200b, 0x0000, 0x7083, 0x0000, 0x7077, 0x000f,
+ 0x2009, 0x000f, 0x2011, 0x4122, 0x1078, 0x596c, 0x007c, 0x157e,
+ 0x7074, 0xa005, 0x00c0, 0x3ae1, 0x2011, 0x4122, 0x1078, 0x58d4,
+ 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9, 0x00c8,
+ 0x6044, 0xd08c, 0x00c0, 0x3ada, 0x00f0, 0x3ac8, 0x6242, 0x7087,
+ 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+ 0x0078, 0x3ae1, 0x6242, 0x7087, 0x0000, 0x707b, 0x0000, 0x0078,
+ 0x3ae1, 0x157f, 0x007c, 0x7078, 0xa08a, 0x0003, 0x00c8, 0x3aec,
+ 0x1079, 0x3aef, 0x0078, 0x3aee, 0x1078, 0x1328, 0x007c, 0x3af2,
+ 0x3b41, 0x3bcb, 0x0f7e, 0x707b, 0x0001, 0x20e1, 0xa000, 0x20e1,
+ 0x8700, 0x1078, 0x218b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2079,
+ 0xa800, 0x207b, 0x2200, 0x7807, 0x00ef, 0x780b, 0x0000, 0x780f,
+ 0x00ef, 0x7813, 0x0138, 0x7817, 0x0000, 0x781b, 0x0000, 0x781f,
+ 0x0000, 0x7823, 0xffff, 0x7827, 0xffff, 0x782b, 0x0000, 0x782f,
+ 0x0000, 0x2079, 0xa80c, 0x207b, 0x1101, 0x7807, 0x0000, 0x2099,
+ 0xa305, 0x20a1, 0xa80e, 0x20a9, 0x0004, 0x53a3, 0x2079, 0xa812,
+ 0x207b, 0x0000, 0x7807, 0x0000, 0x2099, 0xa800, 0x20a1, 0x020b,
+ 0x20a9, 0x0014, 0x53a6, 0x60c3, 0x000c, 0x600f, 0x0000, 0x1078,
+ 0x4158, 0x0f7f, 0x707f, 0x0000, 0x6043, 0x0008, 0x6043, 0x0000,
+ 0x007c, 0x0d7e, 0x707c, 0x707f, 0x0000, 0xa025, 0x0040, 0x3bb5,
+ 0x6020, 0xd0b4, 0x00c0, 0x3bb3, 0x7188, 0x81ff, 0x0040, 0x3ba2,
+ 0xa486, 0x000c, 0x00c0, 0x3bad, 0xa480, 0x0018, 0x8004, 0x20a8,
+ 0x2011, 0xa880, 0x2019, 0xa800, 0x220c, 0x2304, 0xa106, 0x00c0,
+ 0x3b79, 0x8210, 0x8318, 0x00f0, 0x3b5c, 0x6043, 0x0004, 0x608b,
+ 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006, 0x707b, 0x0002, 0x7087,
+ 0x0002, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c, 0x0078,
+ 0x3bb3, 0x2069, 0xa880, 0x6930, 0xa18e, 0x1101, 0x00c0, 0x3bad,
+ 0x6834, 0xa005, 0x00c0, 0x3bad, 0x6900, 0xa18c, 0x00ff, 0x00c0,
+ 0x3b8d, 0x6804, 0xa005, 0x0040, 0x3ba2, 0x2011, 0xa88e, 0x2019,
+ 0xa305, 0x20a9, 0x0004, 0x220c, 0x2304, 0xa102, 0x0048, 0x3ba0,
+ 0x00c0, 0x3bad, 0x8210, 0x8318, 0x00f0, 0x3b93, 0x0078, 0x3bad,
+ 0x708b, 0x0000, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+ 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x6043, 0x0008, 0x6043,
+ 0x0000, 0x0078, 0x3bb5, 0x0d7f, 0x007c, 0x6020, 0xd0b4, 0x00c0,
+ 0x3bb3, 0x60c3, 0x000c, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+ 0x0000, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x1078,
+ 0x6c38, 0x0078, 0x3bb3, 0x007c, 0x7084, 0xa08a, 0x001d, 0x00c8,
+ 0x3bd5, 0x1079, 0x3bd8, 0x0078, 0x3bd7, 0x1078, 0x1328, 0x007c,
+ 0x3c02, 0x3c11, 0x3c40, 0x3c59, 0x3c85, 0x3cb1, 0x3cdd, 0x3d13,
+ 0x3d3f, 0x3d67, 0x3daa, 0x3dd4, 0x3df6, 0x3e0c, 0x3e32, 0x3e45,
+ 0x3e4e, 0x3e7e, 0x3eaa, 0x3ed6, 0x3f02, 0x3f38, 0x3f7d, 0x3fac,
+ 0x3fce, 0x4010, 0x4036, 0x404f, 0x4050, 0x0c7e, 0x2061, 0xa300,
+ 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9, 0x6006,
+ 0x0c7f, 0x007c, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0002,
+ 0x7087, 0x0001, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+ 0x007c, 0x0f7e, 0x707c, 0xa086, 0x0014, 0x00c0, 0x3c3e, 0x6043,
+ 0x0000, 0x6020, 0xd0b4, 0x00c0, 0x3c3e, 0x2079, 0xa880, 0x7a30,
+ 0xa296, 0x1102, 0x00c0, 0x3c3c, 0x7834, 0xa005, 0x00c0, 0x3c3c,
+ 0x7a38, 0xd2fc, 0x0040, 0x3c32, 0x70ac, 0xa005, 0x00c0, 0x3c32,
+ 0x70af, 0x0001, 0x2011, 0x4129, 0x1078, 0x58d4, 0x7087, 0x0010,
+ 0x1078, 0x3e4e, 0x0078, 0x3c3e, 0x1078, 0x4171, 0x0f7f, 0x007c,
+ 0x7087, 0x0003, 0x6043, 0x0004, 0x2011, 0x4129, 0x1078, 0x58d4,
+ 0x1078, 0x41c6, 0x20a3, 0x1102, 0x20a3, 0x0000, 0x20a9, 0x000a,
+ 0x20a3, 0x0000, 0x00f0, 0x3c50, 0x60c3, 0x0014, 0x1078, 0x4158,
+ 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3c83, 0x2011, 0x4129,
+ 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3c81, 0x2079, 0xa880,
+ 0x7a30, 0xa296, 0x1102, 0x00c0, 0x3c81, 0x7834, 0xa005, 0x00c0,
+ 0x3c81, 0x7a38, 0xd2fc, 0x0040, 0x3c7b, 0x70ac, 0xa005, 0x00c0,
+ 0x3c7b, 0x70af, 0x0001, 0x7087, 0x0004, 0x1078, 0x3c85, 0x0078,
+ 0x3c83, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0005, 0x1078,
+ 0x41c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+ 0x1078, 0x4211, 0x00c0, 0x3ca3, 0x7070, 0xa005, 0x00c0, 0x3ca3,
+ 0x714c, 0xa186, 0xffff, 0x0040, 0x3ca3, 0x1078, 0x40ea, 0x0040,
+ 0x3ca3, 0x1078, 0x41f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158,
+ 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3cdb, 0x2011, 0x4129,
+ 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3cd9, 0x2079, 0xa880,
+ 0x7a30, 0xa296, 0x1103, 0x00c0, 0x3cd9, 0x7834, 0xa005, 0x00c0,
+ 0x3cd9, 0x7a38, 0xd2fc, 0x0040, 0x3cd3, 0x70ac, 0xa005, 0x00c0,
+ 0x3cd3, 0x70af, 0x0001, 0x7087, 0x0006, 0x1078, 0x3cdd, 0x0078,
+ 0x3cdb, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0007, 0x1078,
+ 0x41c6, 0x20a3, 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e,
+ 0x1078, 0x4211, 0x00c0, 0x3d05, 0x7070, 0xa005, 0x00c0, 0x3d05,
+ 0x7150, 0xa186, 0xffff, 0x0040, 0x3d05, 0xa180, 0x293f, 0x200c,
+ 0xa18c, 0xff00, 0x810f, 0x1078, 0x40ea, 0x0040, 0x3d05, 0x1078,
+ 0x378b, 0x0040, 0x3d05, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298,
+ 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+ 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3d3d,
+ 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3d3b,
+ 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104, 0x00c0, 0x3d3b, 0x7834,
+ 0xa005, 0x00c0, 0x3d3b, 0x7a38, 0xd2fc, 0x0040, 0x3d35, 0x70ac,
+ 0xa005, 0x00c0, 0x3d35, 0x70af, 0x0001, 0x7087, 0x0008, 0x1078,
+ 0x3d3f, 0x0078, 0x3d3d, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087,
+ 0x0009, 0x1078, 0x41c6, 0x20a3, 0x1105, 0x20a3, 0x0100, 0x3430,
+ 0x1078, 0x4211, 0x00c0, 0x3d58, 0x7070, 0xa005, 0x00c0, 0x3d58,
+ 0x1078, 0x4051, 0x00c0, 0x3d62, 0xa085, 0x0001, 0x1078, 0x2500,
+ 0x20a9, 0x0008, 0x2099, 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e,
+ 0x707c, 0xa005, 0x0040, 0x3da8, 0x2011, 0x4129, 0x1078, 0x58d4,
+ 0xa086, 0x0014, 0x00c0, 0x3da6, 0x2079, 0xa880, 0x7a30, 0xa296,
+ 0x1105, 0x00c0, 0x3da6, 0x7834, 0x2011, 0x0100, 0xa21e, 0x00c0,
+ 0x3d91, 0x7a38, 0xd2fc, 0x0040, 0x3d8b, 0x70ac, 0xa005, 0x00c0,
+ 0x3d8b, 0x70af, 0x0001, 0x7087, 0x000a, 0x1078, 0x3daa, 0x0078,
+ 0x3da8, 0xa005, 0x00c0, 0x3da6, 0x7a38, 0xd2fc, 0x0040, 0x3d9e,
+ 0x70ac, 0xa005, 0x00c0, 0x3d9e, 0x70af, 0x0001, 0x7083, 0x0000,
+ 0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3da8, 0x1078, 0x4171,
+ 0x0f7f, 0x007c, 0x7087, 0x000b, 0x2011, 0xa80e, 0x22a0, 0x20a9,
+ 0x0040, 0x2019, 0xffff, 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000,
+ 0x41a4, 0x1078, 0x41c6, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x1078,
+ 0x4211, 0x0040, 0x3dc7, 0x2013, 0x0000, 0x0078, 0x3dcb, 0x6030,
+ 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9, 0x0042, 0x53a6, 0x60c3,
+ 0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+ 0x3df4, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+ 0x3df2, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3df2,
+ 0x7834, 0xa005, 0x00c0, 0x3df2, 0x7087, 0x000c, 0x1078, 0x3df6,
+ 0x0078, 0x3df4, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x000d,
+ 0x1078, 0x41c6, 0x20a3, 0x1107, 0x20a3, 0x0000, 0x2099, 0xa88e,
+ 0x20a9, 0x0040, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0084, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+ 0x3e30, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+ 0x3e2e, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1107, 0x00c0, 0x3e2e,
+ 0x7834, 0xa005, 0x00c0, 0x3e2e, 0x7083, 0x0001, 0x1078, 0x41b8,
+ 0x7087, 0x000e, 0x1078, 0x3e32, 0x0078, 0x3e30, 0x1078, 0x4171,
+ 0x0f7f, 0x007c, 0x7087, 0x000f, 0x707f, 0x0000, 0x608b, 0xbc85,
+ 0x608f, 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0,
+ 0x2011, 0x4129, 0x1078, 0x58c7, 0x007c, 0x707c, 0xa005, 0x0040,
+ 0x3e4d, 0x2011, 0x4129, 0x1078, 0x58d4, 0x007c, 0x7087, 0x0011,
+ 0x1078, 0x4211, 0x00c0, 0x3e67, 0x7168, 0x81ff, 0x0040, 0x3e67,
+ 0x2009, 0x0000, 0x706c, 0xa084, 0x00ff, 0x1078, 0x24e3, 0xa186,
+ 0x0080, 0x0040, 0x3e67, 0x2011, 0xa88e, 0x1078, 0x40ea, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x747c,
+ 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004, 0x20a8,
+ 0x53a6, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+ 0xa005, 0x0040, 0x3ea8, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+ 0x0014, 0x00c0, 0x3ea6, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1103,
+ 0x00c0, 0x3ea6, 0x7834, 0xa005, 0x00c0, 0x3ea6, 0x7a38, 0xd2fc,
+ 0x0040, 0x3ea0, 0x70ac, 0xa005, 0x00c0, 0x3ea0, 0x70af, 0x0001,
+ 0x7087, 0x0012, 0x1078, 0x3eaa, 0x0078, 0x3ea8, 0x1078, 0x4171,
+ 0x0f7f, 0x007c, 0x7087, 0x0013, 0x1078, 0x41d2, 0x20a3, 0x1103,
+ 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+ 0x3ec8, 0x7070, 0xa005, 0x00c0, 0x3ec8, 0x714c, 0xa186, 0xffff,
+ 0x0040, 0x3ec8, 0x1078, 0x40ea, 0x0040, 0x3ec8, 0x1078, 0x41f5,
+ 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c,
+ 0xa005, 0x0040, 0x3f00, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086,
+ 0x0014, 0x00c0, 0x3efe, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1104,
+ 0x00c0, 0x3efe, 0x7834, 0xa005, 0x00c0, 0x3efe, 0x7a38, 0xd2fc,
+ 0x0040, 0x3ef8, 0x70ac, 0xa005, 0x00c0, 0x3ef8, 0x70af, 0x0001,
+ 0x7087, 0x0014, 0x1078, 0x3f02, 0x0078, 0x3f00, 0x1078, 0x4171,
+ 0x0f7f, 0x007c, 0x7087, 0x0015, 0x1078, 0x41d2, 0x20a3, 0x1104,
+ 0x20a3, 0x0000, 0x3430, 0x2011, 0xa88e, 0x1078, 0x4211, 0x00c0,
+ 0x3f2a, 0x7070, 0xa005, 0x00c0, 0x3f2a, 0x7150, 0xa186, 0xffff,
+ 0x0040, 0x3f2a, 0xa180, 0x293f, 0x200c, 0xa18c, 0xff00, 0x810f,
+ 0x1078, 0x40ea, 0x0040, 0x3f2a, 0x1078, 0x378b, 0x0040, 0x3f2a,
+ 0x1078, 0x2500, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x4158, 0x007c,
+ 0x0f7e, 0x707c, 0xa005, 0x0040, 0x3f7b, 0x2011, 0x4129, 0x1078,
+ 0x58d4, 0xa086, 0x0014, 0x00c0, 0x3f79, 0x2079, 0xa880, 0x7a30,
+ 0xa296, 0x1105, 0x00c0, 0x3f79, 0x7834, 0x2011, 0x0100, 0xa21e,
+ 0x00c0, 0x3f5e, 0x7a38, 0xd2fc, 0x0040, 0x3f5c, 0x70ac, 0xa005,
+ 0x00c0, 0x3f5c, 0x70af, 0x0001, 0x0078, 0x3f6d, 0xa005, 0x00c0,
+ 0x3f79, 0x7a38, 0xd2fc, 0x0040, 0x3f6b, 0x70ac, 0xa005, 0x00c0,
+ 0x3f6b, 0x70af, 0x0001, 0x7083, 0x0000, 0x7a38, 0xd2f4, 0x0040,
+ 0x3f73, 0x70cb, 0x0008, 0x7087, 0x0016, 0x1078, 0x3f7d, 0x0078,
+ 0x3f7b, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b, 0x20a9, 0x000e, 0x53a6,
+ 0x3430, 0x2011, 0xa88e, 0x7087, 0x0017, 0x1078, 0x4211, 0x00c0,
+ 0x3f9d, 0x7070, 0xa005, 0x00c0, 0x3f9d, 0x1078, 0x4051, 0x00c0,
+ 0x3fa7, 0xa085, 0x0001, 0x1078, 0x2500, 0x20a9, 0x0008, 0x2099,
+ 0xa88e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0014, 0x1078, 0x4158, 0x007c, 0x0f7e, 0x707c, 0xa005, 0x0040,
+ 0x3fcc, 0x2011, 0x4129, 0x1078, 0x58d4, 0xa086, 0x0084, 0x00c0,
+ 0x3fca, 0x2079, 0xa880, 0x7a30, 0xa296, 0x1106, 0x00c0, 0x3fca,
+ 0x7834, 0xa005, 0x00c0, 0x3fca, 0x7087, 0x0018, 0x1078, 0x3fce,
+ 0x0078, 0x3fcc, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x0019,
+ 0x1078, 0x41d2, 0x20a3, 0x1106, 0x20a3, 0x0000, 0x3430, 0x2099,
+ 0xa88e, 0x2039, 0xa80e, 0x27a0, 0x20a9, 0x0040, 0x53a3, 0x1078,
+ 0x4211, 0x00c0, 0x4002, 0x2728, 0x2514, 0x8207, 0xa084, 0x00ff,
+ 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007, 0xa205, 0x202a, 0x6030,
+ 0x2310, 0x8214, 0xa2a0, 0xa80e, 0x2414, 0xa38c, 0x0001, 0x0040,
+ 0x3ffd, 0xa294, 0xff00, 0x0078, 0x4000, 0xa294, 0x00ff, 0x8007,
+ 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c,
+ 0x0f7e, 0x707c, 0xa005, 0x0040, 0x4034, 0x2011, 0x4129, 0x1078,
+ 0x58d4, 0xa086, 0x0084, 0x00c0, 0x4032, 0x2079, 0xa880, 0x7a30,
+ 0xa296, 0x1107, 0x00c0, 0x4032, 0x7834, 0xa005, 0x00c0, 0x4032,
+ 0x7083, 0x0001, 0x1078, 0x41b8, 0x7087, 0x001a, 0x1078, 0x4036,
+ 0x0078, 0x4034, 0x1078, 0x4171, 0x0f7f, 0x007c, 0x7087, 0x001b,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880, 0x20a1, 0x020b,
+ 0x747c, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084, 0x03f8, 0x8004,
+ 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x1078, 0x4158, 0x007c, 0x007c,
+ 0x007c, 0x087e, 0x097e, 0x2029, 0xa352, 0x252c, 0x20a9, 0x0008,
+ 0x2041, 0xa80e, 0x28a0, 0x2099, 0xa88e, 0x53a3, 0x20a9, 0x0008,
+ 0x2011, 0x0007, 0xd5d4, 0x0040, 0x4067, 0x2011, 0x0000, 0x2800,
+ 0xa200, 0x200c, 0xa1a6, 0xffff, 0x00c0, 0x4079, 0xd5d4, 0x0040,
+ 0x4074, 0x8210, 0x0078, 0x4075, 0x8211, 0x00f0, 0x4067, 0x0078,
+ 0x40e1, 0x82ff, 0x00c0, 0x408b, 0xd5d4, 0x0040, 0x4085, 0xa1a6,
+ 0x3fff, 0x0040, 0x4071, 0x0078, 0x4089, 0xa1a6, 0x3fff, 0x0040,
+ 0x40e1, 0xa18d, 0xc000, 0x20a9, 0x0010, 0x2019, 0x0001, 0xd5d4,
+ 0x0040, 0x4094, 0x2019, 0x0010, 0x2120, 0xd5d4, 0x0040, 0x409b,
+ 0x8423, 0x0078, 0x409c, 0x8424, 0x00c8, 0x40a9, 0xd5d4, 0x0040,
+ 0x40a4, 0x8319, 0x0078, 0x40a5, 0x8318, 0x00f0, 0x4095, 0x0078,
+ 0x40e1, 0x23a8, 0x2021, 0x0001, 0x8426, 0x8425, 0x00f0, 0x40ad,
+ 0x2328, 0x8529, 0xa2be, 0x0007, 0x0040, 0x40c1, 0x007e, 0x2039,
+ 0x0007, 0x2200, 0xa73a, 0x007f, 0x27a8, 0xa5a8, 0x0010, 0x00f0,
+ 0x40bd, 0x754e, 0xa5c8, 0x293f, 0x292c, 0xa5ac, 0x00ff, 0x6532,
+ 0x60e7, 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x2018, 0x2304,
+ 0xa405, 0x201a, 0x7073, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008,
+ 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0078,
+ 0x40e7, 0xa006, 0x0078, 0x40e7, 0xa006, 0x1078, 0x1328, 0x097f,
+ 0x087f, 0x007c, 0x2118, 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a,
+ 0x0010, 0x0048, 0x40f7, 0x8420, 0x8001, 0x0078, 0x40ef, 0x2118,
+ 0x84ff, 0x0040, 0x4100, 0xa39a, 0x0010, 0x8421, 0x00c0, 0x40fb,
+ 0x2021, 0x0001, 0x83ff, 0x0040, 0x4109, 0x8423, 0x8319, 0x00c0,
+ 0x4105, 0xa238, 0x2704, 0xa42c, 0x00c0, 0x4121, 0xa405, 0x203a,
+ 0x714e, 0xa1a0, 0x293f, 0x242c, 0xa5ac, 0x00ff, 0x6532, 0x60e7,
+ 0x0000, 0x65ea, 0x706b, 0x0000, 0x756e, 0x7073, 0x0001, 0xa084,
+ 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x7077, 0x0000, 0x0e7f,
+ 0x007c, 0x0e7e, 0x0f7e, 0x2001, 0x0002, 0x1078, 0x5975, 0x2079,
+ 0x0100, 0x2071, 0x0140, 0x1078, 0x6c41, 0x7004, 0xa084, 0x4000,
+ 0x0040, 0x413e, 0x7003, 0x1000, 0x7003, 0x0000, 0x127e, 0x2091,
+ 0x8000, 0x2071, 0xa321, 0x2073, 0x0000, 0x7840, 0x027e, 0x017e,
+ 0x2009, 0x00f7, 0x1078, 0x41de, 0x017f, 0xa094, 0x0010, 0xa285,
+ 0x0080, 0x7842, 0x7a42, 0x027f, 0x127f, 0x0f7f, 0x0e7f, 0x007c,
+ 0x127e, 0x2091, 0x8000, 0x2011, 0xa5b5, 0x2013, 0x0000, 0x707f,
+ 0x0000, 0x127f, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575,
+ 0x1078, 0x6c38, 0x2009, 0x07d0, 0x2011, 0x4129, 0x1078, 0x596c,
+ 0x007c, 0x017e, 0x027e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x2009,
+ 0x00f7, 0x1078, 0x41de, 0x2061, 0xa5be, 0x601b, 0x0000, 0x601f,
+ 0x0000, 0x2061, 0xa300, 0x6003, 0x0001, 0x2061, 0x0100, 0x6043,
+ 0x0090, 0x6043, 0x0010, 0x2009, 0x002d, 0x2011, 0x4196, 0x1078,
+ 0x58c7, 0x127f, 0x0c7f, 0x027f, 0x017f, 0x007c, 0x0e7e, 0x007e,
+ 0x127e, 0x2091, 0x8000, 0x2001, 0x0001, 0x1078, 0x5975, 0x2071,
+ 0x0100, 0x1078, 0x6c41, 0x2071, 0x0140, 0x7004, 0xa084, 0x4000,
+ 0x0040, 0x41ae, 0x7003, 0x1000, 0x7003, 0x0000, 0x2001, 0x0001,
+ 0x1078, 0x2480, 0x1078, 0x4171, 0x127f, 0x007f, 0x0e7f, 0x007c,
+ 0x20a9, 0x0040, 0x20a1, 0xa9c0, 0x2099, 0xa88e, 0x3304, 0x8007,
+ 0x20a2, 0x9398, 0x94a0, 0x00f0, 0x41be, 0x007c, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x2099, 0xa800, 0x20a1, 0x020b, 0x20a9, 0x000c,
+ 0x53a6, 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xa880,
+ 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x007c, 0x0c7e, 0x007e,
+ 0x2061, 0x0100, 0x810f, 0x2001, 0xa32e, 0x2004, 0xa005, 0x00c0,
+ 0x41ef, 0x6030, 0xa084, 0x00ff, 0xa105, 0x0078, 0x41f1, 0xa185,
+ 0x00f7, 0x604a, 0x007f, 0x0c7f, 0x007c, 0x017e, 0x047e, 0x2001,
+ 0xa352, 0x2004, 0xd0a4, 0x0040, 0x4208, 0xa006, 0x2020, 0x2009,
+ 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195, 0x2102,
+ 0x2019, 0x002a, 0x2009, 0x0000, 0x1078, 0x27e2, 0x047f, 0x017f,
+ 0x007c, 0x007e, 0x2001, 0xa30c, 0x2004, 0xd09c, 0x0040, 0x4218,
+ 0x007f, 0x007c, 0x007e, 0x017e, 0x127e, 0x2091, 0x8000, 0x2001,
+ 0x0101, 0x200c, 0xa18d, 0x0006, 0x2102, 0x127f, 0x017f, 0x007f,
+ 0x007c, 0x157e, 0x20a9, 0x00ff, 0x2009, 0xa434, 0xa006, 0x200a,
+ 0x8108, 0x00f0, 0x422f, 0x157f, 0x007c, 0x0d7e, 0x037e, 0x157e,
+ 0x137e, 0x147e, 0x2069, 0xa351, 0xa006, 0x6002, 0x6007, 0x0707,
+ 0x600a, 0x600e, 0x6012, 0xa198, 0x293f, 0x231c, 0xa39c, 0x00ff,
+ 0x6316, 0x20a9, 0x0004, 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9,
+ 0x0004, 0xac98, 0x000a, 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e,
+ 0x6052, 0x6056, 0x605a, 0x605e, 0x6062, 0x6066, 0x606a, 0x606e,
+ 0x6072, 0x6076, 0x607a, 0x607e, 0x6082, 0x6086, 0x608a, 0x608e,
+ 0x6092, 0x6096, 0x609a, 0x609e, 0x60ae, 0x61a2, 0x0d7e, 0x60a4,
+ 0xa06d, 0x0040, 0x4275, 0x1078, 0x139a, 0x60a7, 0x0000, 0x60a8,
+ 0xa06d, 0x0040, 0x427d, 0x1078, 0x139a, 0x60ab, 0x0000, 0x0d7f,
+ 0xa006, 0x604a, 0x6810, 0x603a, 0x680c, 0x6046, 0x6814, 0xa084,
+ 0x00ff, 0x6042, 0x147f, 0x137f, 0x157f, 0x037f, 0x0d7f, 0x007c,
+ 0x127e, 0x2091, 0x8000, 0x6944, 0x6e48, 0xa684, 0x3fff, 0xa082,
+ 0x4000, 0x00c8, 0x4361, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+ 0x00c8, 0x4367, 0x2001, 0xa30c, 0x2004, 0xa084, 0x0003, 0x0040,
+ 0x42c2, 0x2001, 0xa30c, 0x2004, 0xd084, 0x00c0, 0x4342, 0xa188,
+ 0xa434, 0x2104, 0xa065, 0x0040, 0x4342, 0x6004, 0xa084, 0x00ff,
+ 0xa08e, 0x0006, 0x00c0, 0x4342, 0x6000, 0xd0c4, 0x0040, 0x4342,
+ 0x0078, 0x42cf, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4326,
+ 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x00c0, 0x432c, 0x60a4,
+ 0xa00d, 0x0040, 0x42d7, 0x1078, 0x4749, 0x0040, 0x4320, 0x60a8,
+ 0xa00d, 0x0040, 0x42f1, 0x1078, 0x479a, 0x00c0, 0x42f1, 0x694c,
+ 0xd1fc, 0x00c0, 0x42e7, 0x1078, 0x441c, 0x0078, 0x431b, 0x1078,
+ 0x43d6, 0x694c, 0xd1ec, 0x00c0, 0x431b, 0x1078, 0x460a, 0x0078,
+ 0x431b, 0x694c, 0xa184, 0xa000, 0x0040, 0x430b, 0xd1ec, 0x0040,
+ 0x4304, 0xd1fc, 0x0040, 0x4300, 0x1078, 0x461b, 0x0078, 0x4307,
+ 0x1078, 0x461b, 0x0078, 0x430b, 0xd1fc, 0x0040, 0x430b, 0x1078,
+ 0x43d6, 0x0078, 0x431b, 0x6050, 0xa00d, 0x0040, 0x4316, 0x2d00,
+ 0x200a, 0x6803, 0x0000, 0x6052, 0x0078, 0x431b, 0x2d00, 0x6052,
+ 0x604e, 0x6803, 0x0000, 0x1078, 0x5c17, 0xa006, 0x127f, 0x007c,
+ 0x2001, 0x0005, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001, 0x0028,
+ 0x2009, 0x0000, 0x0078, 0x436b, 0xa082, 0x0006, 0x00c8, 0x4342,
+ 0x60a0, 0xd0bc, 0x00c0, 0x433e, 0x6100, 0xd1fc, 0x0040, 0x42cf,
+ 0x2001, 0x0029, 0x2009, 0x1000, 0x0078, 0x436b, 0x2001, 0x0028,
+ 0x0078, 0x435d, 0x2009, 0xa30c, 0x210c, 0xd18c, 0x0040, 0x434c,
+ 0x2001, 0x0004, 0x0078, 0x435d, 0xd184, 0x0040, 0x4353, 0x2001,
+ 0x0004, 0x0078, 0x435d, 0x2001, 0x0029, 0x6100, 0xd1fc, 0x0040,
+ 0x435d, 0x2009, 0x1000, 0x0078, 0x436b, 0x2009, 0x0000, 0x0078,
+ 0x436b, 0x2001, 0x0029, 0x2009, 0x0000, 0x0078, 0x436b, 0x2001,
+ 0x0029, 0x2009, 0x0000, 0xa005, 0x127f, 0x007c, 0x6944, 0x6e48,
+ 0xa684, 0x3fff, 0xa082, 0x4000, 0x00c8, 0x43bb, 0xa18c, 0xff00,
+ 0x810f, 0xa182, 0x00ff, 0x00c8, 0x43a1, 0xa188, 0xa434, 0x2104,
+ 0xa065, 0x0040, 0x43a1, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006,
+ 0x00c0, 0x43a7, 0x684c, 0xd0ec, 0x0040, 0x4394, 0x1078, 0x461b,
+ 0x1078, 0x43d6, 0x0078, 0x439c, 0x1078, 0x43d6, 0x684c, 0xd0fc,
+ 0x0040, 0x439c, 0x1078, 0x460a, 0x1078, 0x4663, 0xa006, 0x0078,
+ 0x43bf, 0x2001, 0x0028, 0x2009, 0x0000, 0x0078, 0x43bf, 0xa082,
+ 0x0006, 0x00c8, 0x43b5, 0x6100, 0xd1fc, 0x0040, 0x438a, 0x2001,
+ 0x0029, 0x2009, 0x1000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009,
+ 0x0000, 0x0078, 0x43bf, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005,
+ 0x007c, 0x127e, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0040, 0x43cf,
+ 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x127f, 0x007c, 0x2d00,
+ 0x6052, 0x604e, 0x6803, 0x0000, 0x0078, 0x43cd, 0x127e, 0x2091,
+ 0x8000, 0x604c, 0xa005, 0x0040, 0x43ec, 0x0e7e, 0x2071, 0xa5ab,
+ 0x7004, 0xa086, 0x0002, 0x0040, 0x43f3, 0x0e7f, 0x604c, 0x6802,
+ 0x2d00, 0x604e, 0x127f, 0x007c, 0x2d00, 0x6052, 0x604e, 0x6803,
+ 0x0000, 0x0078, 0x43ea, 0x701c, 0xac06, 0x00c0, 0x43e5, 0x604c,
+ 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x0e7f, 0x127f, 0x007c,
+ 0x127e, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0040, 0x440e, 0x6800,
+ 0xa005, 0x00c0, 0x440c, 0x6052, 0x604e, 0xad05, 0x127f, 0x007c,
+ 0x604c, 0xa06d, 0x0040, 0x441b, 0x6800, 0xa005, 0x00c0, 0x4419,
+ 0x6052, 0x604e, 0xad05, 0x007c, 0x6803, 0x0000, 0x6084, 0xa00d,
+ 0x0040, 0x4426, 0x2d00, 0x200a, 0x6086, 0x007c, 0x2d00, 0x6086,
+ 0x6082, 0x0078, 0x4425, 0x127e, 0x0c7e, 0x027e, 0x2091, 0x8000,
+ 0x6218, 0x2260, 0x6200, 0xa005, 0x0040, 0x4439, 0xc285, 0x0078,
+ 0x443a, 0xc284, 0x6202, 0x027f, 0x0c7f, 0x127f, 0x007c, 0x127e,
+ 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x007e, 0xa086,
+ 0x0006, 0x00c0, 0x445e, 0x609c, 0xd0ac, 0x0040, 0x445e, 0x2001,
+ 0xa352, 0x2004, 0xd0a4, 0x0040, 0x445e, 0xa284, 0xff00, 0x8007,
+ 0xa086, 0x0007, 0x00c0, 0x445e, 0x2011, 0x0600, 0x007f, 0xa294,
+ 0xff00, 0xa215, 0x6206, 0x007e, 0xa086, 0x0006, 0x00c0, 0x446e,
+ 0x6290, 0x82ff, 0x00c0, 0x446e, 0x1078, 0x1328, 0x007f, 0x0c7f,
+ 0x127f, 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x6218, 0x2260,
+ 0x6204, 0x007e, 0xa086, 0x0006, 0x00c0, 0x4490, 0x609c, 0xd0a4,
+ 0x0040, 0x4490, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x4490,
+ 0xa284, 0x00ff, 0xa086, 0x0007, 0x00c0, 0x4490, 0x2011, 0x0006,
+ 0x007f, 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x0c7f, 0x127f,
+ 0x007c, 0x027e, 0xa182, 0x00ff, 0x0048, 0x44a2, 0xa085, 0x0001,
+ 0x0078, 0x44ba, 0xa190, 0xa434, 0x2204, 0xa065, 0x00c0, 0x44b9,
+ 0x017e, 0x0d7e, 0x1078, 0x1366, 0x2d60, 0x0d7f, 0x017f, 0x0040,
+ 0x449e, 0x2c00, 0x2012, 0x60a7, 0x0000, 0x60ab, 0x0000, 0x1078,
+ 0x4235, 0xa006, 0x027f, 0x007c, 0x127e, 0x2091, 0x8000, 0x027e,
+ 0xa182, 0x00ff, 0x0048, 0x44c8, 0xa085, 0x0001, 0x0078, 0x44fe,
+ 0x0d7e, 0xa190, 0xa434, 0x2204, 0xa06d, 0x0040, 0x44fc, 0x2013,
+ 0x0000, 0x0d7e, 0x0c7e, 0x2d60, 0x60a4, 0xa06d, 0x0040, 0x44da,
+ 0x1078, 0x139a, 0x60a8, 0xa06d, 0x0040, 0x44e0, 0x1078, 0x139a,
+ 0x0c7f, 0x0d7f, 0x0d7e, 0x0c7e, 0x68ac, 0x2060, 0x8cff, 0x0040,
+ 0x44f8, 0x600c, 0x007e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+ 0x44f3, 0x1078, 0x13aa, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x44e6,
+ 0x0c7f, 0x0d7f, 0x1078, 0x139a, 0x0d7f, 0xa006, 0x027f, 0x127f,
+ 0x007c, 0x017e, 0xa182, 0x00ff, 0x0048, 0x450a, 0xa085, 0x0001,
+ 0x0078, 0x4511, 0xa188, 0xa434, 0x2104, 0xa065, 0x0040, 0x4506,
+ 0xa006, 0x017f, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x600b,
+ 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x2069, 0xa88e,
+ 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a, 0x0048, 0x4529,
+ 0x603a, 0x6814, 0x6066, 0x2099, 0xa896, 0xac88, 0x000a, 0x21a0,
+ 0x20a9, 0x0004, 0x53a3, 0x2099, 0xa89a, 0xac88, 0x0006, 0x21a0,
+ 0x20a9, 0x0004, 0x53a3, 0x2069, 0xa8ae, 0x6808, 0x606a, 0x690c,
+ 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211, 0x00c8,
+ 0x454d, 0x2009, 0x0008, 0x0078, 0x4577, 0xa182, 0x0259, 0x00c8,
+ 0x4555, 0x2009, 0x0007, 0x0078, 0x4577, 0xa182, 0x02c1, 0x00c8,
+ 0x455d, 0x2009, 0x0006, 0x0078, 0x4577, 0xa182, 0x0349, 0x00c8,
+ 0x4565, 0x2009, 0x0005, 0x0078, 0x4577, 0xa182, 0x0421, 0x00c8,
+ 0x456d, 0x2009, 0x0004, 0x0078, 0x4577, 0xa182, 0x0581, 0x00c8,
+ 0x4575, 0x2009, 0x0003, 0x0078, 0x4577, 0x2009, 0x0002, 0x6192,
+ 0x147f, 0x137f, 0x157f, 0x0d7f, 0x007c, 0x017e, 0x027e, 0x0e7e,
+ 0x2071, 0xa88d, 0x2e04, 0x6896, 0x2071, 0xa88e, 0x7004, 0x689a,
+ 0x701c, 0x689e, 0x6a00, 0x2009, 0xa371, 0x210c, 0xd0bc, 0x0040,
+ 0x4597, 0xd1ec, 0x0040, 0x4597, 0xc2ad, 0x0078, 0x4598, 0xc2ac,
+ 0xd0c4, 0x0040, 0x45a1, 0xd1e4, 0x0040, 0x45a1, 0xc2bd, 0x0078,
+ 0x45a2, 0xc2bc, 0x6a02, 0x0e7f, 0x027f, 0x017f, 0x007c, 0x0d7e,
+ 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x0040, 0x45cb, 0x6900,
+ 0x81ff, 0x00c0, 0x45df, 0x6a04, 0xa282, 0x0010, 0x00c8, 0x45e4,
+ 0xad88, 0x0004, 0x20a9, 0x0010, 0x2104, 0xa086, 0xffff, 0x0040,
+ 0x45c6, 0x8108, 0x00f0, 0x45bc, 0x1078, 0x1328, 0x260a, 0x8210,
+ 0x6a06, 0x0078, 0x45df, 0x1078, 0x1381, 0x0040, 0x45e4, 0x2d00,
+ 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b,
+ 0xffff, 0x8108, 0x00f0, 0x45d7, 0x6807, 0x0001, 0x6e12, 0xa085,
+ 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006, 0x0078, 0x45e1, 0x127e,
+ 0x2091, 0x8000, 0x0d7e, 0x60a4, 0xa00d, 0x0040, 0x4607, 0x2168,
+ 0x6800, 0xa005, 0x00c0, 0x4603, 0x1078, 0x4749, 0x00c0, 0x4607,
+ 0x200b, 0xffff, 0x6804, 0xa08a, 0x0002, 0x0048, 0x4603, 0x8001,
+ 0x6806, 0x0078, 0x4607, 0x1078, 0x139a, 0x60a7, 0x0000, 0x0d7f,
+ 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x47af, 0x0078,
+ 0x4613, 0x1078, 0x43c1, 0x1078, 0x46a7, 0x00c0, 0x4611, 0x1078,
+ 0x4663, 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a8,
+ 0xa06d, 0x0040, 0x463f, 0x6950, 0x81ff, 0x00c0, 0x4653, 0x6a54,
+ 0xa282, 0x0010, 0x00c8, 0x4660, 0xad88, 0x0018, 0x20a9, 0x0010,
+ 0x2104, 0xa086, 0xffff, 0x0040, 0x463a, 0x8108, 0x00f0, 0x4630,
+ 0x1078, 0x1328, 0x260a, 0x8210, 0x6a56, 0x0078, 0x4653, 0x1078,
+ 0x1381, 0x0040, 0x4660, 0x2d00, 0x60aa, 0x6853, 0x0000, 0xad88,
+ 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108, 0x00f0, 0x464b,
+ 0x6857, 0x0001, 0x6e62, 0x0078, 0x4657, 0x1078, 0x441c, 0x1078,
+ 0x466d, 0x00c0, 0x4655, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c,
+ 0xa006, 0x0078, 0x465d, 0x127e, 0x2091, 0x8000, 0x1078, 0x5c17,
+ 0x127f, 0x007c, 0xa01e, 0x0078, 0x466f, 0x2019, 0x0001, 0xa00e,
+ 0x127e, 0x2091, 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x00c0,
+ 0x468d, 0x8dff, 0x0040, 0x46a2, 0x83ff, 0x0040, 0x4685, 0x6848,
+ 0xa606, 0x0040, 0x4692, 0x0078, 0x468d, 0x683c, 0xa406, 0x00c0,
+ 0x468d, 0x6840, 0xa506, 0x0040, 0x4692, 0x2d08, 0x6800, 0x2068,
+ 0x0078, 0x4679, 0x6a00, 0x604c, 0xad06, 0x00c0, 0x469a, 0x624e,
+ 0x0078, 0x469d, 0xa180, 0x0000, 0x2202, 0x82ff, 0x00c0, 0x46a2,
+ 0x6152, 0x8dff, 0x127f, 0x007c, 0xa01e, 0x0078, 0x46a9, 0x2019,
+ 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x0040, 0x46d5, 0x83ff,
+ 0x0040, 0x46b8, 0x6848, 0xa606, 0x0040, 0x46c5, 0x0078, 0x46c0,
+ 0x683c, 0xa406, 0x00c0, 0x46c0, 0x6840, 0xa506, 0x0040, 0x46c5,
+ 0x2d08, 0x6800, 0x2068, 0x0078, 0x46ac, 0x6a00, 0x6080, 0xad06,
+ 0x00c0, 0x46cd, 0x6282, 0x0078, 0x46d0, 0xa180, 0x0000, 0x2202,
+ 0x82ff, 0x00c0, 0x46d5, 0x6186, 0x8dff, 0x007c, 0xa016, 0x1078,
+ 0x4742, 0x00c0, 0x46dd, 0x2011, 0x0001, 0x1078, 0x4793, 0x00c0,
+ 0x46e3, 0xa295, 0x0002, 0x007c, 0x1078, 0x47cb, 0x0040, 0x46ec,
+ 0x1078, 0x8b12, 0x0078, 0x46ee, 0xa085, 0x0001, 0x007c, 0x1078,
+ 0x47cb, 0x0040, 0x46f7, 0x1078, 0x8aaa, 0x0078, 0x46f9, 0xa085,
+ 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040, 0x4702, 0x1078, 0x8af4,
+ 0x0078, 0x4704, 0xa085, 0x0001, 0x007c, 0x1078, 0x47cb, 0x0040,
+ 0x470d, 0x1078, 0x8ac6, 0x0078, 0x470f, 0xa085, 0x0001, 0x007c,
+ 0x1078, 0x47cb, 0x0040, 0x4718, 0x1078, 0x8b30, 0x0078, 0x471a,
+ 0xa085, 0x0001, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x8000,
+ 0x6080, 0xa06d, 0x0040, 0x473a, 0x6800, 0x007e, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x007e, 0x6000, 0xd0fc,
+ 0x0040, 0x4734, 0x1078, 0xa18c, 0x007f, 0x1078, 0x4982, 0x007f,
+ 0x0078, 0x4721, 0x6083, 0x0000, 0x6087, 0x0000, 0x0d7f, 0x007f,
+ 0x127f, 0x007c, 0x60a4, 0xa00d, 0x00c0, 0x4749, 0xa085, 0x0001,
+ 0x007c, 0x0e7e, 0x2170, 0x7000, 0xa005, 0x00c0, 0x475c, 0x20a9,
+ 0x0010, 0xae88, 0x0004, 0x2104, 0xa606, 0x0040, 0x475c, 0x8108,
+ 0x00f0, 0x4753, 0xa085, 0x0001, 0xa006, 0x0e7f, 0x007c, 0x0d7e,
+ 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d, 0x00c0, 0x476d, 0x1078,
+ 0x1381, 0x0040, 0x477f, 0x2d00, 0x60a6, 0x6803, 0x0001, 0x6807,
+ 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010, 0x200b, 0xffff, 0x8108,
+ 0x00f0, 0x4775, 0xa085, 0x0001, 0x127f, 0x0d7f, 0x007c, 0xa006,
+ 0x0078, 0x477c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x60a4, 0xa06d,
+ 0x0040, 0x4790, 0x60a7, 0x0000, 0x1078, 0x139a, 0xa085, 0x0001,
+ 0x127f, 0x0d7f, 0x007c, 0x60a8, 0xa00d, 0x00c0, 0x479a, 0xa085,
+ 0x0001, 0x007c, 0x0e7e, 0x2170, 0x7050, 0xa005, 0x00c0, 0x47ad,
+ 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0040, 0x47ad,
+ 0x8108, 0x00f0, 0x47a4, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x4793, 0x00c0, 0x47c9, 0x200b, 0xffff,
+ 0x0d7e, 0x60a8, 0x2068, 0x6854, 0xa08a, 0x0002, 0x0048, 0x47c4,
+ 0x8001, 0x6856, 0x0078, 0x47c8, 0x1078, 0x139a, 0x60ab, 0x0000,
+ 0x0d7f, 0x127f, 0x007c, 0x609c, 0xd0a4, 0x007c, 0x0f7e, 0x71ac,
+ 0x81ff, 0x00c0, 0x47e9, 0x71c8, 0xd19c, 0x0040, 0x47e9, 0x2001,
+ 0x007e, 0xa080, 0xa434, 0x2004, 0xa07d, 0x0040, 0x47e9, 0x7804,
+ 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x47e9, 0x7800, 0xc0ed,
+ 0x7802, 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x480f, 0x157e,
+ 0x0c7e, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501,
+ 0x00c0, 0x4809, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+ 0x0040, 0x4806, 0xa086, 0x0006, 0x00c0, 0x4809, 0x6000, 0xc0ed,
+ 0x6002, 0x017f, 0x8108, 0x00f0, 0x47f5, 0x0c7f, 0x157f, 0x1078,
+ 0x4897, 0x0040, 0x4818, 0x2001, 0xa59f, 0x200c, 0x0078, 0x4820,
+ 0x2079, 0xa351, 0x7804, 0xd0a4, 0x0040, 0x4824, 0x2009, 0x07d0,
+ 0x2011, 0x4826, 0x1078, 0x596c, 0x0f7f, 0x007c, 0x2011, 0x4826,
+ 0x1078, 0x58d4, 0x1078, 0x4897, 0x0040, 0x484e, 0x2001, 0xa4b2,
+ 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102, 0x2001, 0xa352,
+ 0x2004, 0xd0a4, 0x0040, 0x4842, 0x2009, 0x07d0, 0x2011, 0x4826,
+ 0x1078, 0x596c, 0x0e7e, 0x2071, 0xa300, 0x706b, 0x0000, 0x706f,
+ 0x0000, 0x1078, 0x260d, 0x0e7f, 0x0078, 0x4886, 0x157e, 0x0c7e,
+ 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x1078, 0x4501, 0x00c0,
+ 0x4880, 0x6000, 0xd0ec, 0x0040, 0x4880, 0x047e, 0x62a0, 0xa294,
+ 0x00ff, 0x8227, 0xa006, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6000,
+ 0xc0e5, 0xc0ec, 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700,
+ 0x6006, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000,
+ 0x1078, 0x5c78, 0x2009, 0x0000, 0x1078, 0x9c38, 0x077f, 0x047f,
+ 0x017f, 0x8108, 0x00f0, 0x4854, 0x0c7f, 0x157f, 0x007c, 0x0c7e,
+ 0x6018, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x0c7f, 0x007c, 0x7818,
+ 0x2004, 0xd0ac, 0x007c, 0x7818, 0x2004, 0xd0bc, 0x007c, 0x0f7e,
+ 0x2001, 0xa4b2, 0x2004, 0xa07d, 0x0040, 0x48a0, 0x7800, 0xd0ec,
+ 0x0f7f, 0x007c, 0x127e, 0x027e, 0x2091, 0x8000, 0x6200, 0xa005,
+ 0x0040, 0x48ad, 0xc2fd, 0x0078, 0x48ae, 0xc2fc, 0x6202, 0x027f,
+ 0x127f, 0x007c, 0x2071, 0xa413, 0x7003, 0x0001, 0x7007, 0x0000,
+ 0x7013, 0x0000, 0x7017, 0x0000, 0x701b, 0x0000, 0x701f, 0x0000,
+ 0x700b, 0x0000, 0x704b, 0x0001, 0x704f, 0x0000, 0x705b, 0x0020,
+ 0x705f, 0x0040, 0x707f, 0x0000, 0x2071, 0xa57c, 0x7003, 0xa413,
+ 0x7007, 0x0000, 0x700b, 0x0000, 0x700f, 0xa55c, 0x7013, 0x0020,
+ 0x7017, 0x0040, 0x7037, 0x0000, 0x007c, 0x017e, 0x0e7e, 0x2071,
+ 0xa534, 0xa00e, 0x7186, 0x718a, 0x7097, 0x0001, 0x2001, 0xa352,
+ 0x2004, 0xd0fc, 0x00c0, 0x48f7, 0x2001, 0xa352, 0x2004, 0xa00e,
+ 0xd09c, 0x0040, 0x48f4, 0x8108, 0x7102, 0x0078, 0x494a, 0x2001,
+ 0xa371, 0x200c, 0xa184, 0x000f, 0x2009, 0xa372, 0x210c, 0x0079,
+ 0x4901, 0x48ec, 0x4922, 0x492a, 0x4935, 0x493b, 0x48ec, 0x48ec,
+ 0x48ec, 0x4911, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec, 0x48ec,
+ 0x48ec, 0x7003, 0x0004, 0x137e, 0x147e, 0x157e, 0x2099, 0xa375,
+ 0x20a1, 0xa585, 0x20a9, 0x0004, 0x53a3, 0x157f, 0x147f, 0x137f,
+ 0x0078, 0x494a, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002,
+ 0x0078, 0x4930, 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003,
+ 0x7002, 0x7097, 0x0001, 0x0078, 0x4947, 0x7007, 0x0122, 0x2001,
+ 0x0002, 0x0078, 0x493f, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002,
+ 0xa006, 0x7096, 0x708e, 0xa184, 0xff00, 0x8007, 0x709a, 0xa184,
+ 0x00ff, 0x7092, 0x0e7f, 0x017f, 0x007c, 0x0e7e, 0x2071, 0xa413,
+ 0x684c, 0xa005, 0x00c0, 0x495b, 0x7028, 0xc085, 0x702a, 0xa085,
+ 0x0001, 0x0078, 0x4980, 0x6a60, 0x7236, 0x6b64, 0x733a, 0x6868,
+ 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c, 0x702e, 0x6844,
+ 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000, 0x8007, 0x8006,
+ 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319,
+ 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0xa006,
+ 0x0e7f, 0x007c, 0x0e7e, 0x027e, 0x6838, 0xd0fc, 0x00c0, 0x49d8,
+ 0x6804, 0xa00d, 0x0040, 0x499e, 0x0d7e, 0x2071, 0xa300, 0xa016,
+ 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00, 0x81ff, 0x00c0,
+ 0x4991, 0x702e, 0x70a8, 0xa200, 0x70aa, 0x0d7f, 0x2071, 0xa413,
+ 0x701c, 0xa005, 0x00c0, 0x49ea, 0x0068, 0x49e8, 0x2071, 0xa534,
+ 0x7200, 0x82ff, 0x0040, 0x49e8, 0x6934, 0xa186, 0x0103, 0x00c0,
+ 0x49fb, 0x6948, 0x6844, 0xa105, 0x00c0, 0x49db, 0x2009, 0x8020,
+ 0x2200, 0x0079, 0x49bb, 0x49e8, 0x49c0, 0x4a18, 0x4a26, 0x49e8,
+ 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x49e8, 0x7122, 0x683c,
+ 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x2071,
+ 0xa300, 0x702c, 0x206a, 0x2d00, 0x702e, 0x70a8, 0x8000, 0x70aa,
+ 0x027f, 0x0e7f, 0x007c, 0x6844, 0xa086, 0x0100, 0x00c0, 0x49e8,
+ 0x6868, 0xa005, 0x00c0, 0x49e8, 0x2009, 0x8020, 0x0078, 0x49b8,
+ 0x2071, 0xa413, 0x2d08, 0x206b, 0x0000, 0x7010, 0x8000, 0x7012,
+ 0x7018, 0xa06d, 0x711a, 0x0040, 0x49f8, 0x6902, 0x0078, 0x49f9,
+ 0x711e, 0x0078, 0x49d8, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0040,
+ 0x4a09, 0xa186, 0x001e, 0x0040, 0x4a09, 0xa18e, 0x001f, 0x00c0,
+ 0x49e8, 0x684c, 0xd0cc, 0x0040, 0x49e8, 0x6850, 0xa084, 0x00ff,
+ 0xa086, 0x0001, 0x00c0, 0x49e8, 0x2009, 0x8021, 0x0078, 0x49b8,
+ 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x49e8, 0x7186, 0xae90,
+ 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x4a36, 0x7084, 0x8008,
+ 0xa092, 0x000f, 0x00c8, 0x49e8, 0x7186, 0xae90, 0x0003, 0x8003,
+ 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+ 0x0048, 0x49cf, 0x718c, 0x7084, 0xa10a, 0x0048, 0x49cf, 0x2071,
+ 0x0000, 0x7018, 0xd084, 0x00c0, 0x49cf, 0x2071, 0xa534, 0x7000,
+ 0xa086, 0x0002, 0x00c0, 0x4a56, 0x1078, 0x4cd2, 0x2071, 0x0000,
+ 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf, 0x1078, 0x4cfd,
+ 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x49cf,
+ 0x007e, 0x684c, 0x007e, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80,
+ 0x0011, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x007f, 0xa084, 0x00ff,
+ 0x684e, 0x007f, 0x684a, 0x6952, 0x007c, 0x2071, 0xa413, 0x7004,
+ 0x0079, 0x4a7a, 0x4a84, 0x4a95, 0x4ca3, 0x4ca4, 0x4ccb, 0x4cd1,
+ 0x4a85, 0x4c91, 0x4c32, 0x4cb4, 0x007c, 0x127e, 0x2091, 0x8000,
+ 0x0068, 0x4a94, 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080,
+ 0x7007, 0x0001, 0x700b, 0x0000, 0x127f, 0x2069, 0xa5be, 0x6844,
+ 0xa005, 0x0050, 0x4abd, 0x00c0, 0x4abd, 0x127e, 0x2091, 0x8000,
+ 0x2069, 0x0000, 0x6934, 0x2001, 0xa41f, 0x2004, 0xa10a, 0x0040,
+ 0x4ab8, 0x0068, 0x4abc, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0,
+ 0x4abc, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080,
+ 0x2069, 0xa5be, 0x6847, 0xffff, 0x127f, 0x2069, 0xa300, 0x6844,
+ 0x6960, 0xa102, 0x2069, 0xa534, 0x688a, 0x6984, 0x701c, 0xa06d,
+ 0x0040, 0x4acf, 0x81ff, 0x0040, 0x4b17, 0x0078, 0x4ae5, 0x81ff,
+ 0x0040, 0x4be9, 0x2071, 0xa534, 0x7184, 0x7088, 0xa10a, 0x00c8,
+ 0x4ae5, 0x7190, 0x2071, 0xa5be, 0x7040, 0xa005, 0x0040, 0x4ae5,
+ 0x00d0, 0x4be9, 0x7142, 0x0078, 0x4be9, 0x2071, 0xa534, 0x718c,
+ 0x127e, 0x2091, 0x8000, 0x7084, 0xa10a, 0x0048, 0x4c06, 0x0068,
+ 0x4b9b, 0x2071, 0x0000, 0x7018, 0xd084, 0x00c0, 0x4b9b, 0x2001,
+ 0xffff, 0x2071, 0xa5be, 0x7042, 0x2071, 0xa534, 0x7000, 0xa086,
+ 0x0002, 0x00c0, 0x4b0d, 0x1078, 0x4cd2, 0x2071, 0x0000, 0x701b,
+ 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x1078, 0x4cfd, 0x2071,
+ 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078, 0x4b9b, 0x2071,
+ 0xa534, 0x7000, 0xa005, 0x0040, 0x4bc8, 0x6934, 0xa186, 0x0103,
+ 0x00c0, 0x4b9e, 0x684c, 0xd0bc, 0x00c0, 0x4bc8, 0x6948, 0x6844,
+ 0xa105, 0x00c0, 0x4bbb, 0x2009, 0x8020, 0x2071, 0xa534, 0x7000,
+ 0x0079, 0x4b32, 0x4bc8, 0x4b80, 0x4b58, 0x4b6a, 0x4b37, 0x137e,
+ 0x147e, 0x157e, 0x2099, 0xa375, 0x20a1, 0xa585, 0x20a9, 0x0004,
+ 0x53a3, 0x157f, 0x147f, 0x137f, 0x2071, 0xa57c, 0xad80, 0x000f,
+ 0x700e, 0x7013, 0x0002, 0x7007, 0x0002, 0x700b, 0x0000, 0x2e10,
+ 0x1078, 0x13d1, 0x2071, 0xa413, 0x7007, 0x0009, 0x0078, 0x4be9,
+ 0x7084, 0x8008, 0xa092, 0x001e, 0x00c8, 0x4be9, 0xae90, 0x0003,
+ 0xa210, 0x683c, 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b,
+ 0x0078, 0x4be9, 0x7084, 0x8008, 0xa092, 0x000f, 0x00c8, 0x4be9,
+ 0xae90, 0x0003, 0x8003, 0xa210, 0x683c, 0x2012, 0x8210, 0x6840,
+ 0x2012, 0x7186, 0x2071, 0xa413, 0x1078, 0x4d5b, 0x0078, 0x4be9,
+ 0x127e, 0x2091, 0x8000, 0x0068, 0x4b9b, 0x2071, 0x0000, 0x7018,
+ 0xd084, 0x00c0, 0x4b9b, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+ 0x701b, 0x0001, 0x2091, 0x4080, 0x127f, 0x2071, 0xa413, 0x1078,
+ 0x4d5b, 0x0078, 0x4be9, 0x127f, 0x0078, 0x4be9, 0xa18c, 0x00ff,
+ 0xa186, 0x0017, 0x0040, 0x4bac, 0xa186, 0x001e, 0x0040, 0x4bac,
+ 0xa18e, 0x001f, 0x00c0, 0x4bc8, 0x684c, 0xd0cc, 0x0040, 0x4bc8,
+ 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x00c0, 0x4bc8, 0x2009,
+ 0x8021, 0x0078, 0x4b2d, 0x6844, 0xa086, 0x0100, 0x00c0, 0x4bc8,
+ 0x6868, 0xa005, 0x00c0, 0x4bc8, 0x2009, 0x8020, 0x0078, 0x4b2d,
+ 0x2071, 0xa413, 0x1078, 0x4d6f, 0x0040, 0x4be9, 0x2071, 0xa413,
+ 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff, 0xa086, 0x0003, 0x00c0,
+ 0x4be0, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0040, 0x4be0, 0x710e,
+ 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100, 0x0040,
+ 0x4ca4, 0x127e, 0x2091, 0x8000, 0x2071, 0xa413, 0x7008, 0xa086,
+ 0x0001, 0x00c0, 0x4c04, 0x0068, 0x4c04, 0x2009, 0x000d, 0x7030,
+ 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+ 0x00c0, 0x4c04, 0x7007, 0x0001, 0x127f, 0x007c, 0x2071, 0xa413,
+ 0x1078, 0x4d6f, 0x0040, 0x4c2f, 0x2071, 0xa534, 0x7084, 0x700a,
+ 0x20a9, 0x0020, 0x2099, 0xa535, 0x20a1, 0xa55c, 0x53a3, 0x7087,
+ 0x0000, 0x2071, 0xa413, 0x2069, 0xa57c, 0x706c, 0x6826, 0x7070,
+ 0x682a, 0x7074, 0x682e, 0x7078, 0x6832, 0x2d10, 0x1078, 0x13d1,
+ 0x7007, 0x0008, 0x2001, 0xffff, 0x2071, 0xa5be, 0x7042, 0x127f,
+ 0x0078, 0x4be9, 0x2069, 0xa57c, 0x6808, 0xa08e, 0x0000, 0x0040,
+ 0x4c90, 0xa08e, 0x0200, 0x0040, 0x4c8e, 0xa08e, 0x0100, 0x00c0,
+ 0x4c90, 0x127e, 0x2091, 0x8000, 0x0068, 0x4c8b, 0x2069, 0x0000,
+ 0x6818, 0xd084, 0x00c0, 0x4c8b, 0x702c, 0x7130, 0x8108, 0xa102,
+ 0x0048, 0x4c59, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0078,
+ 0x4c63, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4c63, 0x7070,
+ 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b, 0x0000, 0x2001,
+ 0xa559, 0x2004, 0xa005, 0x00c0, 0x4c82, 0x6934, 0x2069, 0xa534,
+ 0x689c, 0x699e, 0x2069, 0xa5be, 0xa102, 0x00c0, 0x4c7b, 0x6844,
+ 0xa005, 0x00d0, 0x4c89, 0x2001, 0xa55a, 0x200c, 0x810d, 0x6946,
+ 0x0078, 0x4c89, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091,
+ 0x4080, 0x7007, 0x0001, 0x127f, 0x0078, 0x4c90, 0x7007, 0x0005,
+ 0x007c, 0x701c, 0xa06d, 0x0040, 0x4ca2, 0x1078, 0x4d6f, 0x0040,
+ 0x4ca2, 0x7007, 0x0003, 0x1078, 0x4d8f, 0x7050, 0xa086, 0x0100,
+ 0x0040, 0x4ca4, 0x007c, 0x007c, 0x7050, 0xa09e, 0x0100, 0x00c0,
+ 0x4cad, 0x7007, 0x0004, 0x0078, 0x4ccb, 0xa086, 0x0200, 0x00c0,
+ 0x4cb3, 0x7007, 0x0005, 0x007c, 0x2001, 0xa57e, 0x2004, 0xa08e,
+ 0x0100, 0x00c0, 0x4cc0, 0x7007, 0x0001, 0x1078, 0x4d5b, 0x007c,
+ 0xa08e, 0x0000, 0x0040, 0x4cbf, 0xa08e, 0x0200, 0x00c0, 0x4cbf,
+ 0x7007, 0x0005, 0x007c, 0x1078, 0x4d25, 0x7006, 0x1078, 0x4d5b,
+ 0x007c, 0x007c, 0x0e7e, 0x157e, 0x2071, 0xa534, 0x7184, 0x81ff,
+ 0x0040, 0x4cfa, 0xa006, 0x7086, 0xae80, 0x0003, 0x2071, 0x0000,
+ 0x21a8, 0x2014, 0x7226, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722a,
+ 0x8000, 0x0070, 0x4cf7, 0x2014, 0x722e, 0x8000, 0x0070, 0x4cf7,
+ 0x2014, 0x723a, 0x8000, 0x0070, 0x4cf7, 0x2014, 0x723e, 0xa180,
+ 0x8030, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x0e7e, 0x157e, 0x2071,
+ 0xa534, 0x7184, 0x81ff, 0x0040, 0x4d22, 0xa006, 0x7086, 0xae80,
+ 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x2014,
+ 0x722a, 0x8000, 0x0070, 0x4d1b, 0x2014, 0x723a, 0x8000, 0x2014,
+ 0x723e, 0x0078, 0x4d1f, 0x2001, 0x8020, 0x0078, 0x4d21, 0x2001,
+ 0x8042, 0x7022, 0x157f, 0x0e7f, 0x007c, 0x702c, 0x7130, 0x8108,
+ 0xa102, 0x0048, 0x4d32, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072,
+ 0x0078, 0x4d3c, 0x706c, 0xa080, 0x0040, 0x706e, 0x00c8, 0x4d3c,
+ 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x700c, 0x8001, 0x700e,
+ 0x00c0, 0x4d52, 0x127e, 0x2091, 0x8000, 0x0068, 0x4d55, 0x2001,
+ 0x000d, 0x2102, 0x2091, 0x4080, 0x2001, 0x0001, 0x700b, 0x0000,
+ 0x127f, 0x007c, 0x2001, 0x0007, 0x007c, 0x2001, 0x0006, 0x700b,
+ 0x0001, 0x127f, 0x007c, 0x701c, 0xa06d, 0x0040, 0x4d6e, 0x127e,
+ 0x2091, 0x8000, 0x7010, 0x8001, 0x7012, 0x2d04, 0x701e, 0xa005,
+ 0x00c0, 0x4d6b, 0x701a, 0x127f, 0x1078, 0x139a, 0x007c, 0x2019,
+ 0x000d, 0x2304, 0x230c, 0xa10e, 0x0040, 0x4d7e, 0x2304, 0x230c,
+ 0xa10e, 0x0040, 0x4d7e, 0xa006, 0x0078, 0x4d8e, 0x732c, 0x8319,
+ 0x7130, 0xa102, 0x00c0, 0x4d88, 0x2300, 0xa005, 0x0078, 0x4d8e,
+ 0x0048, 0x4d8d, 0xa302, 0x0078, 0x4d8e, 0x8002, 0x007c, 0x2d00,
+ 0x7026, 0xa080, 0x000d, 0x7056, 0x7053, 0x0000, 0x127e, 0x2091,
+ 0x8000, 0x2009, 0xa5d0, 0x2104, 0xc08d, 0x200a, 0x127f, 0x1078,
+ 0x13eb, 0x007c, 0x2071, 0xa3e1, 0x7003, 0x0000, 0x7007, 0x0000,
+ 0x700f, 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001,
+ 0x705f, 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000,
+ 0x708f, 0x0001, 0x70bf, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa3e1,
+ 0x6848, 0xa005, 0x00c0, 0x4dcb, 0x7028, 0xc085, 0x702a, 0xa085,
+ 0x0001, 0x0078, 0x4df0, 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858,
+ 0x703e, 0x707a, 0x685c, 0x7042, 0x707e, 0x6848, 0x702e, 0x6840,
+ 0x7032, 0x2009, 0x000c, 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c,
+ 0x003f, 0xa084, 0xffc0, 0xa210, 0x2100, 0xa319, 0x7272, 0x7376,
+ 0x7028, 0xc084, 0x702a, 0x7007, 0x0001, 0x700f, 0x0000, 0xa006,
+ 0x0e7f, 0x007c, 0x2b78, 0x2071, 0xa3e1, 0x7004, 0x1079, 0x4e50,
+ 0x700c, 0x0079, 0x4dfb, 0x4e00, 0x4df5, 0x4df5, 0x4df5, 0x4df5,
+ 0x007c, 0x700c, 0x0079, 0x4e04, 0x4e09, 0x4e4e, 0x4e4e, 0x4e4f,
+ 0x4e4f, 0x7830, 0x7930, 0xa106, 0x0040, 0x4e13, 0x7830, 0x7930,
+ 0xa106, 0x00c0, 0x4e39, 0x7030, 0xa10a, 0x0040, 0x4e39, 0x00c8,
+ 0x4e1b, 0x712c, 0xa10a, 0xa18a, 0x0002, 0x00c8, 0x4e3a, 0x1078,
+ 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001,
+ 0x0003, 0x7057, 0x0000, 0x127e, 0x007e, 0x2091, 0x8000, 0x2009,
+ 0xa5d0, 0x2104, 0xc085, 0x200a, 0x007f, 0x700e, 0x127f, 0x1078,
+ 0x13eb, 0x007c, 0x1078, 0x1366, 0x0040, 0x4e39, 0x2d00, 0x705a,
+ 0x1078, 0x1366, 0x00c0, 0x4e46, 0x0078, 0x4e25, 0x2d00, 0x7086,
+ 0x7063, 0x0080, 0x2001, 0x0004, 0x0078, 0x4e29, 0x007c, 0x007c,
+ 0x4e61, 0x4e62, 0x4e99, 0x4e9a, 0x4e4e, 0x4ed0, 0x4ed5, 0x4f0c,
+ 0x4f0d, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, 0x4fad,
+ 0x4fd7, 0x007c, 0x700c, 0x0079, 0x4e65, 0x4e6a, 0x4e6d, 0x4e7d,
+ 0x4e98, 0x4e98, 0x1078, 0x4e01, 0x007c, 0x127e, 0x8001, 0x700e,
+ 0x7058, 0x007e, 0x1078, 0x5348, 0x0040, 0x4e7a, 0x2091, 0x8000,
+ 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4e86, 0x127e, 0x8001, 0x700e,
+ 0x1078, 0x5348, 0x7058, 0x2068, 0x7084, 0x705a, 0x6803, 0x0000,
+ 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff, 0xa08a, 0x0020, 0x00c8,
+ 0x4e95, 0x1079, 0x4eb0, 0x127f, 0x007c, 0x127f, 0x1078, 0x4f2e,
+ 0x007c, 0x007c, 0x007c, 0x0e7e, 0x2071, 0xa3e1, 0x700c, 0x0079,
+ 0x4ea1, 0x4ea6, 0x4ea6, 0x4ea6, 0x4ea8, 0x4eac, 0x0e7f, 0x007c,
+ 0x700f, 0x0001, 0x0078, 0x4eae, 0x700f, 0x0002, 0x0e7f, 0x007c,
+ 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x5080, 0x4f2e, 0x4f2e, 0x4f2e,
+ 0x4f2e, 0x4f2e, 0x4f4a, 0x50ca, 0x5117, 0x5170, 0x5186, 0x4f2e,
+ 0x4f2e, 0x4f66, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f87, 0x5245, 0x5263,
+ 0x4f2e, 0x4f66, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f7c, 0x5263,
+ 0x7020, 0x2068, 0x1078, 0x139a, 0x007c, 0x700c, 0x0079, 0x4ed8,
+ 0x4edd, 0x4ee0, 0x4ef0, 0x4f0b, 0x4f0b, 0x1078, 0x4e01, 0x007c,
+ 0x127e, 0x8001, 0x700e, 0x7058, 0x007e, 0x1078, 0x5348, 0x0040,
+ 0x4eed, 0x2091, 0x8000, 0x1078, 0x4e01, 0x0d7f, 0x0078, 0x4ef9,
+ 0x127e, 0x8001, 0x700e, 0x1078, 0x5348, 0x7058, 0x2068, 0x7084,
+ 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+ 0xa08a, 0x001a, 0x00c8, 0x4f08, 0x1079, 0x4f0e, 0x127f, 0x007c,
+ 0x127f, 0x1078, 0x4f2e, 0x007c, 0x007c, 0x007c, 0x4f2e, 0x4f4a,
+ 0x506a, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+ 0x506a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f4a, 0x4f2e, 0x4f4a,
+ 0x506a, 0x4f2e, 0x4f2e, 0x4f4a, 0x4f2e, 0x4f2e, 0x4f2e, 0x4f4a,
+ 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x007c, 0x7007, 0x0001,
+ 0x6838, 0xa084, 0x00ff, 0xc0d5, 0x683a, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x4982, 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084,
+ 0x00ff, 0xc0e5, 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+ 0x127f, 0x007c, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed,
+ 0x683a, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c,
+ 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x4982, 0x127f, 0x007c, 0x6834, 0x8007,
+ 0xa084, 0x00ff, 0x0040, 0x4f3c, 0x8001, 0x00c0, 0x4f73, 0x7007,
+ 0x0001, 0x0078, 0x5049, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+ 0x701a, 0x704b, 0x5049, 0x007c, 0x684c, 0xa084, 0x00c0, 0xa086,
+ 0x00c0, 0x00c0, 0x4f87, 0x7007, 0x0001, 0x0078, 0x5280, 0x2d00,
+ 0x7016, 0x701a, 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1,
+ 0xa40c, 0x53a3, 0x6858, 0x7012, 0xa082, 0x0401, 0x00c8, 0x4f58,
+ 0x6884, 0xa08a, 0x0002, 0x00c8, 0x4f58, 0x82ff, 0x00c0, 0x4fa9,
+ 0x6888, 0x698c, 0xa105, 0x0040, 0x4fa9, 0x2001, 0x5019, 0x0078,
+ 0x4fac, 0xa280, 0x500f, 0x2004, 0x70c6, 0x7010, 0xa015, 0x0040,
+ 0x4ff7, 0x1078, 0x1366, 0x00c0, 0x4fb8, 0x7007, 0x000f, 0x007c,
+ 0x2d00, 0x7022, 0x70c4, 0x2060, 0x6000, 0x6836, 0x6004, 0xad00,
+ 0x7096, 0x6008, 0xa20a, 0x00c8, 0x4fc7, 0xa00e, 0x2200, 0x7112,
+ 0x620c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0040, 0x4fd0, 0xa108,
+ 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x1078, 0x13d1, 0x7090,
+ 0xa08e, 0x0100, 0x0040, 0x4feb, 0xa086, 0x0200, 0x0040, 0x4fe3,
+ 0x7007, 0x0010, 0x007c, 0x7020, 0x2068, 0x1078, 0x139a, 0x7014,
+ 0x2068, 0x0078, 0x4f58, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807,
+ 0x0000, 0x2d08, 0x2068, 0x6906, 0x711a, 0x0078, 0x4fad, 0x7014,
+ 0x2068, 0x7007, 0x0001, 0x6884, 0xa005, 0x00c0, 0x5006, 0x6888,
+ 0x698c, 0xa105, 0x0040, 0x5006, 0x1078, 0x501d, 0x6834, 0xa084,
+ 0x00ff, 0xa086, 0x001e, 0x0040, 0x5280, 0x0078, 0x5049, 0x5011,
+ 0x5015, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a, 0x000f, 0x0005,
+ 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x0f7e, 0x0e7e, 0x0c7e,
+ 0x077e, 0x067e, 0x6f88, 0x6e8c, 0x6804, 0x2060, 0xacf0, 0x0021,
+ 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816, 0x7008, 0x7812,
+ 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a, 0x8109, 0x0040,
+ 0x503f, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0078, 0x502c, 0x6004,
+ 0xa065, 0x00c0, 0x5026, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x0f7f,
+ 0x007c, 0x2009, 0xa32e, 0x210c, 0x81ff, 0x00c0, 0x5064, 0x6838,
+ 0xa084, 0x00ff, 0x683a, 0x1078, 0x4290, 0x00c0, 0x5058, 0x007c,
+ 0x1078, 0x4a60, 0x127e, 0x2091, 0x8000, 0x1078, 0x8cb8, 0x1078,
+ 0x4982, 0x127f, 0x0078, 0x5057, 0x2001, 0x0028, 0x2009, 0x0000,
+ 0x0078, 0x5058, 0x7018, 0x6802, 0x2d08, 0x2068, 0x6906, 0x711a,
+ 0x7010, 0x8001, 0x7012, 0x0040, 0x5079, 0x7007, 0x0006, 0x0078,
+ 0x507f, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048, 0x107a, 0x007c,
+ 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x6848, 0xa084,
+ 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x0040, 0x50a9, 0x2009,
+ 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0040, 0x50a9, 0xa005,
+ 0x00c0, 0x50bc, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x1078, 0x4501,
+ 0x00c0, 0x50bc, 0x067e, 0x6e50, 0x1078, 0x45e7, 0x067f, 0x0078,
+ 0x50bc, 0x047e, 0x2011, 0xa30c, 0x2224, 0xc484, 0xc48c, 0x2412,
+ 0x047f, 0x0c7e, 0x1078, 0x4501, 0x00c0, 0x50b8, 0x1078, 0x4782,
+ 0x8108, 0x00f0, 0x50b2, 0x0c7f, 0x684c, 0xd084, 0x00c0, 0x50c3,
+ 0x1078, 0x139a, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078, 0x4982,
+ 0x127f, 0x007c, 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2001,
+ 0xa352, 0x2004, 0xd0a4, 0x0040, 0x510e, 0x2061, 0xa62d, 0x6100,
+ 0xd184, 0x0040, 0x50ee, 0x6858, 0xa084, 0x00ff, 0x00c0, 0x5111,
+ 0x6000, 0xd084, 0x0040, 0x510e, 0x6004, 0xa005, 0x00c0, 0x5114,
+ 0x6003, 0x0000, 0x600b, 0x0000, 0x0078, 0x510b, 0x2011, 0x0001,
+ 0x6860, 0xa005, 0x00c0, 0x50f6, 0x2001, 0x001e, 0x8000, 0x6016,
+ 0x6858, 0xa084, 0x00ff, 0x0040, 0x510e, 0x6006, 0x6858, 0x8007,
+ 0xa084, 0x00ff, 0x0040, 0x510e, 0x600a, 0x6858, 0x8000, 0x00c0,
+ 0x510a, 0xc28d, 0x6202, 0x127f, 0x0078, 0x5337, 0x127f, 0x0078,
+ 0x532f, 0x127f, 0x0078, 0x5327, 0x127f, 0x0078, 0x532b, 0x127e,
+ 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xa352, 0x2004, 0xd0a4,
+ 0x0040, 0x516d, 0x2061, 0xa62d, 0x6000, 0xd084, 0x0040, 0x516d,
+ 0x6204, 0x6308, 0xd08c, 0x00c0, 0x515f, 0x6c48, 0xa484, 0x0003,
+ 0x0040, 0x5145, 0x6958, 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x513e,
+ 0x2100, 0xa210, 0x0048, 0x516a, 0x0078, 0x5145, 0x8001, 0x00c0,
+ 0x516a, 0x2100, 0xa212, 0x0048, 0x516a, 0xa484, 0x000c, 0x0040,
+ 0x515f, 0x6958, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
+ 0x5157, 0x2100, 0xa318, 0x0048, 0x516a, 0x0078, 0x515f, 0xa082,
+ 0x0004, 0x00c0, 0x516a, 0x2100, 0xa31a, 0x0048, 0x516a, 0x6860,
+ 0xa005, 0x0040, 0x5165, 0x8000, 0x6016, 0x6206, 0x630a, 0x127f,
+ 0x0078, 0x5337, 0x127f, 0x0078, 0x5333, 0x127f, 0x0078, 0x532f,
+ 0x127e, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xa62d, 0x6300,
+ 0xd38c, 0x00c0, 0x5180, 0x6308, 0x8318, 0x0048, 0x5183, 0x630a,
+ 0x127f, 0x0078, 0x5345, 0x127f, 0x0078, 0x5333, 0x127e, 0x0c7e,
+ 0x2091, 0x8000, 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0040, 0x519a,
+ 0x0c7e, 0x2061, 0xa62d, 0x6000, 0xa084, 0xfcff, 0x6002, 0x0c7f,
+ 0x0078, 0x51c9, 0x6858, 0xa005, 0x0040, 0x51e0, 0x685c, 0xa065,
+ 0x0040, 0x51dc, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x51ac,
+ 0x1078, 0x8c01, 0x0078, 0x51ba, 0x6013, 0x0400, 0x6037, 0x0000,
+ 0x694c, 0xd1a4, 0x0040, 0x51b6, 0x6950, 0x6136, 0x2009, 0x0041,
+ 0x1078, 0x756c, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x00c0,
+ 0x51c9, 0x027e, 0x2009, 0x0000, 0x2011, 0xfdff, 0x1078, 0x5a6d,
+ 0x027f, 0x684c, 0xd0c4, 0x0040, 0x51d8, 0x2061, 0xa62d, 0x6000,
+ 0xd08c, 0x00c0, 0x51d8, 0x6008, 0x8000, 0x0048, 0x51dc, 0x600a,
+ 0x0c7f, 0x127f, 0x0078, 0x5337, 0x0c7f, 0x127f, 0x0078, 0x532f,
+ 0x6954, 0xa186, 0x0045, 0x0040, 0x5213, 0xa186, 0x002a, 0x00c0,
+ 0x51f0, 0x2001, 0xa30c, 0x200c, 0xc194, 0x2102, 0x0078, 0x51c9,
+ 0xa186, 0x0020, 0x0040, 0x5209, 0xa186, 0x0029, 0x0040, 0x51fc,
+ 0xa186, 0x002d, 0x00c0, 0x51dc, 0x6944, 0xa18c, 0xff00, 0x810f,
+ 0x1078, 0x4501, 0x00c0, 0x51c9, 0x6000, 0xc0e4, 0x6002, 0x0078,
+ 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x2001, 0xa5a1, 0x2004,
+ 0x6016, 0x0078, 0x51c9, 0x685c, 0xa065, 0x0040, 0x51dc, 0x0e7e,
+ 0x6860, 0xa075, 0x2001, 0xa32e, 0x2004, 0xa005, 0x0040, 0x522b,
+ 0x1078, 0x8c01, 0x8eff, 0x0040, 0x5228, 0x2e60, 0x1078, 0x8c01,
+ 0x0e7f, 0x0078, 0x51c9, 0x6024, 0xc0dc, 0xc0d5, 0x6026, 0x2e60,
+ 0x6007, 0x003a, 0x6870, 0xa005, 0x0040, 0x523c, 0x6007, 0x003b,
+ 0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x1078, 0x5bf8,
+ 0x1078, 0x6109, 0x0e7f, 0x0078, 0x51c9, 0x2061, 0xa62d, 0x6000,
+ 0xd084, 0x0040, 0x525f, 0xd08c, 0x00c0, 0x5345, 0x2091, 0x8000,
+ 0x6204, 0x8210, 0x0048, 0x5259, 0x6206, 0x2091, 0x8001, 0x0078,
+ 0x5345, 0x2091, 0x8001, 0x6853, 0x0016, 0x0078, 0x533e, 0x6853,
+ 0x0007, 0x0078, 0x533e, 0x6834, 0x8007, 0xa084, 0x00ff, 0x00c0,
+ 0x526d, 0x1078, 0x4f3c, 0x0078, 0x527f, 0x2030, 0x8001, 0x00c0,
+ 0x5277, 0x7007, 0x0001, 0x1078, 0x5280, 0x0078, 0x527f, 0x7007,
+ 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5280, 0x007c,
+ 0x0e7e, 0x127e, 0x2091, 0x8000, 0x2009, 0xa32e, 0x210c, 0x81ff,
+ 0x00c0, 0x530b, 0x2009, 0xa30c, 0x210c, 0xd194, 0x00c0, 0x5315,
+ 0x6848, 0x2070, 0xae82, 0xaa00, 0x0048, 0x52fb, 0x2001, 0xa315,
+ 0x2004, 0xae02, 0x00c8, 0x52fb, 0x2061, 0xa62d, 0x6100, 0xa184,
+ 0x0301, 0xa086, 0x0001, 0x00c0, 0x52de, 0x711c, 0xa186, 0x0006,
+ 0x00c0, 0x52e6, 0x7018, 0xa005, 0x0040, 0x530b, 0x2004, 0xd0e4,
+ 0x00c0, 0x530f, 0x7024, 0xd0dc, 0x00c0, 0x5319, 0x6853, 0x0000,
+ 0x6803, 0x0000, 0x2d08, 0x7010, 0xa005, 0x00c0, 0x52ca, 0x7112,
+ 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x2e60, 0x1078, 0x59b6, 0x127f,
+ 0x0e7f, 0x007c, 0x2068, 0x6800, 0xa005, 0x00c0, 0x52ca, 0x6902,
+ 0x2168, 0x684c, 0xd0f4, 0x00c0, 0x531d, 0x127f, 0x0e7f, 0x007c,
+ 0x127f, 0x0e7f, 0x6853, 0x0006, 0x0078, 0x533e, 0xd184, 0x0040,
+ 0x52d8, 0xd1c4, 0x00c0, 0x52ff, 0x0078, 0x5303, 0x6944, 0xa18c,
+ 0xff00, 0x810f, 0x1078, 0x4501, 0x00c0, 0x530f, 0x6000, 0xd0e4,
+ 0x00c0, 0x530f, 0x711c, 0xa186, 0x0007, 0x00c0, 0x52fb, 0x6853,
+ 0x0002, 0x0078, 0x5311, 0x6853, 0x0008, 0x0078, 0x5311, 0x6853,
+ 0x000e, 0x0078, 0x5311, 0x6853, 0x0017, 0x0078, 0x5311, 0x6853,
+ 0x0035, 0x0078, 0x5311, 0x6853, 0x0028, 0x0078, 0x5311, 0x6853,
+ 0x0029, 0x127f, 0x0e7f, 0x0078, 0x533e, 0x6853, 0x002a, 0x0078,
+ 0x5311, 0x6853, 0x0045, 0x0078, 0x5311, 0x2e60, 0x2019, 0x0002,
+ 0x6017, 0x0014, 0x1078, 0x9a6a, 0x127f, 0x0e7f, 0x007c, 0x2009,
+ 0x003e, 0x0078, 0x5339, 0x2009, 0x0004, 0x0078, 0x5339, 0x2009,
+ 0x0006, 0x0078, 0x5339, 0x2009, 0x0016, 0x0078, 0x5339, 0x2009,
+ 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x2091, 0x8000,
+ 0x1078, 0x4982, 0x2091, 0x8001, 0x007c, 0x1078, 0x139a, 0x007c,
+ 0x702c, 0x7130, 0x8108, 0xa102, 0x0048, 0x5355, 0xa00e, 0x7034,
+ 0x7072, 0x7038, 0x7076, 0x0078, 0x5361, 0x7070, 0xa080, 0x0040,
+ 0x7072, 0x00c8, 0x5361, 0x7074, 0xa081, 0x0000, 0x7076, 0xa085,
+ 0x0001, 0x7932, 0x7132, 0x007c, 0x0d7e, 0x1078, 0x59ad, 0x0d7f,
+ 0x007c, 0x0d7e, 0x2011, 0x0004, 0x2204, 0xa085, 0x8002, 0x2012,
+ 0x0d7f, 0x007c, 0x20e1, 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00,
+ 0xa084, 0x7000, 0x0040, 0x5380, 0xa086, 0x1000, 0x00c0, 0x53ac,
+ 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00, 0x8217, 0xa084, 0xf000,
+ 0xa086, 0x3000, 0x00c0, 0x5390, 0x1078, 0x5570, 0x0078, 0x53a7,
+ 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x00c0, 0x5397, 0x3e60, 0xac84,
+ 0x000f, 0x00c0, 0x53ac, 0xac82, 0xaa00, 0x0048, 0x53ac, 0x6854,
+ 0xac02, 0x00c8, 0x53ac, 0x2009, 0x0047, 0x1078, 0x756c, 0x7a1c,
+ 0xd284, 0x00c0, 0x5372, 0x007c, 0xa016, 0x1078, 0x15ec, 0x0078,
+ 0x53a7, 0x0078, 0x53ac, 0x781c, 0xd08c, 0x0040, 0x53db, 0x157e,
+ 0x137e, 0x147e, 0x20e1, 0x3000, 0x3d20, 0x3e28, 0xa584, 0x0076,
+ 0x00c0, 0x53f1, 0xa484, 0x7000, 0xa086, 0x1000, 0x00c0, 0x53e0,
+ 0x1078, 0x540c, 0x0040, 0x53f1, 0x20e1, 0x3000, 0x7828, 0x7828,
+ 0x1078, 0x542a, 0x147f, 0x137f, 0x157f, 0x2009, 0xa5b3, 0x2104,
+ 0xa005, 0x00c0, 0x53dc, 0x007c, 0x1078, 0x6109, 0x0078, 0x53db,
+ 0xa484, 0x7000, 0x00c0, 0x53f1, 0x1078, 0x540c, 0x0040, 0x5403,
+ 0x7000, 0xa084, 0xff00, 0xa086, 0x8100, 0x0040, 0x53cc, 0x0078,
+ 0x5403, 0x1078, 0xa1ee, 0xd5a4, 0x0040, 0x53ff, 0x1078, 0x1af7,
+ 0x20e1, 0x9010, 0x2001, 0x0138, 0x2202, 0x0078, 0x5407, 0x1078,
+ 0x540c, 0x687f, 0x0000, 0x20e1, 0x3000, 0x7828, 0x7828, 0x147f,
+ 0x137f, 0x157f, 0x0078, 0x53db, 0xa484, 0x01ff, 0x687e, 0xa005,
+ 0x0040, 0x541e, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac, 0x20e1,
+ 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x007c, 0x20a9, 0x000c,
+ 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085, 0x0001,
+ 0x0078, 0x541d, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+ 0xa196, 0x0000, 0x00c0, 0x5437, 0x0078, 0x567c, 0x007c, 0xa196,
+ 0x2000, 0x00c0, 0x5448, 0x6900, 0xa18e, 0x0001, 0x00c0, 0x5444,
+ 0x1078, 0x3a43, 0x0078, 0x5436, 0x1078, 0x5450, 0x0078, 0x5436,
+ 0xa196, 0x8000, 0x00c0, 0x5436, 0x1078, 0x570c, 0x0078, 0x5436,
+ 0x0c7e, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa196, 0x0001, 0x0040,
+ 0x545d, 0xa196, 0x0023, 0x00c0, 0x5568, 0xa08e, 0x0023, 0x00c0,
+ 0x5492, 0x1078, 0x57b2, 0x0040, 0x5568, 0x7124, 0x610a, 0x7030,
+ 0xa08e, 0x0200, 0x00c0, 0x5476, 0x7034, 0xa005, 0x00c0, 0x5568,
+ 0x2009, 0x0015, 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0214,
+ 0x0040, 0x547e, 0xa08e, 0x0210, 0x00c0, 0x5484, 0x2009, 0x0015,
+ 0x1078, 0x756c, 0x0078, 0x5568, 0xa08e, 0x0100, 0x00c0, 0x5568,
+ 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009, 0x0016, 0x1078, 0x756c,
+ 0x0078, 0x5568, 0xa08e, 0x0022, 0x00c0, 0x5568, 0x7030, 0xa08e,
+ 0x0300, 0x00c0, 0x54a3, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+ 0x0017, 0x0078, 0x5534, 0xa08e, 0x0500, 0x00c0, 0x54af, 0x7034,
+ 0xa005, 0x00c0, 0x5568, 0x2009, 0x0018, 0x0078, 0x5534, 0xa08e,
+ 0x2010, 0x00c0, 0x54b7, 0x2009, 0x0019, 0x0078, 0x5534, 0xa08e,
+ 0x2110, 0x00c0, 0x54bf, 0x2009, 0x001a, 0x0078, 0x5534, 0xa08e,
+ 0x5200, 0x00c0, 0x54cb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+ 0x001b, 0x0078, 0x5534, 0xa08e, 0x5000, 0x00c0, 0x54d7, 0x7034,
+ 0xa005, 0x00c0, 0x5568, 0x2009, 0x001c, 0x0078, 0x5534, 0xa08e,
+ 0x1300, 0x00c0, 0x54df, 0x2009, 0x0034, 0x0078, 0x5534, 0xa08e,
+ 0x1200, 0x00c0, 0x54eb, 0x7034, 0xa005, 0x00c0, 0x5568, 0x2009,
+ 0x0024, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e, 0x2400, 0x00c0,
+ 0x54f5, 0x2009, 0x002d, 0x0078, 0x5534, 0xa08c, 0xff00, 0xa18e,
+ 0x5300, 0x00c0, 0x54ff, 0x2009, 0x002a, 0x0078, 0x5534, 0xa08e,
+ 0x0f00, 0x00c0, 0x5507, 0x2009, 0x0020, 0x0078, 0x5534, 0xa08e,
+ 0x5300, 0x00c0, 0x550d, 0x0078, 0x552a, 0xa08e, 0x6104, 0x00c0,
+ 0x552a, 0x2011, 0xa88d, 0x8208, 0x2204, 0xa082, 0x0004, 0x20a8,
+ 0x95ac, 0x95ac, 0x2011, 0x8015, 0x211c, 0x8108, 0x047e, 0x2124,
+ 0x1078, 0x3579, 0x047f, 0x8108, 0x00f0, 0x551a, 0x2009, 0x0023,
+ 0x0078, 0x5534, 0xa08e, 0x6000, 0x00c0, 0x5532, 0x2009, 0x003f,
+ 0x0078, 0x5534, 0x2009, 0x001d, 0x017e, 0x2011, 0xa883, 0x2204,
+ 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x556a, 0x1078, 0x4499,
+ 0x00c0, 0x556a, 0x6612, 0x6516, 0x86ff, 0x0040, 0x555a, 0x017f,
+ 0x017e, 0xa186, 0x0017, 0x00c0, 0x555a, 0x6868, 0xa606, 0x00c0,
+ 0x555a, 0x686c, 0xa506, 0xa084, 0xff00, 0x00c0, 0x555a, 0x6000,
+ 0xc0f5, 0x6002, 0x0c7e, 0x1078, 0x74d7, 0x0040, 0x556d, 0x017f,
+ 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x017f, 0x1078, 0x756c,
+ 0x0c7f, 0x007c, 0x017f, 0x0078, 0x5568, 0x0c7f, 0x0078, 0x556a,
+ 0x0c7e, 0x1078, 0x55d4, 0x00c0, 0x55d2, 0xa184, 0xff00, 0x8007,
+ 0xa086, 0x0008, 0x00c0, 0x55d2, 0xa28e, 0x0033, 0x00c0, 0x55a3,
+ 0x1078, 0x57b2, 0x0040, 0x55d2, 0x7124, 0x610a, 0x7030, 0xa08e,
+ 0x0200, 0x00c0, 0x5595, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009,
+ 0x0015, 0x1078, 0x756c, 0x0078, 0x55d2, 0xa08e, 0x0100, 0x00c0,
+ 0x55d2, 0x7034, 0xa005, 0x00c0, 0x55d2, 0x2009, 0x0016, 0x1078,
+ 0x756c, 0x0078, 0x55d2, 0xa28e, 0x0032, 0x00c0, 0x55d2, 0x7030,
+ 0xa08e, 0x1400, 0x00c0, 0x55d2, 0x2009, 0x0038, 0x017e, 0x2011,
+ 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x55d1,
+ 0x1078, 0x4499, 0x00c0, 0x55d1, 0x6612, 0x6516, 0x0c7e, 0x1078,
+ 0x74d7, 0x0040, 0x55d0, 0x017f, 0x611a, 0x601f, 0x0004, 0x7120,
+ 0x610a, 0x017f, 0x1078, 0x756c, 0x1078, 0x6109, 0x0078, 0x55d2,
+ 0x0c7f, 0x017f, 0x0c7f, 0x007c, 0x0f7e, 0x0d7e, 0x027e, 0x017e,
+ 0x137e, 0x147e, 0x157e, 0x3c00, 0x007e, 0x2079, 0x0030, 0x2069,
+ 0x0200, 0x1078, 0x1c25, 0x00c0, 0x5615, 0x1078, 0x1b15, 0x0040,
+ 0x561f, 0x7908, 0xa18c, 0x1fff, 0xa182, 0x0011, 0x00c8, 0x561f,
+ 0x20a9, 0x000c, 0x20e1, 0x0000, 0x2ea0, 0x2099, 0x020a, 0x53a5,
+ 0x20e1, 0x2000, 0x2001, 0x020a, 0x2004, 0x7a0c, 0x7808, 0xa080,
+ 0x0007, 0xa084, 0x1ff8, 0xa08a, 0x0140, 0x10c8, 0x1328, 0x80ac,
+ 0x20e1, 0x6000, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828,
+ 0x6828, 0x7803, 0x0004, 0xa294, 0x0070, 0x007f, 0x20e0, 0x157f,
+ 0x147f, 0x137f, 0x017f, 0x027f, 0x0d7f, 0x0f7f, 0x007c, 0xa085,
+ 0x0001, 0x0078, 0x5615, 0x047e, 0x0e7e, 0x0d7e, 0x2028, 0x2130,
+ 0xa696, 0x00ff, 0x00c0, 0x5644, 0xa596, 0xfffd, 0x00c0, 0x5634,
+ 0x2009, 0x007f, 0x0078, 0x5677, 0xa596, 0xfffe, 0x00c0, 0x563c,
+ 0x2009, 0x007e, 0x0078, 0x5677, 0xa596, 0xfffc, 0x00c0, 0x5644,
+ 0x2009, 0x0080, 0x0078, 0x5677, 0x2011, 0x0000, 0x2021, 0x0081,
+ 0x20a9, 0x007e, 0x2071, 0xa4b5, 0x2e1c, 0x83ff, 0x00c0, 0x5656,
+ 0x82ff, 0x00c0, 0x566b, 0x2410, 0x0078, 0x566b, 0x2368, 0x6f10,
+ 0x007e, 0x2100, 0xa706, 0x007f, 0x6b14, 0x00c0, 0x5665, 0xa346,
+ 0x00c0, 0x5665, 0x2408, 0x0078, 0x5677, 0x87ff, 0x00c0, 0x566b,
+ 0x83ff, 0x0040, 0x5650, 0x8420, 0x8e70, 0x00f0, 0x564c, 0x82ff,
+ 0x00c0, 0x5676, 0xa085, 0x0001, 0x0078, 0x5678, 0x2208, 0xa006,
+ 0x0d7f, 0x0e7f, 0x047f, 0x007c, 0xa084, 0x0007, 0x0079, 0x5681,
+ 0x007c, 0x5689, 0x5689, 0x5689, 0x57c8, 0x5689, 0x568a, 0x56a3,
+ 0x56f3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x56a2, 0x7120, 0x2160,
+ 0xac8c, 0x000f, 0x00c0, 0x56a2, 0xac8a, 0xaa00, 0x0048, 0x56a2,
+ 0x6854, 0xac02, 0x00c8, 0x56a2, 0x7124, 0x610a, 0x2009, 0x0046,
+ 0x1078, 0x756c, 0x007c, 0x0c7e, 0x7110, 0xd1bc, 0x00c0, 0x56f1,
+ 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0,
+ 0x56f1, 0x1078, 0x4499, 0x00c0, 0x56f1, 0x6612, 0x6516, 0x6000,
+ 0xd0ec, 0x00c0, 0x56f1, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286,
+ 0x0006, 0x00c0, 0x56d6, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+ 0x56f1, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6122,
+ 0x2009, 0x0044, 0x1078, 0x756c, 0x0078, 0x56f1, 0x0c7e, 0x1078,
+ 0x74d7, 0x017f, 0x0040, 0x56f1, 0x611a, 0x601f, 0x0004, 0x7120,
+ 0x610a, 0xa286, 0x0004, 0x00c0, 0x56e9, 0x6007, 0x0005, 0x0078,
+ 0x56eb, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078,
+ 0x6109, 0x0c7f, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x570b, 0x7020,
+ 0x2060, 0xac84, 0x000f, 0x00c0, 0x570b, 0xac82, 0xaa00, 0x0048,
+ 0x570b, 0x6854, 0xac02, 0x00c8, 0x570b, 0x7124, 0x610a, 0x2009,
+ 0x0045, 0x1078, 0x756c, 0x007c, 0x7110, 0xa18c, 0xff00, 0x810f,
+ 0xa18e, 0x0000, 0x00c0, 0x571c, 0xa084, 0x000f, 0xa08a, 0x0006,
+ 0x00c8, 0x571c, 0x1079, 0x571d, 0x007c, 0x5723, 0x5724, 0x5723,
+ 0x5723, 0x5794, 0x57a3, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x572c,
+ 0x702c, 0xd084, 0x0040, 0x5793, 0x700c, 0x7108, 0x1078, 0x24e3,
+ 0x00c0, 0x5793, 0x1078, 0x4499, 0x00c0, 0x5793, 0x6612, 0x6516,
+ 0x6204, 0x7110, 0xd1bc, 0x0040, 0x575e, 0xa28c, 0x00ff, 0xa186,
+ 0x0004, 0x0040, 0x5747, 0xa186, 0x0006, 0x00c0, 0x5784, 0x0c7e,
+ 0x1078, 0x57b2, 0x0c7f, 0x0040, 0x5793, 0x0c7e, 0x1078, 0x74d7,
+ 0x017f, 0x0040, 0x5793, 0x611a, 0x601f, 0x0002, 0x7120, 0x610a,
+ 0x2009, 0x0088, 0x1078, 0x756c, 0x0078, 0x5793, 0xa28c, 0x00ff,
+ 0xa186, 0x0006, 0x0040, 0x5773, 0xa186, 0x0004, 0x0040, 0x5773,
+ 0xa294, 0xff00, 0x8217, 0xa286, 0x0004, 0x0040, 0x5773, 0xa286,
+ 0x0006, 0x00c0, 0x5784, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040,
+ 0x5793, 0x611a, 0x601f, 0x0005, 0x7120, 0x610a, 0x2009, 0x0088,
+ 0x1078, 0x756c, 0x0078, 0x5793, 0x0c7e, 0x1078, 0x74d7, 0x017f,
+ 0x0040, 0x5793, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x2009,
+ 0x0001, 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57a2,
+ 0x1078, 0x57b2, 0x0040, 0x57a2, 0x7124, 0x610a, 0x2009, 0x0089,
+ 0x1078, 0x756c, 0x007c, 0x7110, 0xd1bc, 0x0040, 0x57b1, 0x1078,
+ 0x57b2, 0x0040, 0x57b1, 0x7124, 0x610a, 0x2009, 0x008a, 0x1078,
+ 0x756c, 0x007c, 0x7020, 0x2060, 0xac84, 0x000f, 0x00c0, 0x57c5,
+ 0xac82, 0xaa00, 0x0048, 0x57c5, 0x2001, 0xa315, 0x2004, 0xac02,
+ 0x00c8, 0x57c5, 0xa085, 0x0001, 0x007c, 0xa006, 0x0078, 0x57c4,
+ 0x7110, 0xd1bc, 0x00c0, 0x57de, 0x7024, 0x2060, 0xac84, 0x000f,
+ 0x00c0, 0x57de, 0xac82, 0xaa00, 0x0048, 0x57de, 0x6854, 0xac02,
+ 0x00c8, 0x57de, 0x2009, 0x0051, 0x1078, 0x756c, 0x007c, 0x2071,
+ 0xa5be, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+ 0x7017, 0xaa00, 0x7007, 0x0000, 0x7026, 0x702b, 0x6c4e, 0x7032,
+ 0x7037, 0x6ca0, 0x703b, 0x0002, 0x703f, 0x0000, 0x7043, 0xffff,
+ 0x7047, 0xffff, 0x007c, 0x2071, 0xa5be, 0x00e0, 0x58c1, 0x2091,
+ 0x6000, 0x700c, 0x8001, 0x700e, 0x00c0, 0x5873, 0x700f, 0x0361,
+ 0x7007, 0x0001, 0x127e, 0x2091, 0x8000, 0x7138, 0x8109, 0x713a,
+ 0x00c0, 0x5871, 0x703b, 0x0002, 0x2009, 0x0100, 0x2104, 0xa082,
+ 0x0003, 0x00c8, 0x5871, 0x703c, 0xa086, 0x0001, 0x00c0, 0x584e,
+ 0x0d7e, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000, 0x0040, 0x582c,
+ 0x6803, 0x1000, 0x0078, 0x5833, 0x6804, 0xa084, 0x1000, 0x0040,
+ 0x5833, 0x6803, 0x0100, 0x6803, 0x0000, 0x703f, 0x0000, 0x2069,
+ 0xa5ab, 0x6804, 0xa082, 0x0006, 0x00c0, 0x5840, 0x6807, 0x0000,
+ 0x6830, 0xa082, 0x0003, 0x00c0, 0x5847, 0x6833, 0x0000, 0x1078,
+ 0x6109, 0x1078, 0x61d3, 0x0d7f, 0x0078, 0x5871, 0x0d7e, 0x2069,
+ 0xa300, 0x6944, 0x6860, 0xa102, 0x00c8, 0x5870, 0x2069, 0xa5ab,
+ 0x6804, 0xa086, 0x0000, 0x00c0, 0x5870, 0x6830, 0xa086, 0x0000,
+ 0x00c0, 0x5870, 0x703f, 0x0001, 0x6807, 0x0006, 0x6833, 0x0003,
+ 0x2069, 0x0100, 0x6830, 0x689e, 0x2069, 0x0140, 0x6803, 0x0600,
+ 0x0d7f, 0x0078, 0x5876, 0x127e, 0x2091, 0x8000, 0x7024, 0xa00d,
+ 0x0040, 0x588e, 0x7020, 0x8001, 0x7022, 0x00c0, 0x588e, 0x7023,
+ 0x0009, 0x8109, 0x7126, 0xa186, 0x03e8, 0x00c0, 0x5889, 0x7028,
+ 0x107a, 0x81ff, 0x00c0, 0x588e, 0x7028, 0x107a, 0x7030, 0xa00d,
+ 0x0040, 0x589f, 0x702c, 0x8001, 0x702e, 0x00c0, 0x589f, 0x702f,
+ 0x0009, 0x8109, 0x7132, 0x00c0, 0x589f, 0x7034, 0x107a, 0x7040,
+ 0xa005, 0x0040, 0x58a7, 0x0050, 0x58a7, 0x8001, 0x7042, 0x7044,
+ 0xa005, 0x0040, 0x58af, 0x0050, 0x58af, 0x8001, 0x7046, 0x7018,
+ 0xa00d, 0x0040, 0x58c0, 0x7008, 0x8001, 0x700a, 0x00c0, 0x58c0,
+ 0x700b, 0x0009, 0x8109, 0x711a, 0x00c0, 0x58c0, 0x701c, 0x107a,
+ 0x127f, 0x7004, 0x0079, 0x58c4, 0x58eb, 0x58ec, 0x5908, 0x0e7e,
+ 0x2071, 0xa5be, 0x7018, 0xa005, 0x00c0, 0x58d2, 0x711a, 0x721e,
+ 0x700b, 0x0009, 0x0e7f, 0x007c, 0x0e7e, 0x007e, 0x2071, 0xa5be,
+ 0x701c, 0xa206, 0x00c0, 0x58de, 0x701a, 0x701e, 0x007f, 0x0e7f,
+ 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x6088, 0xa102, 0x0048, 0x58e9,
+ 0x618a, 0x0e7f, 0x007c, 0x007c, 0x7110, 0x1078, 0x4501, 0x00c0,
+ 0x58fe, 0x6088, 0x8001, 0x0048, 0x58fe, 0x608a, 0x00c0, 0x58fe,
+ 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x8108, 0xa182,
+ 0x00ff, 0x0048, 0x5906, 0xa00e, 0x7007, 0x0002, 0x7112, 0x007c,
+ 0x7014, 0x2060, 0x127e, 0x2091, 0x8000, 0x603c, 0xa005, 0x0040,
+ 0x5917, 0x8001, 0x603e, 0x00c0, 0x5917, 0x1078, 0x8cd7, 0x6014,
+ 0xa005, 0x0040, 0x5941, 0x8001, 0x6016, 0x00c0, 0x5941, 0x611c,
+ 0xa186, 0x0003, 0x0040, 0x5928, 0xa186, 0x0006, 0x00c0, 0x593f,
+ 0x6010, 0x2068, 0x6854, 0xa08a, 0x199a, 0x0048, 0x593f, 0xa082,
+ 0x1999, 0x6856, 0xa08a, 0x199a, 0x0048, 0x5938, 0x2001, 0x1999,
+ 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x0078, 0x5941, 0x1078,
+ 0x8810, 0x127f, 0xac88, 0x0010, 0x7116, 0x2001, 0xca00, 0xa102,
+ 0x0048, 0x594e, 0x7017, 0xaa00, 0x7007, 0x0000, 0x007c, 0x0e7e,
+ 0x2071, 0xa5be, 0x7027, 0x07d0, 0x7023, 0x0009, 0x703b, 0x0002,
+ 0x0e7f, 0x007c, 0x2001, 0xa5c7, 0x2003, 0x0000, 0x007c, 0x0e7e,
+ 0x2071, 0xa5be, 0x7132, 0x702f, 0x0009, 0x0e7f, 0x007c, 0x2011,
+ 0xa5ca, 0x2013, 0x0000, 0x007c, 0x0e7e, 0x2071, 0xa5be, 0x711a,
+ 0x721e, 0x700b, 0x0009, 0x0e7f, 0x007c, 0x027e, 0x0e7e, 0x0f7e,
+ 0x2079, 0xa300, 0x7a34, 0xd294, 0x0040, 0x59a4, 0x2071, 0xa5aa,
+ 0x2e14, 0xa0fe, 0x0000, 0x0040, 0x5991, 0xa0fe, 0x0001, 0x0040,
+ 0x5995, 0xa0fe, 0x0002, 0x00c0, 0x59a0, 0xa292, 0x0085, 0x0078,
+ 0x5997, 0xa292, 0x0005, 0x0078, 0x5997, 0xa292, 0x0002, 0x2272,
+ 0x0040, 0x599c, 0x00c8, 0x59a4, 0x2011, 0x8037, 0x1078, 0x3579,
+ 0x2011, 0xa5a9, 0x2204, 0x2072, 0x0f7f, 0x0e7f, 0x027f, 0x007c,
+ 0x0c7e, 0x2061, 0xa62d, 0x0c7f, 0x007c, 0xa184, 0x000f, 0x8003,
+ 0x8003, 0x8003, 0xa080, 0xa62d, 0x2060, 0x007c, 0x6854, 0xa08a,
+ 0x199a, 0x0048, 0x59bd, 0x2001, 0x1999, 0xa005, 0x00c0, 0x59cc,
+ 0x0c7e, 0x2061, 0xa62d, 0x6014, 0x0c7f, 0xa005, 0x00c0, 0x59d1,
+ 0x2001, 0x001e, 0x0078, 0x59d1, 0xa08e, 0xffff, 0x00c0, 0x59d1,
+ 0xa006, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c,
+ 0x00c0, 0xa18e, 0x00c0, 0x0040, 0x5a24, 0xd0b4, 0x00c0, 0x59e8,
+ 0xd0bc, 0x00c0, 0x5a14, 0x2009, 0x0006, 0x1078, 0x5a43, 0x007c,
+ 0xd0fc, 0x0040, 0x59f3, 0xa084, 0x0003, 0x0040, 0x59f3, 0xa086,
+ 0x0003, 0x00c0, 0x5a3c, 0x6024, 0xd0d4, 0x0040, 0x59fd, 0xc0d4,
+ 0x6026, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xa373, 0x2104,
+ 0xd084, 0x0040, 0x5a0f, 0x6118, 0xa188, 0x0027, 0x2104, 0xd08c,
+ 0x00c0, 0x5a0f, 0x2009, 0x0042, 0x1078, 0x756c, 0x007c, 0x2009,
+ 0x0043, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a1f, 0xa084,
+ 0x0003, 0x0040, 0x5a1f, 0xa086, 0x0003, 0x00c0, 0x5a3c, 0x2009,
+ 0x0042, 0x1078, 0x756c, 0x007c, 0xd0fc, 0x0040, 0x5a32, 0xa084,
+ 0x0003, 0xa08e, 0x0002, 0x0040, 0x5a36, 0x2009, 0x0041, 0x1078,
+ 0x756c, 0x007c, 0x1078, 0x5a41, 0x0078, 0x5a31, 0x2009, 0x0043,
+ 0x1078, 0x756c, 0x0078, 0x5a31, 0x2009, 0x0004, 0x1078, 0x5a43,
+ 0x007c, 0x2009, 0x0001, 0x0d7e, 0x6010, 0xa0ec, 0xf000, 0x0040,
+ 0x5a6b, 0x2068, 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x00c0,
+ 0x5a65, 0x694c, 0xa18c, 0x8100, 0xa18e, 0x8100, 0x00c0, 0x5a65,
+ 0x0c7e, 0x2061, 0xa62d, 0x6200, 0xd28c, 0x00c0, 0x5a64, 0x6204,
+ 0x8210, 0x0048, 0x5a64, 0x6206, 0x0c7f, 0x1078, 0x4982, 0x6010,
+ 0xa06d, 0x10c0, 0x59b6, 0x0d7f, 0x007c, 0x157e, 0x0c7e, 0x2061,
+ 0xa62d, 0x6000, 0x81ff, 0x0040, 0x5a78, 0xa205, 0x0078, 0x5a79,
+ 0xa204, 0x6002, 0x0c7f, 0x157f, 0x007c, 0x6800, 0xd08c, 0x00c0,
+ 0x5a89, 0x6808, 0xa005, 0x0040, 0x5a89, 0x8001, 0x680a, 0xa085,
+ 0x0001, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
+ 0x00c8, 0x5a93, 0xa200, 0x00f0, 0x5a8e, 0x8086, 0x818e, 0x007c,
+ 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x5ab9, 0xa11a, 0x00c8,
+ 0x5ab9, 0x8213, 0x818d, 0x0048, 0x5aac, 0xa11a, 0x00c8, 0x5aad,
+ 0x00f0, 0x5aa1, 0x0078, 0x5ab1, 0xa11a, 0x2308, 0x8210, 0x00f0,
+ 0x5aa1, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
+ 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x5ab5, 0x127e,
+ 0x2091, 0x2200, 0x2079, 0xa5ab, 0x127f, 0x0d7e, 0x2069, 0xa5ab,
+ 0x6803, 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a,
+ 0x0d7f, 0x007c, 0x0c7e, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007,
+ 0x0079, 0x5ada, 0x5ae4, 0x5b09, 0x5b64, 0x5aea, 0x5b09, 0x5ae4,
+ 0x5ae2, 0x5ae2, 0x1078, 0x1328, 0x1078, 0x595a, 0x1078, 0x6109,
+ 0x0c7f, 0x007c, 0x62c0, 0x82ff, 0x00c0, 0x5af0, 0x0c7f, 0x007c,
+ 0x2011, 0x4129, 0x1078, 0x58d4, 0x7828, 0xa092, 0x00c8, 0x00c8,
+ 0x5aff, 0x8000, 0x782a, 0x1078, 0x4168, 0x0078, 0x5aee, 0x1078,
+ 0x4129, 0x7807, 0x0003, 0x7827, 0x0000, 0x782b, 0x0000, 0x0078,
+ 0x5aee, 0x1078, 0x595a, 0x3c00, 0x007e, 0x2011, 0x0209, 0x20e1,
+ 0x4000, 0x2214, 0x007f, 0x20e0, 0x82ff, 0x0040, 0x5b27, 0x62c0,
+ 0x82ff, 0x00c0, 0x5b27, 0x782b, 0x0000, 0x7824, 0xa065, 0x1040,
+ 0x1328, 0x2009, 0x0013, 0x1078, 0x756c, 0x0c7f, 0x007c, 0x3900,
+ 0xa082, 0xa6cd, 0x00c8, 0x5b2e, 0x1078, 0x728a, 0x0c7e, 0x7824,
+ 0xa065, 0x1040, 0x1328, 0x7804, 0xa086, 0x0004, 0x0040, 0x5ba9,
+ 0x7828, 0xa092, 0x2710, 0x00c8, 0x5b44, 0x8000, 0x782a, 0x0c7f,
+ 0x1078, 0x6c33, 0x0078, 0x5b25, 0x6104, 0xa186, 0x0003, 0x00c0,
+ 0x5b5b, 0x0e7e, 0x2071, 0xa300, 0x70d4, 0x0e7f, 0xd08c, 0x0040,
+ 0x5b5b, 0x0c7e, 0x0e7e, 0x2061, 0x0100, 0x2071, 0xa300, 0x1078,
+ 0x4171, 0x0e7f, 0x0c7f, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+ 0x756c, 0x0c7f, 0x0078, 0x5b25, 0x2001, 0xa5c7, 0x2003, 0x0000,
+ 0x62c0, 0x82ff, 0x00c0, 0x5b78, 0x782b, 0x0000, 0x7824, 0xa065,
+ 0x1040, 0x1328, 0x2009, 0x0013, 0x1078, 0x75c3, 0x0c7f, 0x007c,
+ 0x0c7e, 0x0d7e, 0x3900, 0xa082, 0xa6cd, 0x00c8, 0x5b81, 0x1078,
+ 0x728a, 0x7824, 0xa005, 0x1040, 0x1328, 0x781c, 0xa06d, 0x1040,
+ 0x1328, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x1078, 0x753d,
+ 0x693c, 0x81ff, 0x1040, 0x1328, 0x8109, 0x693e, 0x6854, 0xa015,
+ 0x0040, 0x5b9d, 0x7a1e, 0x0078, 0x5b9f, 0x7918, 0x791e, 0x7807,
+ 0x0000, 0x7827, 0x0000, 0x0d7f, 0x0c7f, 0x1078, 0x6109, 0x0078,
+ 0x5b76, 0x6104, 0xa186, 0x0002, 0x0040, 0x5bb4, 0xa186, 0x0004,
+ 0x0040, 0x5bb4, 0x0078, 0x5b38, 0x7808, 0xac06, 0x0040, 0x5b38,
+ 0x1078, 0x6010, 0x1078, 0x5c45, 0x0c7f, 0x1078, 0x6109, 0x0078,
+ 0x5b25, 0x0c7e, 0x6027, 0x0002, 0x62c8, 0x82ff, 0x00c0, 0x5bdb,
+ 0x62c4, 0x82ff, 0x00c0, 0x5bdb, 0x793c, 0xa1e5, 0x0000, 0x0040,
+ 0x5bd5, 0x2009, 0x0049, 0x1078, 0x756c, 0x2011, 0xa5ca, 0x2013,
+ 0x0000, 0x0c7f, 0x007c, 0x3908, 0xa192, 0xa6cd, 0x00c8, 0x5be2,
+ 0x1078, 0x728a, 0x6017, 0x0010, 0x793c, 0x81ff, 0x0040, 0x5bd5,
+ 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e, 0x0006, 0x00c0, 0x5bf4,
+ 0x6017, 0x0012, 0x0078, 0x5bd9, 0x6017, 0x0016, 0x0078, 0x5bd9,
+ 0x007e, 0x017e, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x600f, 0x0000,
+ 0x2c08, 0x2061, 0xa5ab, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+ 0x0040, 0x5c13, 0xa080, 0x0003, 0x2102, 0x6112, 0x127f, 0x0c7f,
+ 0x017f, 0x007f, 0x007c, 0x6116, 0x6112, 0x0078, 0x5c0e, 0x0d7e,
+ 0x2069, 0xa5ab, 0x6000, 0xd0d4, 0x0040, 0x5c2c, 0x6820, 0x8000,
+ 0x6822, 0xa086, 0x0001, 0x00c0, 0x5c27, 0x2c00, 0x681e, 0x6804,
+ 0xa084, 0x0007, 0x0079, 0x6111, 0xc0d5, 0x6002, 0x6818, 0xa005,
+ 0x0040, 0x5c3e, 0x6056, 0x605b, 0x0000, 0x007e, 0x2c00, 0x681a,
+ 0x0d7f, 0x685a, 0x2069, 0xa5ab, 0x0078, 0x5c1e, 0x6056, 0x605a,
+ 0x2c00, 0x681a, 0x681e, 0x0078, 0x5c1e, 0x007e, 0x017e, 0x0c7e,
+ 0x127e, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061, 0xa5ab,
+ 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0040, 0x5c60, 0xa080,
+ 0x0003, 0x2102, 0x610a, 0x127f, 0x0c7f, 0x017f, 0x007f, 0x007c,
+ 0x610e, 0x610a, 0x0078, 0x5c5b, 0x0c7e, 0x600f, 0x0000, 0x2c08,
+ 0x2061, 0xa5ab, 0x6034, 0xa005, 0x0040, 0x5c74, 0xa080, 0x0003,
+ 0x2102, 0x6136, 0x0c7f, 0x007c, 0x613a, 0x6136, 0x0078, 0x5c72,
+ 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x027e, 0x017e, 0x007e,
+ 0x127e, 0x2071, 0xa5ab, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000,
+ 0x8cff, 0x0040, 0x5ced, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206,
+ 0x00c0, 0x5ce8, 0x87ff, 0x0040, 0x5c99, 0x6020, 0xa106, 0x00c0,
+ 0x5ce8, 0x703c, 0xac06, 0x00c0, 0x5cab, 0x037e, 0x2019, 0x0001,
+ 0x1078, 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+ 0x7047, 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x5cb1, 0x660c,
+ 0x763a, 0x7034, 0xac36, 0x00c0, 0x5cbf, 0x2c00, 0xaf36, 0x0040,
+ 0x5cbd, 0x2f00, 0x7036, 0x0078, 0x5cbf, 0x7037, 0x0000, 0x660c,
+ 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5cc8, 0x7e0e, 0x0078, 0x5cc9,
+ 0x2678, 0x600f, 0x0000, 0x1078, 0x8a44, 0x0040, 0x5ce3, 0x6010,
+ 0x2068, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5cf7, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078,
+ 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5c88,
+ 0x2c78, 0x600c, 0x2060, 0x0078, 0x5c88, 0x127f, 0x007f, 0x017f,
+ 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x601c,
+ 0xa086, 0x0006, 0x00c0, 0x5cd6, 0x1078, 0xa181, 0x1078, 0x9e70,
+ 0x0078, 0x5ce3, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x0f7e, 0x2031,
+ 0x0000, 0x127e, 0x2091, 0x8000, 0x2079, 0xa5ab, 0x7838, 0xa065,
+ 0x0040, 0x5d41, 0x600c, 0x007e, 0x600f, 0x0000, 0x783c, 0xac06,
+ 0x00c0, 0x5d28, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x7833,
+ 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000, 0x037f,
+ 0x1078, 0x8a44, 0x0040, 0x5d3c, 0x6010, 0x2068, 0x601c, 0xa086,
+ 0x0003, 0x00c0, 0x5d4a, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+ 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x007f, 0x0078,
+ 0x5d0f, 0x7e3a, 0x7e36, 0x127f, 0x0f7f, 0x0d7f, 0x0c7f, 0x067f,
+ 0x007f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5d33, 0x1078,
+ 0x9e70, 0x0078, 0x5d3c, 0x017e, 0x027e, 0x087e, 0x2041, 0x0000,
+ 0x1078, 0x5d6d, 0x1078, 0x5e21, 0x087f, 0x027f, 0x017f, 0x007c,
+ 0x0f7e, 0x127e, 0x2079, 0xa5ab, 0x2091, 0x8000, 0x1078, 0x5ebc,
+ 0x1078, 0x5f32, 0x127f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x0d7e,
+ 0x0c7e, 0x067e, 0x017e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+ 0xa5ab, 0x7614, 0x2660, 0x2678, 0x8cff, 0x0040, 0x5e01, 0x6018,
+ 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x5dfc, 0x88ff, 0x0040,
+ 0x5d8d, 0x6020, 0xa106, 0x00c0, 0x5dfc, 0x7024, 0xac06, 0x00c0,
+ 0x5dbd, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040, 0x5db8, 0x1078,
+ 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027,
+ 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040,
+ 0x5dad, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824,
+ 0xd084, 0x0040, 0x5db5, 0x6827, 0x0001, 0x037f, 0x0078, 0x5dbd,
+ 0x6003, 0x0009, 0x630a, 0x0078, 0x5dfc, 0x7014, 0xac36, 0x00c0,
+ 0x5dc3, 0x660c, 0x7616, 0x7010, 0xac36, 0x00c0, 0x5dd1, 0x2c00,
+ 0xaf36, 0x0040, 0x5dcf, 0x2f00, 0x7012, 0x0078, 0x5dd1, 0x7013,
+ 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040, 0x5dda, 0x7e0e,
+ 0x0078, 0x5ddb, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+ 0x8a44, 0x0040, 0x5df5, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5e0a,
+ 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078,
+ 0xa181, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+ 0x7045, 0x0c7f, 0x0078, 0x5d7c, 0x2c78, 0x600c, 0x2060, 0x0078,
+ 0x5d7c, 0x127f, 0x007f, 0x017f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f,
+ 0x0f7f, 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x5e15, 0x1078,
+ 0xa181, 0x1078, 0x9e70, 0x0078, 0x5df5, 0x601c, 0xa086, 0x0002,
+ 0x00c0, 0x5df5, 0x6004, 0xa086, 0x0085, 0x0040, 0x5de8, 0x0078,
+ 0x5df5, 0x0c7e, 0x007e, 0x127e, 0x2091, 0x8000, 0xa280, 0xa434,
+ 0x2004, 0xa065, 0x0040, 0x5eb8, 0x0f7e, 0x0e7e, 0x0d7e, 0x067e,
+ 0x2071, 0xa5ab, 0x6654, 0x7018, 0xac06, 0x00c0, 0x5e38, 0x761a,
+ 0x701c, 0xac06, 0x00c0, 0x5e44, 0x86ff, 0x00c0, 0x5e43, 0x7018,
+ 0x701e, 0x0078, 0x5e44, 0x761e, 0x6058, 0xa07d, 0x0040, 0x5e49,
+ 0x7e56, 0xa6ed, 0x0000, 0x0040, 0x5e4f, 0x2f00, 0x685a, 0x6057,
+ 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078,
+ 0x4410, 0x0040, 0x5eb4, 0x7624, 0x86ff, 0x0040, 0x5ea2, 0xa680,
+ 0x0004, 0x2004, 0xad06, 0x00c0, 0x5ea2, 0x0d7e, 0x2069, 0x0100,
+ 0x68c0, 0xa005, 0x0040, 0x5e99, 0x1078, 0x595a, 0x1078, 0x6c41,
+ 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+ 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5e82, 0x6803, 0x0100,
+ 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5e8a,
+ 0x6827, 0x0001, 0x037f, 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040,
+ 0x5e93, 0x8001, 0x603e, 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078,
+ 0x5ea2, 0x0d7f, 0x0c7e, 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f,
+ 0x0078, 0x5e57, 0x8dff, 0x0040, 0x5eb0, 0x6837, 0x0103, 0x6b4a,
+ 0x6847, 0x0000, 0x1078, 0x8cb8, 0x1078, 0xa181, 0x1078, 0x4982,
+ 0x1078, 0x7045, 0x0078, 0x5e57, 0x067f, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x127f, 0x007f, 0x0c7f, 0x007c, 0x007e, 0x067e, 0x0c7e, 0x0d7e,
+ 0x2031, 0x0000, 0x7814, 0xa065, 0x0040, 0x5f16, 0x600c, 0x007e,
+ 0x600f, 0x0000, 0x7824, 0xac06, 0x00c0, 0x5efb, 0x2069, 0x0100,
+ 0x68c0, 0xa005, 0x0040, 0x5ef5, 0x1078, 0x595a, 0x1078, 0x6c41,
+ 0x68c3, 0x0000, 0x1078, 0x7188, 0x7827, 0x0000, 0x037e, 0x2069,
+ 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x5eea, 0x6803, 0x0100,
+ 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x5ef2,
+ 0x6827, 0x0001, 0x037f, 0x0078, 0x5efb, 0x6003, 0x0009, 0x630a,
+ 0x2c30, 0x0078, 0x5f13, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040,
+ 0x5f0f, 0x601c, 0xa086, 0x0003, 0x00c0, 0x5f1d, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078,
+ 0x8c01, 0x1078, 0x7045, 0x007f, 0x0078, 0x5ec3, 0x7e16, 0x7e12,
+ 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x601c, 0xa086, 0x0006,
+ 0x00c0, 0x5f26, 0x1078, 0x9e70, 0x0078, 0x5f0f, 0x601c, 0xa086,
+ 0x0002, 0x00c0, 0x5f0f, 0x6004, 0xa086, 0x0085, 0x0040, 0x5f06,
+ 0x0078, 0x5f0f, 0x007e, 0x067e, 0x0c7e, 0x0d7e, 0x7818, 0xa065,
+ 0x0040, 0x5fa0, 0x6054, 0x007e, 0x6057, 0x0000, 0x605b, 0x0000,
+ 0x6000, 0xc0d4, 0xc0dc, 0x6002, 0x1078, 0x4410, 0x0040, 0x5f9d,
+ 0x7e24, 0x86ff, 0x0040, 0x5f8f, 0xa680, 0x0004, 0x2004, 0xad06,
+ 0x00c0, 0x5f8f, 0x0d7e, 0x2069, 0x0100, 0x68c0, 0xa005, 0x0040,
+ 0x5f86, 0x1078, 0x595a, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078,
+ 0x7188, 0x7827, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384,
+ 0x1000, 0x0040, 0x5f6f, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069,
+ 0x0100, 0x6824, 0xd084, 0x0040, 0x5f77, 0x6827, 0x0001, 0x037f,
+ 0x0d7f, 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5f80, 0x8001, 0x603e,
+ 0x2660, 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x5f8f, 0x0d7f, 0x0c7e,
+ 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x5f44, 0x8dff,
+ 0x0040, 0x5f99, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078,
+ 0x4982, 0x1078, 0x7045, 0x0078, 0x5f44, 0x007f, 0x0078, 0x5f37,
+ 0x781e, 0x781a, 0x0d7f, 0x0c7f, 0x067f, 0x007f, 0x007c, 0x0e7e,
+ 0x0d7e, 0x067e, 0x6000, 0xd0dc, 0x0040, 0x5fc4, 0x604c, 0xa06d,
+ 0x0040, 0x5fc4, 0x6848, 0xa606, 0x00c0, 0x5fc4, 0x2071, 0xa5ab,
+ 0x7024, 0xa035, 0x0040, 0x5fc4, 0xa080, 0x0004, 0x2004, 0xad06,
+ 0x00c0, 0x5fc4, 0x1078, 0x5fc8, 0x067f, 0x0d7f, 0x0e7f, 0x007c,
+ 0x0f7e, 0x2079, 0x0100, 0x78c0, 0xa005, 0x00c0, 0x5fd7, 0x0c7e,
+ 0x2660, 0x6003, 0x0009, 0x630a, 0x0c7f, 0x0078, 0x600e, 0x1078,
+ 0x6c41, 0x78c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e,
+ 0x2079, 0x0140, 0x7b04, 0xa384, 0x1000, 0x0040, 0x5feb, 0x7803,
+ 0x0100, 0x7803, 0x0000, 0x2079, 0x0100, 0x7824, 0xd084, 0x0040,
+ 0x5ff3, 0x7827, 0x0001, 0x1078, 0x7188, 0x037f, 0x1078, 0x4410,
+ 0x0c7e, 0x603c, 0xa005, 0x0040, 0x5fff, 0x8001, 0x603e, 0x2660,
+ 0x1078, 0x753d, 0x0c7f, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+ 0x1078, 0x8cb8, 0x1078, 0x4982, 0x1078, 0x7045, 0x0f7f, 0x007c,
+ 0x0e7e, 0x0c7e, 0x2071, 0xa5ab, 0x7004, 0xa084, 0x0007, 0x0079,
+ 0x6019, 0x6023, 0x6026, 0x603f, 0x605b, 0x60a0, 0x6023, 0x6023,
+ 0x6021, 0x1078, 0x1328, 0x0c7f, 0x0e7f, 0x007c, 0x7024, 0xa065,
+ 0x0040, 0x6034, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015, 0x0040,
+ 0x603b, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+ 0x0c7f, 0x0e7f, 0x007c, 0x7216, 0x7212, 0x0078, 0x6034, 0x6018,
+ 0x2060, 0x1078, 0x4410, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001,
+ 0x7022, 0x0040, 0x6050, 0x6054, 0xa015, 0x0040, 0x6057, 0x721e,
+ 0x7007, 0x0000, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x7218,
+ 0x721e, 0x0078, 0x6050, 0x7024, 0xa065, 0x0040, 0x609d, 0x700c,
+ 0xac06, 0x00c0, 0x6072, 0x1078, 0x7045, 0x600c, 0xa015, 0x0040,
+ 0x606e, 0x720e, 0x600f, 0x0000, 0x0078, 0x609b, 0x720e, 0x720a,
+ 0x0078, 0x609b, 0x7014, 0xac06, 0x00c0, 0x6085, 0x1078, 0x7045,
+ 0x600c, 0xa015, 0x0040, 0x6081, 0x7216, 0x600f, 0x0000, 0x0078,
+ 0x609b, 0x7216, 0x7212, 0x0078, 0x609b, 0x6018, 0x2060, 0x1078,
+ 0x4410, 0x6000, 0xc0dc, 0x6002, 0x1078, 0x7045, 0x701c, 0xa065,
+ 0x0040, 0x609b, 0x6054, 0xa015, 0x0040, 0x6099, 0x721e, 0x0078,
+ 0x609b, 0x7218, 0x721e, 0x7027, 0x0000, 0x0c7f, 0x0e7f, 0x007c,
+ 0x7024, 0xa065, 0x0040, 0x60ad, 0x1078, 0x7045, 0x600c, 0xa015,
+ 0x0040, 0x60b4, 0x720e, 0x600f, 0x0000, 0x1078, 0x7188, 0x7027,
+ 0x0000, 0x0c7f, 0x0e7f, 0x007c, 0x720e, 0x720a, 0x0078, 0x60ad,
+ 0x0d7e, 0x2069, 0xa5ab, 0x6830, 0xa084, 0x0003, 0x0079, 0x60c0,
+ 0x60c6, 0x60c8, 0x60ee, 0x60c6, 0x1078, 0x1328, 0x0d7f, 0x007c,
+ 0x0c7e, 0x6840, 0xa086, 0x0001, 0x0040, 0x60e4, 0x683c, 0xa065,
+ 0x0040, 0x60d9, 0x600c, 0xa015, 0x0040, 0x60e0, 0x6a3a, 0x600f,
+ 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x0c7f, 0x0d7f, 0x007c,
+ 0x683a, 0x6836, 0x0078, 0x60d9, 0x6843, 0x0000, 0x6838, 0xa065,
+ 0x0040, 0x60d9, 0x6003, 0x0003, 0x0078, 0x60d9, 0x0c7e, 0x6843,
+ 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0040, 0x6106, 0x600c,
+ 0xa015, 0x0040, 0x6102, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+ 0x0078, 0x6106, 0x683f, 0x0000, 0x683a, 0x6836, 0x0c7f, 0x0d7f,
+ 0x007c, 0x0d7e, 0x2069, 0xa5ab, 0x6804, 0xa084, 0x0007, 0x0079,
+ 0x6111, 0x611b, 0x61c2, 0x61c2, 0x61c2, 0x61c2, 0x61c4, 0x61c2,
+ 0x6119, 0x1078, 0x1328, 0x6820, 0xa005, 0x00c0, 0x6121, 0x0d7f,
+ 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040, 0x6130, 0x6807, 0x0004,
+ 0x6826, 0x682b, 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c,
+ 0x6814, 0xa065, 0x0040, 0x613e, 0x6807, 0x0001, 0x6826, 0x682b,
+ 0x0000, 0x1078, 0x620a, 0x0c7f, 0x0d7f, 0x007c, 0x0e7e, 0x037e,
+ 0x6a1c, 0xa2f5, 0x0000, 0x0040, 0x61bd, 0x704c, 0xa00d, 0x0040,
+ 0x614d, 0x7088, 0xa005, 0x0040, 0x6165, 0x7054, 0xa075, 0x0040,
+ 0x6156, 0xa20e, 0x0040, 0x61bd, 0x0078, 0x615b, 0x6818, 0xa20e,
+ 0x0040, 0x61bd, 0x2070, 0x704c, 0xa00d, 0x0040, 0x614d, 0x7088,
+ 0xa005, 0x00c0, 0x614d, 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302,
+ 0x00c8, 0x614d, 0x1078, 0x750c, 0x0040, 0x61bd, 0x8318, 0x733e,
+ 0x6112, 0x2e10, 0x621a, 0xa180, 0x0014, 0x2004, 0xa084, 0x00ff,
+ 0x6032, 0xa180, 0x0014, 0x2003, 0x0000, 0xa180, 0x0015, 0x2004,
+ 0xa08a, 0x199a, 0x0048, 0x6186, 0x2001, 0x1999, 0x8003, 0x801b,
+ 0x831b, 0xa318, 0x6316, 0x037f, 0x0f7e, 0x2c78, 0x71a0, 0xd1bc,
+ 0x0040, 0x619f, 0x7100, 0xd1f4, 0x0040, 0x619b, 0x7114, 0xa18c,
+ 0x00ff, 0x0078, 0x61a4, 0x2009, 0x0000, 0x0078, 0x61a4, 0xa1e0,
+ 0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0x1078,
+ 0x679b, 0x7300, 0xc3dd, 0x7302, 0x6807, 0x0002, 0x2f18, 0x6b26,
+ 0x682b, 0x0000, 0x781f, 0x0003, 0x7803, 0x0001, 0x7807, 0x0040,
+ 0x0f7f, 0x0e7f, 0x0c7f, 0x0d7f, 0x007c, 0x037f, 0x0e7f, 0x0c7f,
+ 0x0078, 0x61bb, 0x0d7f, 0x007c, 0x0c7e, 0x680c, 0xa065, 0x0040,
+ 0x61d0, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x1078, 0x620a,
+ 0x0c7f, 0x0d7f, 0x007c, 0x0f7e, 0x0d7e, 0x2069, 0xa5ab, 0x6830,
+ 0xa086, 0x0000, 0x00c0, 0x61f1, 0x6838, 0xa07d, 0x0040, 0x61f1,
+ 0x6833, 0x0001, 0x683e, 0x6847, 0x0000, 0x127e, 0x0f7e, 0x2091,
+ 0x2200, 0x027f, 0x1078, 0x1d28, 0x00c0, 0x61f4, 0x127f, 0x1078,
+ 0x6ae5, 0x0d7f, 0x0f7f, 0x007c, 0x127f, 0x6843, 0x0000, 0x7803,
+ 0x0002, 0x780c, 0xa015, 0x0040, 0x6206, 0x6a3a, 0x780f, 0x0000,
+ 0x6833, 0x0000, 0x683f, 0x0000, 0x0078, 0x61f1, 0x683a, 0x6836,
+ 0x0078, 0x6200, 0x601c, 0xa084, 0x000f, 0x1079, 0x6210, 0x007c,
+ 0x6219, 0x621e, 0x663f, 0x6758, 0x621e, 0x663f, 0x6758, 0x6219,
+ 0x621e, 0x1078, 0x6010, 0x1078, 0x6109, 0x007c, 0x157e, 0x137e,
+ 0x147e, 0x0c7e, 0x0f7e, 0x6004, 0xa08a, 0x0044, 0x10c8, 0x1328,
+ 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x623b, 0x7900, 0xd1f4,
+ 0x0040, 0x6237, 0x7914, 0xa18c, 0x00ff, 0x0078, 0x6240, 0x2009,
+ 0x0000, 0x0078, 0x6240, 0xa1f8, 0x293f, 0x2f0c, 0xa18c, 0x00ff,
+ 0x2c78, 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x00c8, 0x6292,
+ 0x1079, 0x6250, 0x0f7f, 0x0c7f, 0x147f, 0x137f, 0x157f, 0x007c,
+ 0x62f8, 0x6340, 0x6368, 0x6403, 0x6433, 0x643b, 0x6462, 0x6473,
+ 0x6484, 0x648c, 0x64a4, 0x648c, 0x650f, 0x6473, 0x6530, 0x6538,
+ 0x6484, 0x6538, 0x6549, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290,
+ 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6290, 0x6d05, 0x6d2a,
+ 0x6d3f, 0x6d62, 0x6d83, 0x6462, 0x6290, 0x6462, 0x648c, 0x6290,
+ 0x6368, 0x6403, 0x6290, 0x72ac, 0x648c, 0x6290, 0x72cc, 0x648c,
+ 0x6290, 0x6290, 0x62f3, 0x62a1, 0x6290, 0x72f1, 0x7368, 0x7450,
+ 0x6290, 0x7461, 0x645c, 0x747d, 0x6290, 0x6d98, 0x6290, 0x6290,
+ 0x1078, 0x1328, 0x2100, 0x1079, 0x629b, 0x0f7f, 0x0c7f, 0x147f,
+ 0x137f, 0x157f, 0x007c, 0x629f, 0x629f, 0x629f, 0x62d5, 0x1078,
+ 0x1328, 0x0d7e, 0x20a1, 0x020b, 0x1078, 0x6567, 0x7810, 0x2068,
+ 0x20a3, 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x6850, 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x0d7e, 0x7818,
+ 0x2068, 0x68a0, 0xa082, 0x007e, 0x0048, 0x62d2, 0xa085, 0x0001,
+ 0x0d7f, 0x007c, 0xa006, 0x0078, 0x62d0, 0x0d7e, 0x20a1, 0x020b,
+ 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8,
+ 0x000f, 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814,
+ 0x20a2, 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x1078,
+ 0x6c2d, 0x0d7f, 0x007c, 0x6030, 0x609a, 0x1078, 0x6c2d, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x5200, 0x20a3, 0x0000,
+ 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd084, 0x0040, 0x6312, 0x6828,
+ 0x20a3, 0x0000, 0x017e, 0x1078, 0x24fa, 0x21a2, 0x017f, 0x0d7f,
+ 0x0078, 0x6317, 0x0d7f, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a9,
+ 0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+ 0x53a6, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048,
+ 0x6331, 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078,
+ 0x6337, 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x0500, 0x20a3, 0x0000,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0048, 0x6358,
+ 0x2001, 0xa31a, 0x20a6, 0x2001, 0xa31b, 0x20a6, 0x0078, 0x635e,
+ 0x20a3, 0x0000, 0x6030, 0xa084, 0x00ff, 0x20a2, 0x20a9, 0x0004,
+ 0x2099, 0xa305, 0x53a6, 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x6567, 0x0c7e, 0x7818, 0x2060, 0x2001,
+ 0x0000, 0x1078, 0x48a2, 0x0c7f, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0xa086, 0x007e, 0x00c0, 0x6383, 0x20a3, 0x0400, 0x620c, 0xc2b4,
+ 0x620e, 0x0078, 0x6385, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x00c0, 0x63d2, 0x2099,
+ 0xa58c, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0xa084, 0x3fff,
+ 0x20a2, 0x9398, 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a9, 0x0004, 0x2099, 0xa305, 0x53a6,
+ 0x20a9, 0x0004, 0x2099, 0xa301, 0x53a6, 0x20a9, 0x0010, 0x20a3,
+ 0x0000, 0x00f0, 0x63af, 0x2099, 0xa594, 0x3304, 0xc0dd, 0x20a2,
+ 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040, 0x63ca, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398, 0x33a6, 0x20a9, 0x0004,
+ 0x0078, 0x63cc, 0x20a9, 0x0007, 0x20a3, 0x0000, 0x00f0, 0x63cc,
+ 0x0078, 0x63f2, 0x2099, 0xa58c, 0x20a9, 0x0008, 0x53a6, 0x20a9,
+ 0x0004, 0x2099, 0xa305, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xa301,
+ 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e3, 0x20a9,
+ 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63e9, 0x2099, 0xa594, 0x20a9,
+ 0x0008, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x00f0, 0x63f4,
+ 0x20a9, 0x000a, 0x20a3, 0x0000, 0x00f0, 0x63fa, 0x60c3, 0x0074,
+ 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+ 0x2010, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351,
+ 0x7904, 0x0f7f, 0xd1ac, 0x00c0, 0x641f, 0xa085, 0x0020, 0xd1a4,
+ 0x0040, 0x6424, 0xa085, 0x0010, 0xa085, 0x0002, 0x0d7e, 0x0078,
+ 0x64ed, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+ 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+ 0x5000, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3,
+ 0x2110, 0x20a3, 0x0014, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0014, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65ef,
+ 0x0078, 0x6466, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0004,
+ 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3,
+ 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3,
+ 0x0008, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+ 0x20a3, 0x0200, 0x0078, 0x6385, 0x20a1, 0x020b, 0x1078, 0x65f8,
+ 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0xa005, 0x0040, 0x649b,
+ 0x20a2, 0x0078, 0x649d, 0x20a3, 0x0003, 0x7810, 0x20a2, 0x60c3,
+ 0x0008, 0x1078, 0x6c2d, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+ 0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800, 0x7818,
+ 0x2068, 0x6894, 0xa086, 0x0014, 0x00c0, 0x64ca, 0x6998, 0xa184,
+ 0xc000, 0x00c0, 0x64c6, 0xd1ec, 0x0040, 0x64c2, 0x20a3, 0x2100,
+ 0x0078, 0x64cc, 0x20a3, 0x0100, 0x0078, 0x64cc, 0x20a3, 0x0400,
+ 0x0078, 0x64cc, 0x20a3, 0x0700, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a2, 0x0f7e, 0x2079, 0xa351, 0x7904, 0x0f7f, 0xd1ac,
+ 0x00c0, 0x64dc, 0xa085, 0x0020, 0xd1a4, 0x0040, 0x64e1, 0xa085,
+ 0x0010, 0x2009, 0xa373, 0x210c, 0xd184, 0x0040, 0x64eb, 0x699c,
+ 0xd18c, 0x0040, 0x64ed, 0xa085, 0x0002, 0x027e, 0x2009, 0xa371,
+ 0x210c, 0xd1e4, 0x0040, 0x64fb, 0xc0c5, 0xa094, 0x0030, 0xa296,
+ 0x0010, 0x0040, 0x6505, 0xd1ec, 0x0040, 0x6505, 0xa094, 0x0030,
+ 0xa296, 0x0010, 0x0040, 0x6505, 0xc0bd, 0x027f, 0x20a2, 0x20a2,
+ 0x20a2, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1,
+ 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
+ 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x1078, 0x6c2d, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x0078, 0x62fe,
+ 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+ 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x1078,
+ 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+ 0x0000, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x027e, 0x037e,
+ 0x047e, 0x2019, 0x3200, 0x2021, 0x0800, 0x0078, 0x656e, 0x027e,
+ 0x037e, 0x047e, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e,
+ 0x00c0, 0x6581, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x0078,
+ 0x65b6, 0xa286, 0x007f, 0x00c0, 0x658d, 0x0d7e, 0xa385, 0x00ff,
+ 0x20a2, 0x20a3, 0xfffd, 0x0078, 0x65a4, 0xd2bc, 0x0040, 0x65ac,
+ 0xa286, 0x0080, 0x0d7e, 0x00c0, 0x659c, 0xa385, 0x00ff, 0x20a2,
+ 0x20a3, 0xfffc, 0x0078, 0x65a4, 0xa2e8, 0xa434, 0x2d6c, 0x6810,
+ 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+ 0x2da6, 0x0d7f, 0x0078, 0x65ba, 0x0d7e, 0xa2e8, 0xa434, 0x2d6c,
+ 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+ 0x6230, 0x22a2, 0xa485, 0x0029, 0x20a2, 0x047f, 0x037f, 0x20a3,
+ 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x20a3,
+ 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a3, 0x02ff, 0x2011, 0xfffc,
+ 0x22a2, 0x0d7e, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+ 0x20a3, 0x2029, 0x20a3, 0x0000, 0x0078, 0x65c1, 0x20a3, 0x0100,
+ 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3, 0x0000, 0x007c, 0x027e,
+ 0x037e, 0x047e, 0x2019, 0x3300, 0x2021, 0x0800, 0x0078, 0x65ff,
+ 0x027e, 0x037e, 0x047e, 0x2019, 0x2300, 0x2021, 0x0100, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092,
+ 0x007e, 0x0048, 0x661c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+ 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+ 0x2da6, 0x0d7f, 0x0078, 0x662a, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+ 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+ 0x6230, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3, 0x0000, 0x047f,
+ 0x037f, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+ 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0c7e,
+ 0x0f7e, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c,
+ 0x10c8, 0x1328, 0x6118, 0x2178, 0x79a0, 0xd1bc, 0x0040, 0x665d,
+ 0x7900, 0xd1f4, 0x0040, 0x6659, 0x7914, 0xa18c, 0x00ff, 0x0078,
+ 0x6662, 0x2009, 0x0000, 0x0078, 0x6662, 0xa1f8, 0x293f, 0x2f0c,
+ 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a, 0xa082, 0x0085,
+ 0x1079, 0x666d, 0x0f7f, 0x0c7f, 0x007c, 0x6676, 0x6681, 0x669c,
+ 0x6674, 0x6674, 0x6674, 0x6676, 0x1078, 0x1328, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x66af, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+ 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078, 0x66e3, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+ 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+ 0x1078, 0x6c2d, 0x147f, 0x007c, 0x147e, 0x20a1, 0x020b, 0x1078,
+ 0x6724, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0004, 0x1078, 0x6c2d, 0x147f, 0x007c, 0x027e,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0xa092, 0x007e, 0x0048, 0x66ce, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+ 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x66dd, 0x0d7e, 0xa0e8,
+ 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2, 0x6814, 0x20a2,
+ 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0009, 0x20a3,
+ 0x0000, 0x0078, 0x65c1, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048, 0x6702,
+ 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8400, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f,
+ 0x0078, 0x6711, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+ 0x8400, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230,
+ 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2,
+ 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x7a10, 0x22a2, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x027f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa092, 0x007e, 0x0048,
+ 0x6743, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x8500,
+ 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+ 0x0d7f, 0x0078, 0x6752, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+ 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+ 0x6230, 0x22a2, 0x20a3, 0x0099, 0x20a3, 0x0000, 0x0078, 0x6715,
+ 0x0c7e, 0x0f7e, 0x2c78, 0x7804, 0xa08a, 0x0040, 0x1048, 0x1328,
+ 0xa08a, 0x0053, 0x10c8, 0x1328, 0x7918, 0x2160, 0x61a0, 0xd1bc,
+ 0x0040, 0x6777, 0x6100, 0xd1f4, 0x0040, 0x6773, 0x6114, 0xa18c,
+ 0x00ff, 0x0078, 0x677c, 0x2009, 0x0000, 0x0078, 0x677c, 0xa1e0,
+ 0x293f, 0x2c0c, 0xa18c, 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082,
+ 0x0040, 0x1079, 0x6786, 0x0f7f, 0x0c7f, 0x007c, 0x679b, 0x68a9,
+ 0x684a, 0x6a59, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799, 0x6799,
+ 0x6799, 0x6f5e, 0x6f6f, 0x6f80, 0x6f91, 0x6799, 0x748e, 0x6799,
+ 0x6f4d, 0x1078, 0x1328, 0x0d7e, 0x157e, 0x147e, 0x780b, 0xffff,
+ 0x20a1, 0x020b, 0x1078, 0x6806, 0x7910, 0x2168, 0x6948, 0x7922,
+ 0x21a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x694c, 0xa184, 0x000f,
+ 0x00c0, 0x67b6, 0x2001, 0x0005, 0x0078, 0x67c0, 0xd184, 0x0040,
+ 0x67bd, 0x2001, 0x0004, 0x0078, 0x67c0, 0xa084, 0x0006, 0x8004,
+ 0x017e, 0x2008, 0x7830, 0xa084, 0x00ff, 0x8007, 0xa105, 0x017f,
+ 0x20a2, 0xd1ac, 0x0040, 0x67d0, 0x20a3, 0x0002, 0x0078, 0x67dc,
+ 0xd1b4, 0x0040, 0x67d7, 0x20a3, 0x0001, 0x0078, 0x67dc, 0x20a3,
+ 0x0000, 0x2230, 0x0078, 0x67de, 0x6a80, 0x6e7c, 0x20a9, 0x0008,
+ 0xad80, 0x0017, 0x200c, 0x810f, 0x21a2, 0x8000, 0x00f0, 0x67e2,
+ 0x22a2, 0x26a2, 0x60c3, 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084,
+ 0x0004, 0xa085, 0x0009, 0x6016, 0x2001, 0xa5c7, 0x2003, 0x07d0,
+ 0x2001, 0xa5c6, 0x2003, 0x0009, 0x2001, 0xa5cc, 0x2003, 0x0002,
+ 0x1078, 0x157e, 0x147f, 0x157f, 0x0d7f, 0x007c, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294,
+ 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc,
+ 0x0040, 0x682c, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085,
+ 0x0600, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68,
+ 0x2da6, 0x0d7f, 0x0078, 0x683b, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+ 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3,
+ 0x0000, 0x6130, 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2,
+ 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x20a1, 0x020b,
+ 0x1078, 0x686a, 0x7810, 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2,
+ 0x6880, 0x20a2, 0x687c, 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2,
+ 0x20a2, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x147f, 0x137f, 0x157f,
+ 0x0d7f, 0x007c, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6888, 0x0d7e, 0xa0e8,
+ 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814, 0x20a2,
+ 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6897,
+ 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+ 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3,
+ 0x0889, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+ 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+ 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x7810, 0xa06d, 0x1078,
+ 0x488f, 0x0040, 0x68bd, 0x684c, 0xa084, 0x2020, 0xa086, 0x2020,
+ 0x00c0, 0x68bd, 0x7824, 0xc0cd, 0x7826, 0x20a1, 0x020b, 0x1078,
+ 0x6a12, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+ 0xa084, 0xf000, 0x00c0, 0x68d4, 0x7810, 0xa084, 0x0700, 0x8007,
+ 0x1079, 0x68dc, 0x0078, 0x68d7, 0xa006, 0x1079, 0x68dc, 0x147f,
+ 0x137f, 0x157f, 0x0d7f, 0x007c, 0x68e6, 0x697e, 0x6989, 0x69b3,
+ 0x69c7, 0x69e3, 0x69ee, 0x68e4, 0x1078, 0x1328, 0x017e, 0x037e,
+ 0x694c, 0xa18c, 0x0003, 0x0040, 0x68f1, 0xa186, 0x0003, 0x00c0,
+ 0x6900, 0x6b78, 0x7824, 0xd0cc, 0x0040, 0x68f7, 0xc3e5, 0x23a2,
+ 0x6868, 0x20a2, 0x6864, 0x20a2, 0x037f, 0x017f, 0x0078, 0x69be,
+ 0xa186, 0x0001, 0x10c0, 0x1328, 0x6b78, 0x7824, 0xd0cc, 0x0040,
+ 0x690a, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+ 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+ 0x0300, 0x0040, 0x6978, 0xd3c4, 0x0040, 0x6920, 0x687c, 0xa108,
+ 0xd3cc, 0x0040, 0x6925, 0x6874, 0xa108, 0x157e, 0x20a9, 0x000d,
+ 0xad80, 0x0020, 0x201c, 0x831f, 0x23a2, 0x8000, 0x00f0, 0x692a,
+ 0x157f, 0x22a2, 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0040, 0x6978,
+ 0x20a1, 0x020b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x007e, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6958, 0x0d7e, 0xa0e8,
+ 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+ 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6967,
+ 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+ 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x007f,
+ 0x7b24, 0xd3cc, 0x0040, 0x6970, 0x20a3, 0x0889, 0x0078, 0x6972,
+ 0x20a3, 0x0898, 0x20a2, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+ 0x61c2, 0x037f, 0x017f, 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008,
+ 0x7824, 0xd0cc, 0x0040, 0x6985, 0xc2e5, 0x22a2, 0xa016, 0x0078,
+ 0x69bc, 0x2011, 0x0302, 0x7824, 0xd0cc, 0x0040, 0x6990, 0xc2e5,
+ 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2,
+ 0x20a3, 0x0008, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000,
+ 0x20a3, 0x0500, 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3,
+ 0x2500, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032,
+ 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0028, 0x7824, 0xd0cc, 0x0040,
+ 0x69ba, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+ 0x22a2, 0x22a2, 0x60c3, 0x0018, 0x1078, 0x6c2d, 0x007c, 0x2011,
+ 0x0100, 0x7824, 0xd0cc, 0x0040, 0x69ce, 0xc2e5, 0x22a2, 0xa016,
+ 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0008, 0x22a2,
+ 0x7834, 0xa084, 0x00ff, 0x20a2, 0x22a2, 0x22a2, 0x60c3, 0x0020,
+ 0x1078, 0x6c2d, 0x007c, 0x2011, 0x0008, 0x7824, 0xd0cc, 0x0040,
+ 0x69ea, 0xc2e5, 0x22a2, 0xa016, 0x0078, 0x69bc, 0x037e, 0x7b10,
+ 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001, 0x00c0, 0x6a01,
+ 0x7824, 0xd0cc, 0x0040, 0x69fd, 0xc2e5, 0x22a2, 0x037f, 0x0078,
+ 0x69bc, 0x047e, 0x2021, 0x0800, 0x007e, 0x7824, 0xd0cc, 0x007f,
+ 0x0040, 0x6a0b, 0xc4e5, 0x24a2, 0x047f, 0x22a2, 0x20a2, 0x037f,
+ 0x0078, 0x69be, 0x027e, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040, 0x6a30, 0x0d7e, 0xa0e8,
+ 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2, 0x6814, 0x20a2,
+ 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x6a3f,
+ 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+ 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x7824,
+ 0xd0cc, 0x0040, 0x6a47, 0x20a3, 0x0889, 0x0078, 0x6a49, 0x20a3,
+ 0x0898, 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000,
+ 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x027f,
+ 0x007c, 0x0d7e, 0x157e, 0x137e, 0x147e, 0x017e, 0x037e, 0x7810,
+ 0xa084, 0x0700, 0x8007, 0x1079, 0x6a6c, 0x037f, 0x017f, 0x147f,
+ 0x137f, 0x157f, 0x0d7f, 0x007c, 0x6a74, 0x6a74, 0x6a76, 0x6a74,
+ 0x6a74, 0x6a74, 0x6a9b, 0x6a74, 0x1078, 0x1328, 0x7910, 0xa18c,
+ 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+ 0x1078, 0x6aa5, 0x0d7e, 0x2069, 0xa351, 0x6804, 0xd0bc, 0x0040,
+ 0x6a90, 0x682c, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0078, 0x6a92,
+ 0x20a3, 0x3f00, 0x0d7f, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001,
+ 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x2009, 0x0003, 0x1078,
+ 0x6aa5, 0x20a3, 0x7f00, 0x0078, 0x6a93, 0x027e, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004, 0xd0bc, 0x0040,
+ 0x6ac3, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810, 0xa085, 0x0100,
+ 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a, 0x2da6, 0x8d68, 0x2da6,
+ 0x0d7f, 0x0078, 0x6ad2, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c, 0x6810,
+ 0xa085, 0x0100, 0x20a2, 0x6814, 0x20a2, 0x0d7f, 0x20a3, 0x0000,
+ 0x6230, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x1078,
+ 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x0c7e,
+ 0x057e, 0x047e, 0x037e, 0x2061, 0x0100, 0x2071, 0xa300, 0x6130,
+ 0x7818, 0x2068, 0x68a0, 0x2028, 0xd0bc, 0x00c0, 0x6afc, 0x6910,
+ 0x6a14, 0x6430, 0x0078, 0x6b00, 0x6910, 0x6a14, 0x7368, 0x746c,
+ 0x781c, 0xa086, 0x0006, 0x0040, 0x6b5f, 0xd5bc, 0x0040, 0x6b10,
+ 0xa185, 0x0100, 0x6062, 0x6266, 0x636a, 0x646e, 0x0078, 0x6b17,
+ 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x6073,
+ 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+ 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
+ 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+ 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5,
+ 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6b49, 0x6a00, 0xd2f4,
+ 0x0040, 0x6b47, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6b49, 0x2011,
+ 0x0000, 0x629e, 0x6017, 0x0016, 0x2009, 0x07d0, 0x60c4, 0xa084,
+ 0xfff0, 0xa005, 0x0040, 0x6b56, 0x2009, 0x1b58, 0x1078, 0x595f,
+ 0x037f, 0x047f, 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7810,
+ 0x2070, 0x704c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0040, 0x6bb7,
+ 0xd5bc, 0x0040, 0x6b73, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+ 0x646e, 0x0078, 0x6b7a, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b,
+ 0x0000, 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000,
+ 0xa084, 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00,
+ 0x6086, 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080,
+ 0x60c6, 0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080,
+ 0x7928, 0xa109, 0x792a, 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af,
+ 0x95d5, 0x60d7, 0x0000, 0xa582, 0x0080, 0x0048, 0x6bb2, 0x6a00,
+ 0xd2f4, 0x0040, 0x6bb0, 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6bb2,
+ 0x2011, 0x0000, 0x629e, 0x6017, 0x0012, 0x0078, 0x6b4c, 0xd5bc,
+ 0x0040, 0x6bc2, 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e,
+ 0x0078, 0x6bc9, 0xa185, 0x0700, 0x6062, 0x6266, 0x606b, 0x0000,
+ 0x646e, 0x1078, 0x488f, 0x0040, 0x6bdf, 0x0d7e, 0x7810, 0xa06d,
+ 0x684c, 0x0d7f, 0xa084, 0x2020, 0xa086, 0x2020, 0x00c0, 0x6bdf,
+ 0x7824, 0xc0cd, 0x7826, 0x6073, 0x0889, 0x0078, 0x6be1, 0x6073,
+ 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+ 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086, 0x7808, 0x6082,
+ 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6, 0x7008, 0x60ca,
+ 0x686c, 0x60ce, 0x60ab, 0x0036, 0x60af, 0x95d5, 0x60d7, 0x0000,
+ 0xa582, 0x0080, 0x0048, 0x6c0f, 0x6a00, 0xd2f4, 0x0040, 0x6c0d,
+ 0x6a14, 0xa294, 0x00ff, 0x0078, 0x6c0f, 0x2011, 0x0000, 0x629e,
+ 0x7824, 0xd0cc, 0x0040, 0x6c18, 0x6017, 0x0016, 0x0078, 0x6b4c,
+ 0x6017, 0x0012, 0x0078, 0x6b4c, 0x7a18, 0xa280, 0x0023, 0x2014,
+ 0x8210, 0xa294, 0x00ff, 0x2202, 0x8217, 0x007c, 0x0d7e, 0x2069,
+ 0xa5ab, 0x6843, 0x0001, 0x0d7f, 0x007c, 0x20e1, 0x9080, 0x60a3,
+ 0x0056, 0x60a7, 0x9575, 0x1078, 0x6c38, 0x1078, 0x594f, 0x007c,
+ 0x007e, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009, 0x6016, 0x007f,
+ 0x007c, 0x007e, 0x0c7e, 0x2061, 0x0100, 0x6014, 0xa084, 0x0004,
+ 0xa085, 0x0008, 0x6016, 0x0c7f, 0x007f, 0x007c, 0x0c7e, 0x0d7e,
+ 0x017e, 0x027e, 0x2061, 0x0100, 0x2069, 0x0140, 0x6904, 0xa194,
+ 0x4000, 0x0040, 0x6c89, 0x1078, 0x6c41, 0x6803, 0x1000, 0x6803,
+ 0x0000, 0x0c7e, 0x2061, 0xa5ab, 0x6128, 0xa192, 0x00c8, 0x00c8,
+ 0x6c76, 0x8108, 0x612a, 0x6124, 0x0c7f, 0x81ff, 0x0040, 0x6c84,
+ 0x1078, 0x594f, 0x1078, 0x6c38, 0x0078, 0x6c84, 0x6124, 0xa1e5,
+ 0x0000, 0x0040, 0x6c81, 0x1078, 0xa241, 0x2009, 0x0014, 0x1078,
+ 0x756c, 0x0c7f, 0x0078, 0x6c84, 0x027f, 0x017f, 0x0d7f, 0x0c7f,
+ 0x007c, 0x2001, 0xa5c7, 0x2004, 0xa005, 0x00c0, 0x6c84, 0x0c7e,
+ 0x2061, 0xa5ab, 0x6128, 0xa192, 0x0003, 0x00c8, 0x6c76, 0x8108,
+ 0x612a, 0x0c7f, 0x1078, 0x594f, 0x1078, 0x4171, 0x0078, 0x6c84,
+ 0x0c7e, 0x0d7e, 0x0e7e, 0x017e, 0x027e, 0x1078, 0x5967, 0x2071,
+ 0xa5ab, 0x713c, 0x81ff, 0x0040, 0x6cca, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x6904, 0xa194, 0x4000, 0x0040, 0x6cd0, 0x6803, 0x1000,
+ 0x6803, 0x0000, 0x037e, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x037f,
+ 0x713c, 0x2160, 0x1078, 0xa241, 0x2009, 0x004a, 0x1078, 0x756c,
+ 0x0078, 0x6cca, 0x027f, 0x017f, 0x0e7f, 0x0d7f, 0x0c7f, 0x007c,
+ 0x0078, 0x6cba, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x057e, 0x047e,
+ 0x007e, 0x127e, 0x2091, 0x8000, 0x6018, 0x2068, 0x6ca0, 0x2071,
+ 0xa5ab, 0x7018, 0x2068, 0x8dff, 0x0040, 0x6cfc, 0x68a0, 0xa406,
+ 0x0040, 0x6cee, 0x6854, 0x2068, 0x0078, 0x6ce3, 0x6010, 0x2060,
+ 0x643c, 0x6540, 0x6e48, 0x2d60, 0x1078, 0x466a, 0x0040, 0x6cfc,
+ 0x1078, 0x7045, 0xa085, 0x0001, 0x127f, 0x007f, 0x047f, 0x057f,
+ 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x20a1, 0x020b, 0x1078,
+ 0x6567, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+ 0xa086, 0x0004, 0x00c0, 0x6d17, 0x6098, 0x0078, 0x6d18, 0x6030,
+ 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+ 0x20a2, 0x00f0, 0x6d20, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x1078,
+ 0x6c2d, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6567,
+ 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+ 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c, 0x157e,
+ 0x147e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0200, 0x20a3,
+ 0x0000, 0x20a9, 0x0006, 0x2011, 0xa340, 0x2019, 0xa341, 0x23a6,
+ 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x00f0, 0x6d4f, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x1078, 0x6c2d, 0x147f,
+ 0x157f, 0x007c, 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b,
+ 0x1078, 0x65cf, 0x1078, 0x65e6, 0x7810, 0xa080, 0x0000, 0x2004,
+ 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+ 0xa080, 0x0004, 0x8003, 0x60c2, 0x1078, 0x6c2d, 0x027f, 0x017f,
+ 0x147f, 0x157f, 0x007c, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078,
+ 0x6567, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+ 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x147f, 0x157f, 0x007c,
+ 0x157e, 0x147e, 0x017e, 0x027e, 0x20a1, 0x020b, 0x1078, 0x6567,
+ 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+ 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x1078, 0x6c2d,
+ 0x027f, 0x017f, 0x147f, 0x157f, 0x007c, 0x0e7e, 0x0c7e, 0x007e,
+ 0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x700c, 0x2060, 0x8cff,
+ 0x0040, 0x6dd1, 0x1078, 0x8c3b, 0x00c0, 0x6dc8, 0x1078, 0x7a05,
+ 0x600c, 0x007e, 0x1078, 0x753d, 0x1078, 0x7045, 0x0c7f, 0x0078,
+ 0x6dbf, 0x700f, 0x0000, 0x700b, 0x0000, 0x127f, 0x007f, 0x0c7f,
+ 0x0e7f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e,
+ 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079,
+ 0x0140, 0x2071, 0xa5ab, 0x7024, 0x2060, 0x8cff, 0x0040, 0x6e2a,
+ 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x595a, 0x2009, 0x0013,
+ 0x1078, 0x756c, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0040, 0x6e0d,
+ 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6e1f, 0x7803,
+ 0x1000, 0x7803, 0x0000, 0x0078, 0x6e1f, 0xd084, 0x0040, 0x6e14,
+ 0x6827, 0x0001, 0x0078, 0x6e16, 0x00f0, 0x6dfc, 0x7804, 0xa084,
+ 0x1000, 0x0040, 0x6e1f, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+ 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+ 0x127f, 0x007c, 0x2001, 0xa300, 0x2004, 0xa096, 0x0001, 0x0040,
+ 0x6e62, 0xa096, 0x0004, 0x0040, 0x6e62, 0x6817, 0x0008, 0x68c3,
+ 0x0000, 0x2011, 0x4129, 0x1078, 0x58d4, 0x20a9, 0x01f4, 0x6824,
+ 0xd094, 0x0040, 0x6e50, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000,
+ 0x0040, 0x6e62, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0x6e62,
+ 0xd084, 0x0040, 0x6e57, 0x6827, 0x0001, 0x0078, 0x6e59, 0x00f0,
+ 0x6e3f, 0x7804, 0xa084, 0x1000, 0x0040, 0x6e62, 0x7803, 0x0100,
+ 0x7803, 0x0000, 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f,
+ 0x0f7f, 0x157f, 0x127f, 0x007c, 0x127e, 0x157e, 0x0f7e, 0x0e7e,
+ 0x0d7e, 0x0c7e, 0x027e, 0x017e, 0x007e, 0x2091, 0x8000, 0x2069,
+ 0x0100, 0x2079, 0x0140, 0x2071, 0xa5ab, 0x703c, 0x2060, 0x8cff,
+ 0x0040, 0x6ee8, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x00c0,
+ 0x6e86, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x1078, 0x5967, 0x1078,
+ 0x1f31, 0x047e, 0x057e, 0x2009, 0x017f, 0x212c, 0x200b, 0x00a5,
+ 0x2021, 0x0169, 0x2404, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+ 0x6eb7, 0x68c7, 0x0000, 0x68cb, 0x0008, 0x0e7e, 0x0f7e, 0x2079,
+ 0x0020, 0x2071, 0xa602, 0x6814, 0xa084, 0x0004, 0xa085, 0x0012,
+ 0x6816, 0x7803, 0x0008, 0x7003, 0x0000, 0x0f7f, 0x0e7f, 0x250a,
+ 0x057f, 0x047f, 0xa39d, 0x0000, 0x00c0, 0x6ec2, 0x2009, 0x0049,
+ 0x1078, 0x756c, 0x20a9, 0x03e8, 0x6824, 0xd094, 0x0040, 0x6ed5,
+ 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x0040, 0x6ee7, 0x7803,
+ 0x1000, 0x7803, 0x0000, 0x0078, 0x6ee7, 0xd08c, 0x0040, 0x6edc,
+ 0x6827, 0x0002, 0x0078, 0x6ede, 0x00f0, 0x6ec4, 0x7804, 0xa084,
+ 0x1000, 0x0040, 0x6ee7, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+ 0x007f, 0x017f, 0x027f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x157f,
+ 0x127f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000, 0x2069, 0xa5ab,
+ 0x6a06, 0x127f, 0x0d7f, 0x007c, 0x0d7e, 0x127e, 0x2091, 0x8000,
+ 0x2069, 0xa5ab, 0x6a32, 0x127f, 0x0d7f, 0x007c, 0x0f7e, 0x0e7e,
+ 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2071, 0xa5ab, 0x7614, 0x2660,
+ 0x2678, 0x2091, 0x8000, 0x8cff, 0x0040, 0x6f46, 0x601c, 0xa206,
+ 0x00c0, 0x6f41, 0x7014, 0xac36, 0x00c0, 0x6f20, 0x660c, 0x7616,
+ 0x7010, 0xac36, 0x00c0, 0x6f2e, 0x2c00, 0xaf36, 0x0040, 0x6f2c,
+ 0x2f00, 0x7012, 0x0078, 0x6f2e, 0x7013, 0x0000, 0x660c, 0x067e,
+ 0x2c00, 0xaf06, 0x0040, 0x6f37, 0x7e0e, 0x0078, 0x6f38, 0x2678,
+ 0x600f, 0x0000, 0x1078, 0x8c01, 0x1078, 0x7045, 0x0c7f, 0x0078,
+ 0x6f13, 0x2c78, 0x600c, 0x2060, 0x0078, 0x6f13, 0x127f, 0x007f,
+ 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0x157e, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0078, 0x6fa0, 0x157e, 0x147e,
+ 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000, 0x0078, 0x6fa0, 0x157e,
+ 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2, 0xa006,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000, 0x0078, 0x6fa0,
+ 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810, 0x20a2,
+ 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400, 0x0078,
+ 0x6fa0, 0x157e, 0x147e, 0x20a1, 0x020b, 0x1078, 0x6806, 0x7810,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+ 0x1078, 0x7050, 0x60c3, 0x0020, 0x1078, 0x6c2d, 0x147f, 0x157f,
+ 0x007c, 0x127e, 0x0c7e, 0x2091, 0x8000, 0x2061, 0x0100, 0x6120,
+ 0xd1b4, 0x00c0, 0x6fb8, 0xd1bc, 0x00c0, 0x7002, 0x0078, 0x7042,
+ 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e, 0x0d7e, 0x2069,
+ 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804, 0xa084, 0x4000,
+ 0x0040, 0x6ff9, 0x6020, 0xd0b4, 0x0040, 0x6ff9, 0x6024, 0xd094,
+ 0x00c0, 0x6ff9, 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0,
+ 0x6ff9, 0x00f0, 0x6fc5, 0x027e, 0x6198, 0xa18c, 0x00ff, 0x8107,
+ 0x6130, 0xa18c, 0x00ff, 0xa10d, 0x6088, 0x628c, 0x618e, 0x608b,
+ 0xbc91, 0x6043, 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6024,
+ 0xd094, 0x00c0, 0x6ff8, 0x6a04, 0xa294, 0x4000, 0x00c0, 0x6fef,
+ 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f, 0x200b, 0x0000,
+ 0x0078, 0x7042, 0x2009, 0x017f, 0x200b, 0x00a1, 0x157e, 0x007e,
+ 0x0d7e, 0x2069, 0x0140, 0x20a9, 0x001e, 0x2009, 0x0169, 0x6804,
+ 0xa084, 0x4000, 0x0040, 0x703b, 0x6020, 0xd0bc, 0x0040, 0x703b,
+ 0x2104, 0xa084, 0x000f, 0xa086, 0x0004, 0x00c0, 0x703b, 0x00f0,
+ 0x700f, 0x027e, 0x6164, 0xa18c, 0x00ff, 0x8107, 0x6130, 0xa18c,
+ 0x00ff, 0xa10d, 0x6088, 0x628c, 0x608b, 0xbc91, 0x618e, 0x6043,
+ 0x0001, 0x6043, 0x0000, 0x608a, 0x628e, 0x6a04, 0xa294, 0x4000,
+ 0x00c0, 0x7035, 0x027f, 0x0d7f, 0x007f, 0x157f, 0x2009, 0x017f,
+ 0x200b, 0x0000, 0x0c7f, 0x127f, 0x007c, 0x0e7e, 0x2071, 0xa5ab,
+ 0x7020, 0xa005, 0x0040, 0x704e, 0x8001, 0x7022, 0x0e7f, 0x007c,
+ 0x20a9, 0x0008, 0x20a2, 0x00f0, 0x7052, 0x20a2, 0x20a2, 0x007c,
+ 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x077e, 0x067e, 0x007e, 0x127e,
+ 0x2091, 0x8000, 0x2071, 0xa5ab, 0x7614, 0x2660, 0x2678, 0x2039,
+ 0x0001, 0x87ff, 0x0040, 0x70f4, 0x8cff, 0x0040, 0x70f4, 0x601c,
+ 0xa086, 0x0006, 0x00c0, 0x70ef, 0x88ff, 0x0040, 0x707f, 0x2800,
+ 0xac06, 0x00c0, 0x70ef, 0x2039, 0x0000, 0x0078, 0x708a, 0x6018,
+ 0xa206, 0x00c0, 0x70ef, 0x85ff, 0x0040, 0x708a, 0x6020, 0xa106,
+ 0x00c0, 0x70ef, 0x7024, 0xac06, 0x00c0, 0x70ba, 0x2069, 0x0100,
+ 0x68c0, 0xa005, 0x0040, 0x70b5, 0x1078, 0x595a, 0x6817, 0x0008,
+ 0x68c3, 0x0000, 0x1078, 0x7188, 0x7027, 0x0000, 0x037e, 0x2069,
+ 0x0140, 0x6b04, 0xa384, 0x1000, 0x0040, 0x70aa, 0x6803, 0x0100,
+ 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0040, 0x70b2,
+ 0x6827, 0x0001, 0x037f, 0x0078, 0x70ba, 0x6003, 0x0009, 0x630a,
+ 0x0078, 0x70ef, 0x7014, 0xac36, 0x00c0, 0x70c0, 0x660c, 0x7616,
+ 0x7010, 0xac36, 0x00c0, 0x70ce, 0x2c00, 0xaf36, 0x0040, 0x70cc,
+ 0x2f00, 0x7012, 0x0078, 0x70ce, 0x7013, 0x0000, 0x660c, 0x067e,
+ 0x2c00, 0xaf06, 0x0040, 0x70d7, 0x7e0e, 0x0078, 0x70d8, 0x2678,
+ 0x89ff, 0x00c0, 0x70e7, 0x600f, 0x0000, 0x6010, 0x2068, 0x1078,
+ 0x8a44, 0x0040, 0x70e5, 0x1078, 0x9e70, 0x1078, 0x8c01, 0x1078,
+ 0x7045, 0x88ff, 0x00c0, 0x70fe, 0x0c7f, 0x0078, 0x7069, 0x2c78,
+ 0x600c, 0x2060, 0x0078, 0x7069, 0xa006, 0x127f, 0x007f, 0x067f,
+ 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f, 0x007c, 0x6017, 0x0000,
+ 0x0c7f, 0xa8c5, 0x0001, 0x0078, 0x70f5, 0x0f7e, 0x0e7e, 0x0d7e,
+ 0x0c7e, 0x067e, 0x027e, 0x007e, 0x127e, 0x2091, 0x8000, 0x2071,
+ 0xa5ab, 0x7638, 0x2660, 0x2678, 0x8cff, 0x0040, 0x7177, 0x601c,
+ 0xa086, 0x0006, 0x00c0, 0x7172, 0x87ff, 0x0040, 0x7125, 0x2700,
+ 0xac06, 0x00c0, 0x7172, 0x0078, 0x7130, 0x6018, 0xa206, 0x00c0,
+ 0x7172, 0x85ff, 0x0040, 0x7130, 0x6020, 0xa106, 0x00c0, 0x7172,
+ 0x703c, 0xac06, 0x00c0, 0x7142, 0x037e, 0x2019, 0x0001, 0x1078,
+ 0x6e6c, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000, 0x7047,
+ 0x0000, 0x037f, 0x7038, 0xac36, 0x00c0, 0x7148, 0x660c, 0x763a,
+ 0x7034, 0xac36, 0x00c0, 0x7156, 0x2c00, 0xaf36, 0x0040, 0x7154,
+ 0x2f00, 0x7036, 0x0078, 0x7156, 0x7037, 0x0000, 0x660c, 0x067e,
+ 0x2c00, 0xaf06, 0x0040, 0x715f, 0x7e0e, 0x0078, 0x7160, 0x2678,
+ 0x600f, 0x0000, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x716a,
+ 0x1078, 0x9e70, 0x1078, 0x8c01, 0x87ff, 0x00c0, 0x7181, 0x0c7f,
+ 0x0078, 0x7114, 0x2c78, 0x600c, 0x2060, 0x0078, 0x7114, 0xa006,
+ 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x007c, 0x6017, 0x0000, 0x0c7f, 0xa7bd, 0x0001, 0x0078, 0x7178,
+ 0x0e7e, 0x2071, 0xa5ab, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002,
+ 0x00c0, 0x7196, 0x7007, 0x0005, 0x0078, 0x7198, 0x7007, 0x0000,
+ 0x0e7f, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x067e, 0x027e, 0x007e,
+ 0x127e, 0x2091, 0x8000, 0x2071, 0xa5ab, 0x2c10, 0x7638, 0x2660,
+ 0x2678, 0x8cff, 0x0040, 0x71d8, 0x2200, 0xac06, 0x00c0, 0x71d3,
+ 0x7038, 0xac36, 0x00c0, 0x71b6, 0x660c, 0x763a, 0x7034, 0xac36,
+ 0x00c0, 0x71c4, 0x2c00, 0xaf36, 0x0040, 0x71c2, 0x2f00, 0x7036,
+ 0x0078, 0x71c4, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0040,
+ 0x71cc, 0x7e0e, 0x0078, 0x71cd, 0x2678, 0x600f, 0x0000, 0xa085,
+ 0x0001, 0x0078, 0x71d8, 0x2c78, 0x600c, 0x2060, 0x0078, 0x71a9,
+ 0x127f, 0x007f, 0x027f, 0x067f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c,
+ 0x0f7e, 0x0e7e, 0x0d7e, 0x0c7e, 0x067e, 0x007e, 0x127e, 0x2091,
+ 0x8000, 0x2071, 0xa5ab, 0x760c, 0x2660, 0x2678, 0x8cff, 0x0040,
+ 0x7279, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x00c0, 0x7274,
+ 0x7024, 0xac06, 0x00c0, 0x721f, 0x2069, 0x0100, 0x68c0, 0xa005,
+ 0x0040, 0x724d, 0x1078, 0x6c41, 0x68c3, 0x0000, 0x1078, 0x7188,
+ 0x7027, 0x0000, 0x037e, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000,
+ 0x0040, 0x7216, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+ 0x6824, 0xd084, 0x0040, 0x721e, 0x6827, 0x0001, 0x037f, 0x700c,
+ 0xac36, 0x00c0, 0x7225, 0x660c, 0x760e, 0x7008, 0xac36, 0x00c0,
+ 0x7233, 0x2c00, 0xaf36, 0x0040, 0x7231, 0x2f00, 0x700a, 0x0078,
+ 0x7233, 0x700b, 0x0000, 0x660c, 0x067e, 0x2c00, 0xaf06, 0x0040,
+ 0x723c, 0x7e0e, 0x0078, 0x723d, 0x2678, 0x600f, 0x0000, 0x1078,
+ 0x8c27, 0x00c0, 0x7251, 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0,
+ 0x726d, 0x1078, 0x7a05, 0x0078, 0x726d, 0x1078, 0x7188, 0x0078,
+ 0x721f, 0x1078, 0x8c3b, 0x00c0, 0x7259, 0x1078, 0x7a05, 0x0078,
+ 0x726d, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x726d, 0x601c,
+ 0xa086, 0x0003, 0x00c0, 0x7281, 0x6837, 0x0103, 0x6b4a, 0x6847,
+ 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x1078, 0x8c01, 0x1078,
+ 0x7045, 0x0c7f, 0x0078, 0x71ee, 0x2c78, 0x600c, 0x2060, 0x0078,
+ 0x71ee, 0x127f, 0x007f, 0x067f, 0x0c7f, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x007c, 0x601c, 0xa086, 0x0006, 0x00c0, 0x726d, 0x1078, 0x9e70,
+ 0x0078, 0x726d, 0x037e, 0x157e, 0x137e, 0x147e, 0x3908, 0xa006,
+ 0xa190, 0x0020, 0x221c, 0xa39e, 0x260c, 0x00c0, 0x729b, 0x8210,
+ 0x8000, 0x0078, 0x7292, 0xa005, 0x0040, 0x72a7, 0x20a9, 0x0020,
+ 0x2198, 0x8211, 0xa282, 0x0020, 0x20c8, 0x20a0, 0x53a3, 0x147f,
+ 0x137f, 0x157f, 0x037f, 0x007c, 0x0d7e, 0x20a1, 0x020b, 0x1078,
+ 0x65f8, 0x20a3, 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x2099, 0xa5a3, 0x20a9, 0x0004, 0x53a6,
+ 0x20a3, 0x0004, 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x1078, 0x6c2d, 0x0d7f, 0x007c, 0x20a1, 0x020b, 0x1078, 0x65f8,
+ 0x20a3, 0x0214, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084,
+ 0xff00, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0018, 0x1078, 0x6c2d,
+ 0x007c, 0x0d7e, 0x017e, 0x2f68, 0x2009, 0x0035, 0x1078, 0x8ef5,
+ 0x00c0, 0x7361, 0x20a1, 0x020b, 0x1078, 0x6567, 0x20a3, 0x1300,
+ 0x20a3, 0x0000, 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0040,
+ 0x733d, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x00c0,
+ 0x7317, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0078, 0x7352, 0xa286,
+ 0x007f, 0x00c0, 0x7321, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0078,
+ 0x7352, 0xd2bc, 0x0040, 0x7337, 0xa286, 0x0080, 0x00c0, 0x732e,
+ 0x20a3, 0x00ff, 0x20a3, 0xfffc, 0x0078, 0x7352, 0xa2e8, 0xa434,
+ 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2, 0x0078, 0x7352, 0x20a3,
+ 0x0000, 0x6098, 0x20a2, 0x0078, 0x7352, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0xa082, 0x007e, 0x0048, 0x734e, 0x0d7e, 0x2069, 0xa31a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x7352, 0x20a3, 0x0000,
+ 0x6030, 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x000c, 0x1078, 0x6c2d, 0x017f, 0x0d7f,
+ 0x007c, 0x7817, 0x0001, 0x7803, 0x0006, 0x017f, 0x0d7f, 0x007c,
+ 0x0d7e, 0x027e, 0x7928, 0x2168, 0x691c, 0xa186, 0x0006, 0x0040,
+ 0x738a, 0xa186, 0x0003, 0x0040, 0x73e5, 0xa186, 0x0005, 0x0040,
+ 0x73c8, 0xa186, 0x0004, 0x0040, 0x73b8, 0xa186, 0x0008, 0x0040,
+ 0x73d2, 0x7807, 0x0037, 0x7813, 0x1700, 0x1078, 0x7450, 0x027f,
+ 0x0d7f, 0x007c, 0x1078, 0x740d, 0x2009, 0x4000, 0x6800, 0x0079,
+ 0x7391, 0x73a4, 0x73b2, 0x73a6, 0x73b2, 0x73ad, 0x73a4, 0x73a4,
+ 0x73b2, 0x73b2, 0x73b2, 0x73b2, 0x73a4, 0x73a4, 0x73a4, 0x73a4,
+ 0x73a4, 0x73b2, 0x73a4, 0x73b2, 0x1078, 0x1328, 0x6824, 0xd0e4,
+ 0x0040, 0x73ad, 0xd0cc, 0x0040, 0x73b0, 0xa00e, 0x0078, 0x73b2,
+ 0x2009, 0x2000, 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0078, 0x7403,
+ 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+ 0x6a00, 0xa286, 0x0002, 0x00c0, 0x73c6, 0xa00e, 0x0078, 0x7403,
+ 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000,
+ 0x0078, 0x7403, 0x1078, 0x740d, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x2009, 0x4000, 0xa286, 0x0005, 0x0040, 0x73e2, 0xa286, 0x0002,
+ 0x00c0, 0x73e3, 0xa00e, 0x0078, 0x7403, 0x1078, 0x740d, 0x6810,
+ 0x2068, 0x697c, 0x6810, 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2,
+ 0x22a2, 0x7928, 0xa180, 0x0000, 0x2004, 0xa08e, 0x0002, 0x0040,
+ 0x7401, 0xa08e, 0x0004, 0x0040, 0x7401, 0x2009, 0x4000, 0x0078,
+ 0x7403, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000, 0x60c3, 0x0018,
+ 0x1078, 0x6c2d, 0x027f, 0x0d7f, 0x007c, 0x037e, 0x047e, 0x057e,
+ 0x067e, 0x20a1, 0x020b, 0x1078, 0x65f8, 0xa006, 0x20a3, 0x0200,
+ 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0xa092, 0x007e, 0x0048, 0x7433, 0x0d7e, 0x2069, 0xa31a,
+ 0x2d2c, 0x8d68, 0x2d34, 0xa0e8, 0xa434, 0x2d6c, 0x6b10, 0x6c14,
+ 0x0d7f, 0x0078, 0x7439, 0x2019, 0x0000, 0x6498, 0x2029, 0x0000,
+ 0x6630, 0x7828, 0xa080, 0x0007, 0x2004, 0xa086, 0x0003, 0x00c0,
+ 0x7447, 0x25a2, 0x26a2, 0x23a2, 0x24a2, 0x0078, 0x744b, 0x23a2,
+ 0x24a2, 0x25a2, 0x26a2, 0x067f, 0x057f, 0x047f, 0x037f, 0x007c,
+ 0x20a1, 0x020b, 0x1078, 0x65f8, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d,
+ 0x007c, 0x20a1, 0x020b, 0x1078, 0x655e, 0x20a3, 0x1400, 0x20a3,
+ 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x7828, 0x20a2, 0x782c,
+ 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007, 0x20a2, 0x20a3, 0x0000,
+ 0x60c3, 0x0010, 0x1078, 0x6c2d, 0x007c, 0x20a1, 0x020b, 0x1078,
+ 0x65ef, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828, 0x20a2, 0x7810,
+ 0x20a2, 0x60c3, 0x0008, 0x1078, 0x6c2d, 0x007c, 0x147e, 0x20a1,
+ 0x020b, 0x1078, 0x7499, 0x60c3, 0x0000, 0x1078, 0x6c2d, 0x147f,
+ 0x007c, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0xd0bc, 0x0040, 0x74b6, 0x0d7e, 0xa0e8, 0xa434, 0x2d6c,
+ 0x6810, 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xa31a,
+ 0x2da6, 0x8d68, 0x2da6, 0x0d7f, 0x0078, 0x74be, 0x20a3, 0x0300,
+ 0x6298, 0x22a2, 0x20a3, 0x0000, 0x6230, 0x22a2, 0x20a3, 0x0819,
+ 0x20a3, 0x0000, 0x1078, 0x6c1c, 0x22a2, 0x20a3, 0x0000, 0x2fa2,
+ 0x7a08, 0x22a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x007c, 0x2061,
+ 0xaa00, 0x2a70, 0x7060, 0x7046, 0x704b, 0xaa00, 0x007c, 0x0e7e,
+ 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582, 0x0010,
+ 0x0048, 0x7509, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0040,
+ 0x74f5, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x74f1, 0x0078,
+ 0x74e4, 0x2061, 0xaa00, 0x0078, 0x74e4, 0x6003, 0x0008, 0x8529,
+ 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x7505, 0x754a,
+ 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00, 0x0078,
+ 0x7500, 0xa006, 0x0078, 0x7502, 0x0e7e, 0x2071, 0xa300, 0x7544,
+ 0xa582, 0x0010, 0x0048, 0x753a, 0x7048, 0x2060, 0x6000, 0xa086,
+ 0x0000, 0x0040, 0x7527, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+ 0x7523, 0x0078, 0x7516, 0x2061, 0xaa00, 0x0078, 0x7516, 0x6003,
+ 0x0008, 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8,
+ 0x7536, 0x754a, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+ 0x0078, 0x7532, 0xa006, 0x0078, 0x7534, 0xac82, 0xaa00, 0x1048,
+ 0x1328, 0x2001, 0xa315, 0x2004, 0xac02, 0x10c8, 0x1328, 0xa006,
+ 0x6006, 0x600a, 0x600e, 0x6012, 0x6016, 0x601a, 0x601f, 0x0000,
+ 0x6003, 0x0000, 0x6022, 0x6026, 0x602a, 0x602e, 0x6032, 0x6036,
+ 0x603a, 0x603e, 0x2061, 0xa300, 0x6044, 0x8000, 0x6046, 0xa086,
+ 0x0001, 0x0040, 0x7564, 0x007c, 0x127e, 0x2091, 0x8000, 0x1078,
+ 0x6109, 0x127f, 0x0078, 0x7563, 0x601c, 0xa084, 0x000f, 0x0079,
+ 0x7571, 0x757a, 0x758b, 0x75a7, 0x75c3, 0x8f2d, 0x8f49, 0x8f65,
+ 0x757a, 0x758b, 0xa186, 0x0013, 0x00c0, 0x7583, 0x1078, 0x6010,
+ 0x1078, 0x6109, 0x007c, 0xa18e, 0x0047, 0x00c0, 0x758a, 0xa016,
+ 0x1078, 0x15ec, 0x007c, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+ 0x1328, 0x1079, 0x7595, 0x067f, 0x007c, 0x75a5, 0x7891, 0x7a34,
+ 0x75a5, 0x7ab8, 0x75df, 0x75a5, 0x75a5, 0x7823, 0x7e6d, 0x75a5,
+ 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x75a5, 0x1078, 0x1328, 0x067e,
+ 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079, 0x75b1, 0x067f,
+ 0x007c, 0x75c1, 0x8522, 0x75c1, 0x75c1, 0x75c1, 0x75c1, 0x75c1,
+ 0x75c1, 0x84c5, 0x86a8, 0x75c1, 0x8552, 0x85d8, 0x8552, 0x85d8,
+ 0x75c1, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8,
+ 0x1328, 0x1079, 0x75cd, 0x067f, 0x007c, 0x75dd, 0x7eb4, 0x7f81,
+ 0x80c6, 0x8242, 0x75dd, 0x75dd, 0x75dd, 0x7e8d, 0x846d, 0x8471,
+ 0x75dd, 0x75dd, 0x75dd, 0x75dd, 0x84a1, 0x1078, 0x1328, 0xa1b6,
+ 0x0015, 0x00c0, 0x75e7, 0x1078, 0x753d, 0x0078, 0x75ed, 0xa1b6,
+ 0x0016, 0x10c0, 0x1328, 0x1078, 0x753d, 0x007c, 0x20a9, 0x000e,
+ 0x2e98, 0x6010, 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420,
+ 0x9398, 0x94a0, 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002,
+ 0xa5a8, 0x0002, 0xa398, 0x0002, 0xa4a0, 0x0002, 0x00f0, 0x75fc,
+ 0x0e7e, 0x1078, 0x8a44, 0x0040, 0x7613, 0x6010, 0x2070, 0x7007,
+ 0x0000, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c, 0x0d7e,
+ 0x037e, 0x7330, 0xa386, 0x0200, 0x00c0, 0x7624, 0x6018, 0x2068,
+ 0x6813, 0x00ff, 0x6817, 0xfffd, 0x6010, 0xa005, 0x0040, 0x762e,
+ 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6b32, 0x1078, 0x753d,
+ 0x037f, 0x0d7f, 0x007c, 0x017e, 0x20a9, 0x002a, 0xae80, 0x000c,
+ 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0, 0x53a3, 0x20a9, 0x002a,
+ 0x6010, 0xa080, 0x0001, 0x2004, 0xa080, 0x0002, 0x20a0, 0x53a3,
+ 0x0e7e, 0x6010, 0x2004, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078,
+ 0x753d, 0x017f, 0x007c, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2c68,
+ 0x017e, 0x2009, 0x0035, 0x1078, 0x8ef5, 0x017f, 0x00c0, 0x766f,
+ 0x027e, 0x6228, 0x2268, 0x027f, 0x2071, 0xa88c, 0x6b1c, 0xa386,
+ 0x0003, 0x0040, 0x7673, 0xa386, 0x0006, 0x0040, 0x7677, 0x1078,
+ 0x753d, 0x0078, 0x7679, 0x1078, 0x767c, 0x0078, 0x7679, 0x1078,
+ 0x771e, 0x0d7f, 0x0e7f, 0x007c, 0x0f7e, 0x6810, 0x2078, 0xa186,
+ 0x0015, 0x0040, 0x7705, 0xa18e, 0x0016, 0x00c0, 0x771c, 0x700c,
+ 0xa084, 0xff00, 0xa086, 0x1700, 0x00c0, 0x76e0, 0x8fff, 0x0040,
+ 0x771a, 0x6808, 0xa086, 0xffff, 0x00c0, 0x7709, 0x784c, 0xa084,
+ 0x0060, 0xa086, 0x0020, 0x00c0, 0x76a7, 0x797c, 0x7810, 0xa106,
+ 0x00c0, 0x7709, 0x7980, 0x7814, 0xa106, 0x00c0, 0x7709, 0x1078,
+ 0x8bf4, 0x6830, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4, 0x784e,
+ 0x027e, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x1078, 0x5a98, 0x7854,
+ 0xa20a, 0x0048, 0x76bc, 0x8011, 0x7a56, 0x82ff, 0x027f, 0x00c0,
+ 0x76c8, 0x0c7e, 0x2d60, 0x1078, 0x8832, 0x0c7f, 0x0078, 0x771a,
+ 0x0c7e, 0x0d7e, 0x2f68, 0x6838, 0xd0fc, 0x00c0, 0x76d3, 0x1078,
+ 0x4290, 0x0078, 0x76d5, 0x1078, 0x436e, 0x0d7f, 0x0c7f, 0x00c0,
+ 0x7709, 0x0c7e, 0x2d60, 0x1078, 0x753d, 0x0c7f, 0x0078, 0x771a,
+ 0x7008, 0xa086, 0x000b, 0x00c0, 0x76fa, 0x6018, 0x200c, 0xc1bc,
+ 0x2102, 0x0c7e, 0x2d60, 0x7853, 0x0003, 0x6007, 0x0085, 0x6003,
+ 0x000b, 0x601f, 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f,
+ 0x0078, 0x771a, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x7709, 0x2001,
+ 0xa5a2, 0x2004, 0x683e, 0x0078, 0x771a, 0x1078, 0x7739, 0x0078,
+ 0x771c, 0x8fff, 0x1040, 0x1328, 0x0c7e, 0x0d7e, 0x2d60, 0x2f68,
+ 0x684b, 0x0003, 0x1078, 0x8726, 0x1078, 0x8bf4, 0x1078, 0x8c01,
+ 0x0d7f, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0xa186, 0x0015,
+ 0x00c0, 0x7728, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x7736,
+ 0xa18e, 0x0016, 0x00c0, 0x7738, 0x0c7e, 0x2d00, 0x2060, 0x1078,
+ 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d, 0x0c7f, 0x1078, 0x753d,
+ 0x007c, 0x027e, 0x037e, 0x047e, 0x7228, 0x7c80, 0x7b7c, 0xd2f4,
+ 0x0040, 0x7748, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x0078, 0x77ac,
+ 0x0c7e, 0x2d60, 0x1078, 0x874a, 0x0c7f, 0x6804, 0xa086, 0x0050,
+ 0x00c0, 0x7760, 0x0c7e, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+ 0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x77ac,
+ 0x6800, 0xa086, 0x000f, 0x0040, 0x7782, 0x8fff, 0x1040, 0x1328,
+ 0x6824, 0xd0dc, 0x00c0, 0x7782, 0x6800, 0xa086, 0x0004, 0x00c0,
+ 0x7787, 0x784c, 0xd0ac, 0x0040, 0x7787, 0x784c, 0xc0dc, 0xc0f4,
+ 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852, 0x2001, 0x0001, 0x682e,
+ 0x0078, 0x77a6, 0x2001, 0x0007, 0x682e, 0x0078, 0x77a6, 0x784c,
+ 0xd0b4, 0x00c0, 0x7794, 0xd0ac, 0x0040, 0x7782, 0x784c, 0xd0f4,
+ 0x00c0, 0x7782, 0x0078, 0x7775, 0xd2ec, 0x00c0, 0x7782, 0x7024,
+ 0xa306, 0x00c0, 0x779f, 0x7020, 0xa406, 0x0040, 0x7782, 0x7020,
+ 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e, 0x1078, 0x8d2b,
+ 0x1078, 0x6109, 0x0078, 0x77ae, 0x1078, 0x753d, 0x047f, 0x037f,
+ 0x027f, 0x007c, 0x0e7e, 0x0d7e, 0x027e, 0x6034, 0x2068, 0x6a1c,
+ 0xa286, 0x0007, 0x0040, 0x7806, 0xa286, 0x0002, 0x0040, 0x7806,
+ 0xa286, 0x0000, 0x0040, 0x7806, 0x6808, 0x6338, 0xa306, 0x00c0,
+ 0x7806, 0x2071, 0xa88c, 0xa186, 0x0015, 0x0040, 0x7800, 0xa18e,
+ 0x0016, 0x00c0, 0x77e8, 0x6030, 0xa084, 0x00ff, 0xa086, 0x0001,
+ 0x00c0, 0x77e8, 0x700c, 0xa086, 0x2a00, 0x00c0, 0x77e8, 0x6034,
+ 0xa080, 0x0009, 0x200c, 0xc1dd, 0xc1f5, 0x2102, 0x0078, 0x7800,
+ 0x0c7e, 0x6034, 0x2060, 0x6010, 0x2068, 0x1078, 0x8a44, 0x1040,
+ 0x1328, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+ 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7f, 0x0078, 0x7806,
+ 0x6034, 0x2068, 0x2001, 0xa5a2, 0x2004, 0x683e, 0x1078, 0x753d,
+ 0x027f, 0x0d7f, 0x0e7f, 0x007c, 0x0d7e, 0x20a9, 0x000e, 0x2e98,
+ 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x00c0, 0x7820, 0x6018,
+ 0x2068, 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802,
+ 0x0d7f, 0x0078, 0x7608, 0x2100, 0xa1b2, 0x0044, 0x10c8, 0x1328,
+ 0xa1b2, 0x0040, 0x00c8, 0x7888, 0x0079, 0x782e, 0x787c, 0x7870,
+ 0x787c, 0x787c, 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e,
+ 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+ 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+ 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x787c,
+ 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x787c, 0x786e,
+ 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+ 0x787c, 0x787c, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e, 0x786e,
+ 0x786e, 0x786e, 0x786e, 0x787c, 0x786e, 0x786e, 0x1078, 0x1328,
+ 0x6003, 0x0001, 0x6106, 0x1078, 0x5c45, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078,
+ 0x5c45, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c,
+ 0x2600, 0x0079, 0x788b, 0x788f, 0x788f, 0x788f, 0x787c, 0x1078,
+ 0x1328, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328, 0xa1b6, 0x0013,
+ 0x00c0, 0x78a1, 0xa0b2, 0x0040, 0x00c8, 0x79fb, 0x2008, 0x0079,
+ 0x7941, 0xa1b6, 0x0027, 0x00c0, 0x78fe, 0x1078, 0x6010, 0x6004,
+ 0x1078, 0x8c27, 0x0040, 0x78be, 0x1078, 0x8c3b, 0x0040, 0x78f6,
+ 0xa08e, 0x0021, 0x0040, 0x78fa, 0xa08e, 0x0022, 0x0040, 0x78f6,
+ 0xa08e, 0x003d, 0x0040, 0x78fa, 0x0078, 0x78f1, 0x1078, 0x2839,
+ 0x2001, 0x0007, 0x1078, 0x443f, 0x6018, 0xa080, 0x0028, 0x200c,
+ 0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x78d3, 0x2001, 0xa332,
+ 0x2014, 0xc285, 0x2202, 0x017e, 0x027e, 0x037e, 0x2110, 0x2019,
+ 0x0028, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078, 0x5c78,
+ 0x0c7e, 0x6018, 0xa065, 0x0040, 0x78e7, 0x1078, 0x471b, 0x0c7f,
+ 0x2c08, 0x1078, 0x9c38, 0x077f, 0x037f, 0x027f, 0x017f, 0x1078,
+ 0x44bc, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x7a05,
+ 0x0078, 0x78f1, 0x1078, 0x7a28, 0x0078, 0x78f1, 0xa186, 0x0014,
+ 0x00c0, 0x78f5, 0x1078, 0x6010, 0x1078, 0x2813, 0x1078, 0x8c27,
+ 0x00c0, 0x791d, 0x1078, 0x2839, 0x6018, 0xa080, 0x0028, 0x200c,
+ 0x1078, 0x7a05, 0xa186, 0x007e, 0x00c0, 0x791b, 0x2001, 0xa332,
+ 0x200c, 0xc185, 0x2102, 0x0078, 0x78f1, 0x1078, 0x8c3b, 0x00c0,
+ 0x7925, 0x1078, 0x7a05, 0x0078, 0x78f1, 0x6004, 0xa08e, 0x0032,
+ 0x00c0, 0x7936, 0x0e7e, 0x0f7e, 0x2071, 0xa381, 0x2079, 0x0000,
+ 0x1078, 0x2b56, 0x0f7f, 0x0e7f, 0x0078, 0x78f1, 0x6004, 0xa08e,
+ 0x0021, 0x0040, 0x7921, 0xa08e, 0x0022, 0x1040, 0x7a05, 0x0078,
+ 0x78f1, 0x7983, 0x7985, 0x7989, 0x798d, 0x7991, 0x7995, 0x7981,
+ 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+ 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+ 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981, 0x7999,
+ 0x79ab, 0x7981, 0x79ad, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981,
+ 0x7981, 0x79ab, 0x79ab, 0x7981, 0x7981, 0x7981, 0x7981, 0x7981,
+ 0x7981, 0x7981, 0x7981, 0x79de, 0x79ab, 0x7981, 0x79a5, 0x7981,
+ 0x7981, 0x7981, 0x79a7, 0x7981, 0x7981, 0x7981, 0x79ab, 0x7981,
+ 0x7981, 0x1078, 0x1328, 0x0078, 0x79ab, 0x2001, 0x000b, 0x0078,
+ 0x79b8, 0x2001, 0x0003, 0x0078, 0x79b8, 0x2001, 0x0005, 0x0078,
+ 0x79b8, 0x2001, 0x0001, 0x0078, 0x79b8, 0x2001, 0x0009, 0x0078,
+ 0x79b8, 0x1078, 0x6010, 0x6003, 0x0005, 0x2001, 0xa5a2, 0x2004,
+ 0x603e, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0078, 0x79ab, 0x0078,
+ 0x79ab, 0x1078, 0x443f, 0x0078, 0x79f0, 0x1078, 0x6010, 0x6003,
+ 0x0004, 0x2001, 0xa5a0, 0x2004, 0x6016, 0x1078, 0x6109, 0x007c,
+ 0x1078, 0x443f, 0x1078, 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e,
+ 0x6003, 0x0002, 0x037e, 0x2019, 0xa35c, 0x2304, 0xa084, 0xff00,
+ 0x00c0, 0x79cf, 0x2019, 0xa5a0, 0x231c, 0x0078, 0x79d8, 0x8007,
+ 0xa09a, 0x0004, 0x0048, 0x79ca, 0x8003, 0x801b, 0x831b, 0xa318,
+ 0x6316, 0x037f, 0x1078, 0x6109, 0x0078, 0x79b7, 0x0e7e, 0x0f7e,
+ 0x2071, 0xa381, 0x2079, 0x0000, 0x1078, 0x2b56, 0x0f7f, 0x0e7f,
+ 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x0078, 0x79b7,
+ 0x1078, 0x6010, 0x6003, 0x0002, 0x2001, 0xa5a0, 0x2004, 0x6016,
+ 0x1078, 0x6109, 0x007c, 0x2600, 0x2008, 0x0079, 0x79ff, 0x7a03,
+ 0x7a03, 0x7a03, 0x79f0, 0x1078, 0x1328, 0x0e7e, 0x1078, 0x8a44,
+ 0x0040, 0x7a21, 0x6010, 0x2070, 0x7038, 0xd0fc, 0x0040, 0x7a21,
+ 0x7007, 0x0000, 0x017e, 0x6004, 0xa08e, 0x0021, 0x0040, 0x7a23,
+ 0xa08e, 0x003d, 0x0040, 0x7a23, 0x017f, 0x7037, 0x0103, 0x7033,
+ 0x0100, 0x0e7f, 0x007c, 0x017f, 0x1078, 0x7a28, 0x0078, 0x7a21,
+ 0x0e7e, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103,
+ 0x7023, 0x8001, 0x0e7f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804,
+ 0xa084, 0x00ff, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0x6604,
+ 0xa6b6, 0x0043, 0x00c0, 0x7a48, 0x1078, 0x8e6d, 0x0078, 0x7aa7,
+ 0x6604, 0xa6b6, 0x0033, 0x00c0, 0x7a51, 0x1078, 0x8e11, 0x0078,
+ 0x7aa7, 0x6604, 0xa6b6, 0x0028, 0x00c0, 0x7a5a, 0x1078, 0x8c6a,
+ 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0029, 0x00c0, 0x7a63, 0x1078,
+ 0x8c84, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x001f, 0x00c0, 0x7a6c,
+ 0x1078, 0x75ee, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0000, 0x00c0,
+ 0x7a75, 0x1078, 0x780c, 0x0078, 0x7aa7, 0x6604, 0xa6b6, 0x0022,
+ 0x00c0, 0x7a7e, 0x1078, 0x7617, 0x0078, 0x7aa7, 0x6604, 0xa6b6,
+ 0x0035, 0x00c0, 0x7a87, 0x1078, 0x7653, 0x0078, 0x7aa7, 0x6604,
+ 0xa6b6, 0x0039, 0x00c0, 0x7a90, 0x1078, 0x77b2, 0x0078, 0x7aa7,
+ 0x6604, 0xa6b6, 0x003d, 0x00c0, 0x7a99, 0x1078, 0x7633, 0x0078,
+ 0x7aa7, 0xa1b6, 0x0015, 0x00c0, 0x7aa1, 0x1079, 0x7aac, 0x0078,
+ 0x7aa7, 0xa1b6, 0x0016, 0x00c0, 0x7aa8, 0x1079, 0x7bfd, 0x007c,
+ 0x1078, 0x7583, 0x0078, 0x7aa7, 0x7ad0, 0x7ad3, 0x7ad0, 0x7b1e,
+ 0x7ad0, 0x7b91, 0x7c09, 0x7ad0, 0x7ad0, 0x7bd5, 0x7ad0, 0x7beb,
+ 0xa1b6, 0x0048, 0x0040, 0x7ac4, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+ 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0e7e, 0xacf0, 0x0004, 0x2e74,
+ 0x7000, 0x2070, 0x7037, 0x0103, 0x0e7f, 0x1078, 0x753d, 0x007c,
+ 0x0005, 0x0005, 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086,
+ 0x0074, 0x00c0, 0x7b07, 0x1078, 0x9c0c, 0x00c0, 0x7af9, 0x0d7e,
+ 0x6018, 0x2068, 0x7030, 0xd08c, 0x0040, 0x7aec, 0x6800, 0xd0bc,
+ 0x0040, 0x7aec, 0xc0c5, 0x6802, 0x1078, 0x7b0b, 0x0d7f, 0x2001,
+ 0x0006, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078,
+ 0x7b09, 0x2001, 0x000a, 0x1078, 0x443f, 0x1078, 0x2839, 0x6003,
+ 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7b09, 0x1078,
+ 0x7b81, 0x0e7f, 0x007c, 0x6800, 0xd084, 0x0040, 0x7b1d, 0x2001,
+ 0x0000, 0x1078, 0x442b, 0x2069, 0xa351, 0x6804, 0xd0a4, 0x0040,
+ 0x7b1d, 0x2001, 0x0006, 0x1078, 0x4472, 0x007c, 0x0d7e, 0x2011,
+ 0xa31f, 0x2204, 0xa086, 0x0074, 0x00c0, 0x7b7d, 0x6018, 0x2068,
+ 0x6aa0, 0xa286, 0x007e, 0x00c0, 0x7b31, 0x1078, 0x7d17, 0x0078,
+ 0x7b7f, 0x1078, 0x7d0d, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014,
+ 0xa286, 0x0080, 0x00c0, 0x7b55, 0x6813, 0x00ff, 0x6817, 0xfffc,
+ 0x6010, 0xa005, 0x0040, 0x7b4b, 0x2068, 0x6807, 0x0000, 0x6837,
+ 0x0103, 0x6833, 0x0200, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+ 0x2839, 0x1078, 0x753d, 0x0078, 0x7b7f, 0x0e7e, 0x2071, 0xa332,
+ 0x2e04, 0xd09c, 0x0040, 0x7b70, 0x2071, 0xa880, 0x7108, 0x720c,
+ 0xa18c, 0x00ff, 0x00c0, 0x7b68, 0xa284, 0xff00, 0x0040, 0x7b70,
+ 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x00c0, 0x7b70, 0x7112, 0x7216,
+ 0x0e7f, 0x2001, 0x0004, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+ 0x0003, 0x1078, 0x5c45, 0x0078, 0x7b7f, 0x1078, 0x7b81, 0x0d7f,
+ 0x007c, 0x2001, 0xa300, 0x2004, 0xa086, 0x0003, 0x0040, 0x7b8c,
+ 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x2839, 0x1078, 0x753d,
+ 0x007c, 0x0e7e, 0x2071, 0xa300, 0x707c, 0xa086, 0x0014, 0x00c0,
+ 0x7bcf, 0x7000, 0xa086, 0x0003, 0x00c0, 0x7ba4, 0x6010, 0xa005,
+ 0x00c0, 0x7ba4, 0x1078, 0x35f7, 0x0d7e, 0x6018, 0x2068, 0x1078,
+ 0x457d, 0x1078, 0x7b0b, 0x0d7f, 0x1078, 0x7dba, 0x00c0, 0x7bcf,
+ 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f, 0xa005, 0x0040, 0x7bcf,
+ 0x2001, 0x0006, 0x1078, 0x443f, 0x0e7e, 0x6010, 0xa005, 0x0040,
+ 0x7bc8, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103, 0x7033, 0x0200,
+ 0x0e7f, 0x1078, 0x2839, 0x1078, 0x753d, 0x0078, 0x7bd3, 0x1078,
+ 0x7a05, 0x1078, 0x7b81, 0x0e7f, 0x007c, 0x2011, 0xa31f, 0x2204,
+ 0xa086, 0x0014, 0x00c0, 0x7be8, 0x2001, 0x0002, 0x1078, 0x443f,
+ 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7bea,
+ 0x1078, 0x7b81, 0x007c, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0004,
+ 0x00c0, 0x7bfa, 0x2001, 0x0007, 0x1078, 0x443f, 0x1078, 0x753d,
+ 0x0078, 0x7bfc, 0x1078, 0x7b81, 0x007c, 0x7ad0, 0x7c11, 0x7ad0,
+ 0x7c4e, 0x7ad0, 0x7cc0, 0x7c09, 0x7ad0, 0x7ad0, 0x7cd5, 0x7ad0,
+ 0x7ce8, 0x6604, 0xa6b6, 0x001e, 0x00c0, 0x7c10, 0x1078, 0x753d,
+ 0x007c, 0x0d7e, 0x0c7e, 0x1078, 0x7cfb, 0x00c0, 0x7c27, 0x2001,
+ 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x0078, 0x7c4b, 0x2009,
+ 0xa88e, 0x2104, 0xa086, 0x0009, 0x00c0, 0x7c3c, 0x6018, 0x2068,
+ 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x7c49, 0x8001, 0x6842,
+ 0x6017, 0x000a, 0x0078, 0x7c4b, 0x2009, 0xa88f, 0x2104, 0xa084,
+ 0xff00, 0xa086, 0x1900, 0x00c0, 0x7c49, 0x1078, 0x753d, 0x0078,
+ 0x7c4b, 0x1078, 0x7b81, 0x0c7f, 0x0d7f, 0x007c, 0x1078, 0x7d0a,
+ 0x00c0, 0x7c62, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002,
+ 0x1078, 0x443f, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45,
+ 0x0078, 0x7c8e, 0x1078, 0x7a05, 0x2009, 0xa88e, 0x2134, 0xa6b4,
+ 0x00ff, 0xa686, 0x0005, 0x0040, 0x7c8f, 0xa686, 0x000b, 0x0040,
+ 0x7c8c, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0x00c0, 0x7c7c,
+ 0xa686, 0x0009, 0x0040, 0x7c8f, 0xa086, 0x1900, 0x00c0, 0x7c8c,
+ 0xa686, 0x0009, 0x0040, 0x7c8f, 0x2001, 0x0004, 0x1078, 0x443f,
+ 0x1078, 0x753d, 0x0078, 0x7c8e, 0x1078, 0x7b81, 0x007c, 0x0d7e,
+ 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x7c9d, 0x6838, 0xd0fc,
+ 0x0040, 0x7c9d, 0x0d7f, 0x0078, 0x7c8c, 0x6018, 0x2068, 0x6840,
+ 0xa084, 0x00ff, 0xa005, 0x0040, 0x7cae, 0x8001, 0x6842, 0x6017,
+ 0x000a, 0x6007, 0x0016, 0x0d7f, 0x0078, 0x7c8e, 0x68a0, 0xa086,
+ 0x007e, 0x00c0, 0x7cbb, 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5,
+ 0x0e7f, 0x0078, 0x7cbd, 0x1078, 0x2813, 0x0d7f, 0x0078, 0x7c8c,
+ 0x1078, 0x7d0a, 0x00c0, 0x7cd0, 0x2001, 0x0004, 0x1078, 0x443f,
+ 0x6003, 0x0001, 0x6007, 0x0003, 0x1078, 0x5c45, 0x0078, 0x7cd4,
+ 0x1078, 0x7a05, 0x1078, 0x7b81, 0x007c, 0x1078, 0x7d0a, 0x00c0,
+ 0x7ce5, 0x2001, 0x0008, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+ 0x0005, 0x1078, 0x5c45, 0x0078, 0x7ce7, 0x1078, 0x7b81, 0x007c,
+ 0x1078, 0x7d0a, 0x00c0, 0x7cf8, 0x2001, 0x000a, 0x1078, 0x443f,
+ 0x6003, 0x0001, 0x6007, 0x0001, 0x1078, 0x5c45, 0x0078, 0x7cfa,
+ 0x1078, 0x7b81, 0x007c, 0x2009, 0xa88e, 0x2104, 0xa086, 0x0003,
+ 0x00c0, 0x7d09, 0x2009, 0xa88f, 0x2104, 0xa084, 0xff00, 0xa086,
+ 0x2a00, 0x007c, 0xa085, 0x0001, 0x007c, 0x0c7e, 0x017e, 0xac88,
+ 0x0006, 0x2164, 0x1078, 0x4513, 0x017f, 0x0c7f, 0x007c, 0x0f7e,
+ 0x0e7e, 0x0d7e, 0x037e, 0x017e, 0x6018, 0x2068, 0x2071, 0xa332,
+ 0x2e04, 0xa085, 0x0003, 0x2072, 0x1078, 0x7d8b, 0x0040, 0x7d50,
+ 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x7d39, 0xa006, 0x2020,
+ 0x2009, 0x002a, 0x1078, 0x9ec0, 0x2001, 0xa30c, 0x200c, 0xc195,
+ 0x2102, 0x2019, 0x002a, 0x2009, 0x0001, 0x1078, 0x27e2, 0x2071,
+ 0xa300, 0x1078, 0x260d, 0x0c7e, 0x157e, 0x20a9, 0x0081, 0x2009,
+ 0x007f, 0x1078, 0x2921, 0x8108, 0x00f0, 0x7d49, 0x157f, 0x0c7f,
+ 0x1078, 0x7d0d, 0x6813, 0x00ff, 0x6817, 0xfffe, 0x2071, 0xa880,
+ 0x2079, 0x0100, 0x2e04, 0xa084, 0x00ff, 0x2069, 0xa31a, 0x206a,
+ 0x78e6, 0x007e, 0x8e70, 0x2e04, 0x2069, 0xa31b, 0x206a, 0x78ea,
+ 0xa084, 0xff00, 0x017f, 0xa105, 0x2009, 0xa325, 0x200a, 0x2069,
+ 0xa88e, 0x2071, 0xa59c, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+ 0x700a, 0x681c, 0x700e, 0x1078, 0x8da9, 0x2001, 0x0006, 0x1078,
+ 0x443f, 0x1078, 0x2839, 0x1078, 0x753d, 0x017f, 0x037f, 0x0d7f,
+ 0x0e7f, 0x0f7f, 0x007c, 0x027e, 0x037e, 0x0e7e, 0x157e, 0x2019,
+ 0xa325, 0x231c, 0x83ff, 0x0040, 0x7db5, 0x2071, 0xa880, 0x2e14,
+ 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x00c0,
+ 0x7db5, 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078,
+ 0x7e55, 0x00c0, 0x7db5, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9,
+ 0x0004, 0x1078, 0x7e55, 0x00c0, 0x7db5, 0x157f, 0x0e7f, 0x037f,
+ 0x027f, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7004, 0xa086, 0x0014,
+ 0x00c0, 0x7ddd, 0x7008, 0xa086, 0x0800, 0x00c0, 0x7ddd, 0x700c,
+ 0xd0ec, 0x0040, 0x7ddb, 0xa084, 0x0f00, 0xa086, 0x0100, 0x00c0,
+ 0x7ddb, 0x7024, 0xd0a4, 0x00c0, 0x7dd8, 0xd0ac, 0x0040, 0x7ddb,
+ 0xa006, 0x0078, 0x7ddd, 0xa085, 0x0001, 0x0e7f, 0x007c, 0x0e7e,
+ 0x0d7e, 0x0c7e, 0x077e, 0x057e, 0x047e, 0x027e, 0x007e, 0x127e,
+ 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba, 0x2424,
+ 0x2061, 0xaa00, 0x2071, 0xa300, 0x7244, 0x7060, 0xa202, 0x00c8,
+ 0x7e43, 0x1078, 0x9ee5, 0x0040, 0x7e3b, 0x671c, 0xa786, 0x0001,
+ 0x0040, 0x7e3b, 0xa786, 0x0007, 0x0040, 0x7e3b, 0x2500, 0xac06,
+ 0x0040, 0x7e3b, 0x2400, 0xac06, 0x0040, 0x7e3b, 0x0c7e, 0x6000,
+ 0xa086, 0x0004, 0x00c0, 0x7e16, 0x1078, 0x1749, 0xa786, 0x0008,
+ 0x00c0, 0x7e25, 0x1078, 0x8c3b, 0x00c0, 0x7e25, 0x0c7f, 0x1078,
+ 0x7a05, 0x1078, 0x8c01, 0x0078, 0x7e3b, 0x6010, 0x2068, 0x1078,
+ 0x8a44, 0x0040, 0x7e38, 0xa786, 0x0003, 0x00c0, 0x7e4d, 0x6837,
+ 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4,
+ 0x1078, 0x8c01, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+ 0x7e43, 0x0078, 0x7df4, 0x127f, 0x007f, 0x027f, 0x047f, 0x057f,
+ 0x077f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+ 0x7e2f, 0x1078, 0x9e70, 0x0078, 0x7e38, 0x220c, 0x2304, 0xa106,
+ 0x00c0, 0x7e60, 0x8210, 0x8318, 0x00f0, 0x7e55, 0xa006, 0x007c,
+ 0x2304, 0xa102, 0x0048, 0x7e68, 0x2001, 0x0001, 0x0078, 0x7e6a,
+ 0x2001, 0x0000, 0xa18d, 0x0001, 0x007c, 0x6004, 0xa08a, 0x0044,
+ 0x10c8, 0x1328, 0x1078, 0x8c27, 0x0040, 0x7e7c, 0x1078, 0x8c3b,
+ 0x0040, 0x7e89, 0x0078, 0x7e82, 0x1078, 0x2839, 0x1078, 0x8c3b,
+ 0x0040, 0x7e89, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+ 0x007c, 0x1078, 0x7a05, 0x0078, 0x7e82, 0xa182, 0x0040, 0x0079,
+ 0x7e91, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4,
+ 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x7ea6, 0x7ea6, 0x7ea6,
+ 0x7ea4, 0x7ea4, 0x7ea4, 0x7ea6, 0x1078, 0x1328, 0x600b, 0xffff,
+ 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000,
+ 0x1078, 0x6109, 0x127f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x7ebd,
+ 0x6004, 0xa082, 0x0040, 0x0079, 0x7f48, 0xa186, 0x0027, 0x00c0,
+ 0x7edf, 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168,
+ 0x1078, 0x8a44, 0x0040, 0x7ed9, 0x6837, 0x0103, 0x684b, 0x0029,
+ 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e, 0x1078, 0x4982, 0x1078,
+ 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0xa186,
+ 0x0014, 0x00c0, 0x7ee8, 0x6004, 0xa082, 0x0040, 0x0079, 0x7f10,
+ 0xa186, 0x0046, 0x0040, 0x7ef4, 0xa186, 0x0045, 0x0040, 0x7ef4,
+ 0xa186, 0x0047, 0x10c0, 0x1328, 0x2001, 0x0109, 0x2004, 0xd084,
+ 0x0040, 0x7f0d, 0x127e, 0x2091, 0x2200, 0x007e, 0x017e, 0x027e,
+ 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f, 0x6000, 0xa086,
+ 0x0002, 0x00c0, 0x7f0d, 0x0078, 0x7f81, 0x1078, 0x7583, 0x007c,
+ 0x7f25, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23, 0x7f23,
+ 0x7f23, 0x7f23, 0x7f23, 0x7f41, 0x7f41, 0x7f41, 0x7f41, 0x7f23,
+ 0x7f41, 0x7f23, 0x7f41, 0x1078, 0x1328, 0x1078, 0x6010, 0x0d7e,
+ 0x6110, 0x2168, 0x1078, 0x8a44, 0x0040, 0x7f3b, 0x6837, 0x0103,
+ 0x684b, 0x0006, 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x1078,
+ 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109,
+ 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109, 0x007c,
+ 0x7f5d, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b, 0x7f5b,
+ 0x7f5b, 0x7f5b, 0x7f5b, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f6f, 0x7f5b,
+ 0x7f7a, 0x7f5b, 0x7f6f, 0x1078, 0x1328, 0x1078, 0x6010, 0x2001,
+ 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x6109, 0x6010,
+ 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x007c, 0x1078,
+ 0x6010, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x000f, 0x1078,
+ 0x6109, 0x007c, 0x1078, 0x6010, 0x1078, 0x753d, 0x1078, 0x6109,
+ 0x007c, 0xa182, 0x0040, 0x0079, 0x7f85, 0x7f98, 0x7f98, 0x7f98,
+ 0x7f98, 0x7f98, 0x7f9a, 0x8095, 0x80b7, 0x7f98, 0x7f98, 0x7f98,
+ 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98, 0x7f98,
+ 0x1078, 0x1328, 0x0e7e, 0x0d7e, 0x603f, 0x0000, 0x2071, 0xa880,
+ 0x7124, 0x610a, 0x2071, 0xa88c, 0x6110, 0x2168, 0x7614, 0xa6b4,
+ 0x0fff, 0x86ff, 0x0040, 0x8058, 0xa68c, 0x0c00, 0x0040, 0x7fd1,
+ 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x7fcd, 0x684c,
+ 0xd0ac, 0x0040, 0x7fcd, 0x6024, 0xd0dc, 0x00c0, 0x7fcd, 0x6850,
+ 0xd0bc, 0x00c0, 0x7fcd, 0x7318, 0x6814, 0xa306, 0x00c0, 0x806f,
+ 0x731c, 0x6810, 0xa306, 0x00c0, 0x806f, 0x7318, 0x6b62, 0x731c,
+ 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x8004, 0xa186,
+ 0x0028, 0x00c0, 0x7fe1, 0x1078, 0x8c15, 0x684b, 0x001c, 0x0078,
+ 0x8006, 0xd6dc, 0x0040, 0x7ffd, 0x684b, 0x0015, 0x684c, 0xd0ac,
+ 0x0040, 0x7ffb, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040, 0x7ffb,
+ 0x7018, 0xa106, 0x00c0, 0x7ff8, 0x701c, 0xa206, 0x0040, 0x7ffb,
+ 0x6962, 0x6a5e, 0xc6dc, 0x0078, 0x8006, 0xd6d4, 0x0040, 0x8004,
+ 0x684b, 0x0007, 0x0078, 0x8006, 0x684b, 0x0000, 0x6837, 0x0103,
+ 0x6e46, 0xa01e, 0xd6c4, 0x0040, 0x802f, 0xa686, 0x0100, 0x00c0,
+ 0x801a, 0x2001, 0xa899, 0x2004, 0xa005, 0x00c0, 0x801a, 0xc6c4,
+ 0x0078, 0x7fa9, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x802f,
+ 0xa38a, 0x0009, 0x0048, 0x8026, 0x2019, 0x0008, 0x037e, 0x2308,
+ 0x2019, 0xa898, 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc,
+ 0x0040, 0x8085, 0x7124, 0x695a, 0x81ff, 0x0040, 0x8085, 0xa192,
+ 0x0021, 0x00c8, 0x8046, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18,
+ 0xad90, 0x001d, 0x1078, 0x8739, 0x0078, 0x8085, 0x6838, 0xd0fc,
+ 0x0040, 0x804f, 0x2009, 0x0020, 0x695a, 0x0078, 0x803b, 0x0f7e,
+ 0x2d78, 0x1078, 0x86d1, 0x0f7f, 0x1078, 0x8726, 0x0078, 0x8087,
+ 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8075, 0x684c,
+ 0xd0ac, 0x0040, 0x8075, 0x6024, 0xd0dc, 0x00c0, 0x8075, 0x6850,
+ 0xd0bc, 0x00c0, 0x8075, 0x684c, 0xd0f4, 0x00c0, 0x8075, 0x1078,
+ 0x8cfa, 0x0d7f, 0x0e7f, 0x0078, 0x8094, 0x684b, 0x0000, 0x6837,
+ 0x0103, 0x6e46, 0x684c, 0xd0ac, 0x0040, 0x8085, 0x6810, 0x6914,
+ 0xa115, 0x0040, 0x8085, 0x1078, 0x8233, 0x1078, 0x4982, 0x6218,
+ 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x1078, 0x8cc4, 0x0d7f, 0x0e7f,
+ 0x00c0, 0x8094, 0x1078, 0x753d, 0x007c, 0x0f7e, 0x6003, 0x0003,
+ 0x2079, 0xa88c, 0x7c04, 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078,
+ 0x784c, 0xd0ac, 0x0040, 0x80a8, 0x6003, 0x0002, 0x0f7f, 0x007c,
+ 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x0f7f, 0x603f, 0x0000, 0x2c10,
+ 0x1078, 0x1cab, 0x1078, 0x5c64, 0x1078, 0x61d3, 0x007c, 0x2001,
+ 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110, 0x20e1, 0x0005,
+ 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0xa182, 0x0040,
+ 0x0079, 0x80ca, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80dd, 0x80df,
+ 0x8182, 0x80dd, 0x80dd, 0x8198, 0x8209, 0x80dd, 0x80dd, 0x80dd,
+ 0x80dd, 0x8218, 0x80dd, 0x80dd, 0x80dd, 0x1078, 0x1328, 0x077e,
+ 0x0f7e, 0x0e7e, 0x0d7e, 0x2071, 0xa88c, 0x6110, 0x2178, 0x7614,
+ 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218, 0x2268,
+ 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0040, 0x817d, 0xa694, 0xff00,
+ 0xa284, 0x0c00, 0x0040, 0x8100, 0x7018, 0x7862, 0x701c, 0x785e,
+ 0xa284, 0x0300, 0x0040, 0x817d, 0x1078, 0x1381, 0x1040, 0x1328,
+ 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+ 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+ 0x0040, 0x811e, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff,
+ 0xa186, 0x0002, 0x0040, 0x813a, 0xa186, 0x0028, 0x00c0, 0x812c,
+ 0x684b, 0x001c, 0x0078, 0x813c, 0xd6dc, 0x0040, 0x8133, 0x684b,
+ 0x0015, 0x0078, 0x813c, 0xd6d4, 0x0040, 0x813a, 0x684b, 0x0007,
+ 0x0078, 0x813c, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+ 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x815a, 0x7328, 0x732c, 0x6b56,
+ 0x83ff, 0x0040, 0x815a, 0xa38a, 0x0009, 0x0048, 0x8151, 0x2019,
+ 0x0008, 0x037e, 0x2308, 0x2019, 0xa898, 0xad90, 0x0019, 0x1078,
+ 0x8739, 0x037f, 0xd6cc, 0x0040, 0x817d, 0x7124, 0x695a, 0x81ff,
+ 0x0040, 0x817d, 0xa192, 0x0021, 0x00c8, 0x8171, 0x2071, 0xa898,
+ 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x1078, 0x8739, 0x0078,
+ 0x817d, 0x7838, 0xd0fc, 0x0040, 0x817a, 0x2009, 0x0020, 0x695a,
+ 0x0078, 0x8166, 0x2d78, 0x1078, 0x86d1, 0x0d7f, 0x0e7f, 0x0f7f,
+ 0x077f, 0x007c, 0x0f7e, 0x6003, 0x0003, 0x2079, 0xa88c, 0x7c04,
+ 0x7b00, 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a,
+ 0x7d0e, 0x0f7f, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x6c26, 0x007c,
+ 0x0d7e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x81a4,
+ 0x2001, 0xa5a2, 0x2004, 0x603e, 0x6003, 0x0002, 0x1078, 0x60b8,
+ 0x1078, 0x61d3, 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0040, 0x8207,
+ 0xd1cc, 0x0040, 0x81de, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x81d6,
+ 0x017e, 0x684c, 0x007e, 0x6850, 0x007e, 0xad90, 0x000d, 0xa198,
+ 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8, 0x2304, 0x2012, 0x8318,
+ 0x8210, 0x00f0, 0x81c5, 0x157f, 0x007f, 0x6852, 0x007f, 0x684e,
+ 0x017f, 0x2168, 0x1078, 0x13aa, 0x0078, 0x8201, 0x017e, 0x1078,
+ 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8201, 0x6837, 0x0103,
+ 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040, 0x81fd, 0xa086,
+ 0x0028, 0x00c0, 0x81ef, 0x684b, 0x001c, 0x0078, 0x81ff, 0xd1dc,
+ 0x0040, 0x81f6, 0x684b, 0x0015, 0x0078, 0x81ff, 0xd1d4, 0x0040,
+ 0x81fd, 0x684b, 0x0007, 0x0078, 0x81ff, 0x684b, 0x0000, 0x1078,
+ 0x4982, 0x1078, 0x8cc4, 0x00c0, 0x8207, 0x1078, 0x753d, 0x0d7f,
+ 0x007c, 0x2019, 0x0001, 0x1078, 0x6e6c, 0x6003, 0x0002, 0x2001,
+ 0xa5a2, 0x2004, 0x603e, 0x1078, 0x60b8, 0x1078, 0x61d3, 0x007c,
+ 0x1078, 0x60b8, 0x1078, 0x2813, 0x0d7e, 0x6110, 0x2168, 0x1078,
+ 0x8a44, 0x0040, 0x822d, 0x6837, 0x0103, 0x684b, 0x0029, 0x6847,
+ 0x0000, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+ 0x1078, 0x61d3, 0x007c, 0x684b, 0x0015, 0xd1fc, 0x0040, 0x823f,
+ 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+ 0x685e, 0x007c, 0xa182, 0x0040, 0x0079, 0x8246, 0x8259, 0x8259,
+ 0x8259, 0x8259, 0x8259, 0x825b, 0x8259, 0x8333, 0x833f, 0x8259,
+ 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259, 0x8259,
+ 0x8259, 0x1078, 0x1328, 0x077e, 0x0f7e, 0x0e7e, 0x0d7e, 0x2071,
+ 0xa88c, 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x0f7e, 0x2c78,
+ 0x1078, 0x4893, 0x0f7f, 0x0040, 0x827e, 0xa684, 0x00ff, 0x00c0,
+ 0x827e, 0x6024, 0xd0f4, 0x00c0, 0x827a, 0x7808, 0xa086, 0x0000,
+ 0x00c0, 0x827e, 0x1078, 0x8cfa, 0x0078, 0x832e, 0x7e46, 0x7f4c,
+ 0xc7e5, 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff,
+ 0x0040, 0x8323, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0040, 0x8294,
+ 0x7018, 0x7862, 0x701c, 0x785e, 0xa284, 0x0300, 0x0040, 0x8320,
+ 0xa686, 0x0100, 0x00c0, 0x82a6, 0x2001, 0xa899, 0x2004, 0xa005,
+ 0x00c0, 0x82a6, 0xc6c4, 0x7e46, 0x0078, 0x8287, 0x1078, 0x1381,
+ 0x1040, 0x1328, 0x2d00, 0x784a, 0x7f4c, 0xa7bd, 0x0200, 0x7f4e,
+ 0x6837, 0x0103, 0x7838, 0x683a, 0x783c, 0x683e, 0x7840, 0x6842,
+ 0x6e46, 0xa68c, 0x0c00, 0x0040, 0x82c1, 0x7318, 0x6b62, 0x731c,
+ 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0040, 0x82dd, 0xa186,
+ 0x0028, 0x00c0, 0x82cf, 0x684b, 0x001c, 0x0078, 0x82df, 0xd6dc,
+ 0x0040, 0x82d6, 0x684b, 0x0015, 0x0078, 0x82df, 0xd6d4, 0x0040,
+ 0x82dd, 0x684b, 0x0007, 0x0078, 0x82df, 0x684b, 0x0000, 0x6f4e,
+ 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e, 0xd6c4, 0x0040, 0x82fd,
+ 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0040, 0x82fd, 0xa38a, 0x0009,
+ 0x0048, 0x82f4, 0x2019, 0x0008, 0x037e, 0x2308, 0x2019, 0xa898,
+ 0xad90, 0x0019, 0x1078, 0x8739, 0x037f, 0xd6cc, 0x0040, 0x8320,
+ 0x7124, 0x695a, 0x81ff, 0x0040, 0x8320, 0xa192, 0x0021, 0x00c8,
+ 0x8314, 0x2071, 0xa898, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d,
+ 0x1078, 0x8739, 0x0078, 0x8320, 0x7838, 0xd0fc, 0x0040, 0x831d,
+ 0x2009, 0x0020, 0x695a, 0x0078, 0x8309, 0x2d78, 0x1078, 0x86d1,
+ 0xd6dc, 0x00c0, 0x8326, 0xa006, 0x0078, 0x832c, 0x2001, 0x0001,
+ 0x2071, 0xa88c, 0x7218, 0x731c, 0x1078, 0x1645, 0x0d7f, 0x0e7f,
+ 0x0f7f, 0x077f, 0x007c, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x20e1,
+ 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x2001,
+ 0xa5a2, 0x2004, 0x603e, 0x0d7e, 0x6003, 0x0002, 0x6110, 0x2168,
+ 0x694c, 0xd1e4, 0x0040, 0x846b, 0x603f, 0x0000, 0x0f7e, 0x2c78,
+ 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8385, 0x6814, 0x6910, 0xa115,
+ 0x0040, 0x8385, 0x6a60, 0xa206, 0x00c0, 0x8362, 0x685c, 0xa106,
+ 0x0040, 0x8385, 0x684c, 0xc0e4, 0x684e, 0x6847, 0x0000, 0x6863,
+ 0x0000, 0x685f, 0x0000, 0x6024, 0xd0f4, 0x00c0, 0x837a, 0x697c,
+ 0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6024,
+ 0xc0f5, 0x6026, 0x0d7e, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+ 0x0d7f, 0x1078, 0x8cfa, 0x0078, 0x846b, 0x694c, 0xd1cc, 0x0040,
+ 0x8430, 0x6948, 0x6838, 0xd0fc, 0x0040, 0x83ea, 0x017e, 0x684c,
+ 0x007e, 0x6850, 0x007e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+ 0xa0b6, 0x0002, 0x0040, 0x83bf, 0xa086, 0x0028, 0x00c0, 0x83a6,
+ 0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x83ca, 0xd1dc, 0x0040,
+ 0x83b6, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+ 0x83b4, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x83ca, 0xd1d4, 0x0040,
+ 0x83bf, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x83ca, 0x684c,
+ 0xd0ac, 0x0040, 0x83ca, 0x6810, 0x6914, 0xa115, 0x0040, 0x83ca,
+ 0x1078, 0x8233, 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e,
+ 0xad90, 0x000d, 0xaf98, 0x000d, 0x2009, 0x0020, 0x157e, 0x21a8,
+ 0x2304, 0x2012, 0x8318, 0x8210, 0x00f0, 0x83d8, 0x157f, 0x0f7f,
+ 0x007f, 0x6852, 0x007f, 0x684e, 0x017f, 0x2168, 0x1078, 0x13aa,
+ 0x0078, 0x8465, 0x017e, 0x0f7e, 0x2178, 0x7944, 0xa184, 0x00ff,
+ 0xa0b6, 0x0002, 0x0040, 0x8417, 0xa086, 0x0028, 0x00c0, 0x83fe,
+ 0x684b, 0x001c, 0x784b, 0x001c, 0x0078, 0x8422, 0xd1dc, 0x0040,
+ 0x840e, 0x684b, 0x0015, 0x784b, 0x0015, 0x1078, 0x8ea5, 0x0040,
+ 0x840c, 0x7944, 0xc1dc, 0x7946, 0x0078, 0x8422, 0xd1d4, 0x0040,
+ 0x8417, 0x684b, 0x0007, 0x784b, 0x0007, 0x0078, 0x8422, 0x684c,
+ 0xd0ac, 0x0040, 0x8422, 0x6810, 0x6914, 0xa115, 0x0040, 0x8422,
+ 0x1078, 0x8233, 0x6860, 0x7862, 0x685c, 0x785e, 0x684c, 0x784e,
+ 0x0f7f, 0x1078, 0x13aa, 0x0d7f, 0x1078, 0x8726, 0x0078, 0x8465,
+ 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0040,
+ 0x8456, 0xa086, 0x0028, 0x00c0, 0x8441, 0x684b, 0x001c, 0x0078,
+ 0x8463, 0xd1dc, 0x0040, 0x844f, 0x684b, 0x0015, 0x1078, 0x8ea5,
+ 0x0040, 0x844d, 0x6944, 0xc1dc, 0x6946, 0x0078, 0x8463, 0xd1d4,
+ 0x0040, 0x8456, 0x684b, 0x0007, 0x0078, 0x8463, 0x684b, 0x0000,
+ 0x684c, 0xd0ac, 0x0040, 0x8463, 0x6810, 0x6914, 0xa115, 0x0040,
+ 0x8463, 0x1078, 0x8233, 0x1078, 0x4982, 0x1078, 0x8cc4, 0x00c0,
+ 0x846b, 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x6010, 0x0078,
+ 0x8473, 0x1078, 0x60b8, 0x1078, 0x8a44, 0x0040, 0x8492, 0x0d7e,
+ 0x6110, 0x2168, 0x6837, 0x0103, 0x2009, 0xa30c, 0x210c, 0xd18c,
+ 0x00c0, 0x849d, 0xd184, 0x00c0, 0x8499, 0x6108, 0x694a, 0xa18e,
+ 0x0029, 0x00c0, 0x848d, 0x1078, 0xa181, 0x6847, 0x0000, 0x1078,
+ 0x4982, 0x0d7f, 0x1078, 0x753d, 0x1078, 0x6109, 0x1078, 0x61d3,
+ 0x007c, 0x684b, 0x0004, 0x0078, 0x848d, 0x684b, 0x0004, 0x0078,
+ 0x848d, 0xa182, 0x0040, 0x0079, 0x84a5, 0x84b8, 0x84b8, 0x84b8,
+ 0x84b8, 0x84b8, 0x84ba, 0x84b8, 0x84bd, 0x84b8, 0x84b8, 0x84b8,
+ 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8, 0x84b8,
+ 0x1078, 0x1328, 0x1078, 0x753d, 0x007c, 0x007e, 0x027e, 0xa016,
+ 0x1078, 0x15ec, 0x027f, 0x007f, 0x007c, 0xa182, 0x0085, 0x0079,
+ 0x84c9, 0x84d2, 0x84d0, 0x84d0, 0x84de, 0x84d0, 0x84d0, 0x84d0,
+ 0x1078, 0x1328, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x057e,
+ 0x0d7e, 0x0e7e, 0x2071, 0xa880, 0x7224, 0x6212, 0x7220, 0x1078,
+ 0x8a30, 0x0040, 0x8503, 0x2268, 0x6800, 0xa086, 0x0000, 0x0040,
+ 0x8503, 0x6018, 0x6d18, 0xa52e, 0x00c0, 0x8503, 0x0c7e, 0x2d60,
+ 0x1078, 0x874a, 0x0c7f, 0x0040, 0x8503, 0x6803, 0x0002, 0x6007,
+ 0x0086, 0x0078, 0x8505, 0x6007, 0x0087, 0x6003, 0x0001, 0x1078,
+ 0x5bf8, 0x1078, 0x6109, 0x0f7e, 0x2278, 0x1078, 0x4893, 0x0f7f,
+ 0x0040, 0x851d, 0x6824, 0xd0ec, 0x0040, 0x851d, 0x0c7e, 0x2260,
+ 0x603f, 0x0000, 0x1078, 0x8cfa, 0x0c7f, 0x0e7f, 0x0d7f, 0x057f,
+ 0x027f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x8533, 0x6004, 0xa08a,
+ 0x0085, 0x1048, 0x1328, 0xa08a, 0x008c, 0x10c8, 0x1328, 0xa082,
+ 0x0085, 0x0079, 0x8542, 0xa186, 0x0027, 0x0040, 0x853b, 0xa186,
+ 0x0014, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+ 0x6109, 0x007c, 0x8549, 0x854b, 0x854b, 0x8549, 0x8549, 0x8549,
+ 0x8549, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+ 0x6109, 0x007c, 0xa186, 0x0013, 0x00c0, 0x855c, 0x6004, 0xa082,
+ 0x0085, 0x2008, 0x0078, 0x8597, 0xa186, 0x0027, 0x00c0, 0x857f,
+ 0x1078, 0x6010, 0x1078, 0x2813, 0x0d7e, 0x6010, 0x2068, 0x1078,
+ 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b,
+ 0x0029, 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d,
+ 0x1078, 0x6109, 0x007c, 0x1078, 0x7583, 0x0078, 0x857a, 0xa186,
+ 0x0014, 0x00c0, 0x857b, 0x1078, 0x6010, 0x0d7e, 0x6010, 0x2068,
+ 0x1078, 0x8a44, 0x0040, 0x8575, 0x6837, 0x0103, 0x6847, 0x0000,
+ 0x684b, 0x0006, 0x6850, 0xc0ec, 0x6852, 0x0078, 0x8571, 0x0079,
+ 0x8599, 0x85a2, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85a0, 0x85bd,
+ 0x1078, 0x1328, 0x1078, 0x6010, 0x6030, 0xa08c, 0xff00, 0x810f,
+ 0xa186, 0x0039, 0x0040, 0x85b0, 0xa186, 0x0035, 0x00c0, 0x85b4,
+ 0x2001, 0xa5a0, 0x0078, 0x85b6, 0x2001, 0xa5a1, 0x2004, 0x6016,
+ 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x6030,
+ 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0040, 0x85cb, 0xa186,
+ 0x0035, 0x00c0, 0x85cf, 0x2001, 0xa5a0, 0x0078, 0x85d1, 0x2001,
+ 0xa5a1, 0x2004, 0x6016, 0x6003, 0x000e, 0x1078, 0x6109, 0x007c,
+ 0xa182, 0x008c, 0x00c8, 0x85e2, 0xa182, 0x0085, 0x0048, 0x85e2,
+ 0x0079, 0x85e5, 0x1078, 0x7583, 0x007c, 0x85ec, 0x85ec, 0x85ec,
+ 0x85ec, 0x85ee, 0x8643, 0x85ec, 0x1078, 0x1328, 0x0f7e, 0x2c78,
+ 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8601, 0x6030, 0xa08c, 0xff00,
+ 0x810f, 0xa186, 0x0039, 0x0040, 0x865a, 0xa186, 0x0035, 0x0040,
+ 0x865a, 0x0d7e, 0x1078, 0x8bf4, 0x1078, 0x8a44, 0x0040, 0x8625,
+ 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8616,
+ 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0078, 0x8621, 0xd0bc, 0x0040,
+ 0x861d, 0x684b, 0x0002, 0x0078, 0x8621, 0x684b, 0x0005, 0x1078,
+ 0x8cc0, 0x6847, 0x0000, 0x1078, 0x4982, 0x2c68, 0x1078, 0x74d7,
+ 0x0040, 0x863e, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xa88e,
+ 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x6918, 0x611a,
+ 0x6920, 0x6122, 0x601f, 0x0001, 0x1078, 0x5bf8, 0x2d60, 0x1078,
+ 0x753d, 0x0d7f, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f,
+ 0x0040, 0x8680, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+ 0x0040, 0x865a, 0xa186, 0x001e, 0x0040, 0x865a, 0xa186, 0x0039,
+ 0x00c0, 0x8680, 0x0d7e, 0x2c68, 0x1078, 0x8ef5, 0x00c0, 0x86a4,
+ 0x1078, 0x74d7, 0x0040, 0x867d, 0x6106, 0x6003, 0x0001, 0x601f,
+ 0x0001, 0x6918, 0x611a, 0x6928, 0x612a, 0x692c, 0x612e, 0x6930,
+ 0xa18c, 0x00ff, 0x6132, 0x6934, 0x6136, 0x6938, 0x613a, 0x6920,
+ 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x2d60, 0x0078, 0x86a4,
+ 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86a4, 0x6837,
+ 0x0103, 0x6850, 0xd0b4, 0x0040, 0x8693, 0xc0ec, 0x6852, 0x684b,
+ 0x0006, 0x0078, 0x869e, 0xd0bc, 0x0040, 0x869a, 0x684b, 0x0002,
+ 0x0078, 0x869e, 0x684b, 0x0005, 0x1078, 0x8cc0, 0x6847, 0x0000,
+ 0x1078, 0x4982, 0x1078, 0x8bf4, 0x0d7f, 0x1078, 0x753d, 0x007c,
+ 0x017e, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x86b8,
+ 0x6837, 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x1078, 0x4982,
+ 0x0d7f, 0x017f, 0xa186, 0x0013, 0x0040, 0x86ca, 0xa186, 0x0014,
+ 0x0040, 0x86ca, 0xa186, 0x0027, 0x0040, 0x86ca, 0x1078, 0x7583,
+ 0x0078, 0x86d0, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+ 0x007c, 0x057e, 0x067e, 0x0d7e, 0x0f7e, 0x2029, 0x0001, 0xa182,
+ 0x0101, 0x00c8, 0x86dd, 0x0078, 0x86df, 0x2009, 0x0100, 0x2130,
+ 0x2069, 0xa898, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020, 0xaf90,
+ 0x001d, 0x1078, 0x8739, 0xa6b2, 0x0020, 0x7804, 0xa06d, 0x0040,
+ 0x86f3, 0x1078, 0x13aa, 0x1078, 0x1381, 0x0040, 0x871d, 0x8528,
+ 0x6837, 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d,
+ 0x00c8, 0x8709, 0x2608, 0xad90, 0x000f, 0x1078, 0x8739, 0x0078,
+ 0x871d, 0xa6b2, 0x003c, 0x2009, 0x003c, 0x2d78, 0xad90, 0x000f,
+ 0x1078, 0x8739, 0x0078, 0x86f3, 0x0f7f, 0x852f, 0xa5ad, 0x0003,
+ 0x7d36, 0xa5ac, 0x0000, 0x0078, 0x8722, 0x0f7f, 0x852f, 0xa5ad,
+ 0x0003, 0x7d36, 0x0d7f, 0x067f, 0x057f, 0x007c, 0x0f7e, 0x8dff,
+ 0x0040, 0x8737, 0x6804, 0xa07d, 0x0040, 0x8735, 0x6807, 0x0000,
+ 0x1078, 0x4982, 0x2f68, 0x0078, 0x872a, 0x1078, 0x4982, 0x0f7f,
+ 0x007c, 0x157e, 0xa184, 0x0001, 0x0040, 0x873f, 0x8108, 0x810c,
+ 0x21a8, 0x2304, 0x8007, 0x2012, 0x8318, 0x8210, 0x00f0, 0x8741,
+ 0x157f, 0x007c, 0x067e, 0x127e, 0x2091, 0x8000, 0x2031, 0x0001,
+ 0x601c, 0xa084, 0x000f, 0x1079, 0x8766, 0x127f, 0x067f, 0x007c,
+ 0x127e, 0x2091, 0x8000, 0x067e, 0x2031, 0x0000, 0x601c, 0xa084,
+ 0x000f, 0x1079, 0x8766, 0x067f, 0x127f, 0x007c, 0x8780, 0x876e,
+ 0x877b, 0x879c, 0x876e, 0x877b, 0x879c, 0x877b, 0x1078, 0x1328,
+ 0x037e, 0x2019, 0x0010, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003,
+ 0x0007, 0x037f, 0x007c, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
+ 0x0d7e, 0x86ff, 0x00c0, 0x8797, 0x6010, 0x2068, 0x1078, 0x8a44,
+ 0x0040, 0x8799, 0xa00e, 0x2001, 0x0005, 0x1078, 0x4a60, 0x1078,
+ 0x8cc0, 0x1078, 0x4982, 0x1078, 0x753d, 0xa085, 0x0001, 0x0d7f,
+ 0x007c, 0xa006, 0x0078, 0x8797, 0x6000, 0xa08a, 0x0010, 0x10c8,
+ 0x1328, 0x1079, 0x87a4, 0x007c, 0x87b4, 0x87d4, 0x87b6, 0x87f7,
+ 0x87d0, 0x87b4, 0x877b, 0x8780, 0x8780, 0x877b, 0x877b, 0x877b,
+ 0x877b, 0x877b, 0x877b, 0x877b, 0x1078, 0x1328, 0x86ff, 0x00c0,
+ 0x87cd, 0x0d7e, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x87c2,
+ 0x1078, 0x8cc0, 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f,
+ 0x0002, 0x1078, 0x5bf8, 0x1078, 0x6109, 0xa085, 0x0001, 0x007c,
+ 0x1078, 0x1749, 0x0078, 0x87b6, 0x0e7e, 0x2071, 0xa5ab, 0x7024,
+ 0xac06, 0x00c0, 0x87dd, 0x1078, 0x6dda, 0x601c, 0xa084, 0x000f,
+ 0xa086, 0x0006, 0x00c0, 0x87ef, 0x087e, 0x097e, 0x2049, 0x0001,
+ 0x2c40, 0x1078, 0x7058, 0x097f, 0x087f, 0x0078, 0x87f1, 0x1078,
+ 0x6cd2, 0x0e7f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c, 0x037e,
+ 0x0e7e, 0x2071, 0xa5ab, 0x703c, 0xac06, 0x00c0, 0x8807, 0x2019,
+ 0x0000, 0x1078, 0x6e6c, 0x0e7f, 0x037f, 0x0078, 0x87b6, 0x1078,
+ 0x719a, 0x0e7f, 0x037f, 0x00c0, 0x87b6, 0x1078, 0x877b, 0x007c,
+ 0x0c7e, 0x601c, 0xa084, 0x000f, 0x1079, 0x8818, 0x0c7f, 0x007c,
+ 0x8827, 0x8895, 0x89cd, 0x8832, 0x8c01, 0x8827, 0x9a5b, 0x753d,
+ 0x8895, 0x1078, 0x8c3b, 0x00c0, 0x8827, 0x1078, 0x7a05, 0x007c,
+ 0x1078, 0x6010, 0x1078, 0x6109, 0x1078, 0x753d, 0x007c, 0x6017,
+ 0x0001, 0x007c, 0x6010, 0xa080, 0x0019, 0x2c02, 0x6000, 0xa08a,
+ 0x0010, 0x10c8, 0x1328, 0x1079, 0x883e, 0x007c, 0x884e, 0x8850,
+ 0x8872, 0x8884, 0x8891, 0x884e, 0x8827, 0x8827, 0x8827, 0x8884,
+ 0x8884, 0x884e, 0x884e, 0x884e, 0x884e, 0x888e, 0x1078, 0x1328,
+ 0x0e7e, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071, 0xa5ab,
+ 0x7024, 0xac06, 0x0040, 0x886e, 0x1078, 0x6cd2, 0x6007, 0x0085,
+ 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xa5a1, 0x2004, 0x6016,
+ 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x6017, 0x0001,
+ 0x0078, 0x886c, 0x0d7e, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852,
+ 0x0d7f, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x1078,
+ 0x5bf8, 0x1078, 0x6109, 0x007c, 0x0d7e, 0x6017, 0x0001, 0x6010,
+ 0x2068, 0x6850, 0xc0b5, 0x6852, 0x0d7f, 0x007c, 0x1078, 0x753d,
+ 0x007c, 0x1078, 0x1749, 0x0078, 0x8872, 0x6000, 0xa08a, 0x0010,
+ 0x10c8, 0x1328, 0x1079, 0x889d, 0x007c, 0x88ad, 0x882f, 0x88af,
+ 0x88ad, 0x88af, 0x88af, 0x8828, 0x88ad, 0x8821, 0x8821, 0x88ad,
+ 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x88ad, 0x1078, 0x1328, 0x0d7e,
+ 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f, 0xa08a, 0x000c,
+ 0x10c8, 0x1328, 0x1079, 0x88bd, 0x007c, 0x88c9, 0x8971, 0x88cb,
+ 0x890b, 0x88cb, 0x890b, 0x88cb, 0x88d8, 0x88c9, 0x890b, 0x88c9,
+ 0x88f5, 0x1078, 0x1328, 0x6004, 0xa08e, 0x0016, 0x0040, 0x8906,
+ 0xa08e, 0x0004, 0x0040, 0x8906, 0xa08e, 0x0002, 0x0040, 0x8906,
+ 0x6004, 0x1078, 0x8c3b, 0x0040, 0x898c, 0xa08e, 0x0021, 0x0040,
+ 0x8990, 0xa08e, 0x0022, 0x0040, 0x898c, 0xa08e, 0x003d, 0x0040,
+ 0x8990, 0xa08e, 0x0039, 0x0040, 0x8994, 0xa08e, 0x0035, 0x0040,
+ 0x8994, 0xa08e, 0x001e, 0x0040, 0x8908, 0xa08e, 0x0001, 0x00c0,
+ 0x8904, 0x0d7e, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x0d7f,
+ 0xa086, 0x0006, 0x0040, 0x8906, 0x1078, 0x2813, 0x1078, 0x7a05,
+ 0x1078, 0x8c01, 0x007c, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016,
+ 0x0040, 0x8961, 0xa186, 0x0002, 0x00c0, 0x8934, 0x6018, 0x2068,
+ 0x68a0, 0xd0bc, 0x00c0, 0x89b8, 0x6840, 0xa084, 0x00ff, 0xa005,
+ 0x0040, 0x8934, 0x8001, 0x6842, 0x6013, 0x0000, 0x601f, 0x0007,
+ 0x6017, 0x0398, 0x1078, 0x74d7, 0x0040, 0x8934, 0x2d00, 0x601a,
+ 0x601f, 0x0001, 0x0078, 0x8961, 0x0d7f, 0x0c7f, 0x6004, 0xa08e,
+ 0x0002, 0x00c0, 0x8952, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086,
+ 0x007e, 0x00c0, 0x8952, 0x2009, 0xa332, 0x2104, 0xc085, 0x200a,
+ 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x0e7f, 0x1078, 0x7a05,
+ 0x0078, 0x8956, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x2839, 0x127f, 0x0e7f, 0x1078, 0x8c01,
+ 0x007c, 0x2001, 0x0002, 0x1078, 0x443f, 0x6003, 0x0001, 0x6007,
+ 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0d7f, 0x0c7f, 0x0078,
+ 0x8960, 0x0c7e, 0x0d7e, 0x6104, 0xa186, 0x0016, 0x0040, 0x8961,
+ 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0040, 0x8934,
+ 0x8001, 0x6842, 0x6003, 0x0001, 0x1078, 0x5c45, 0x1078, 0x6109,
+ 0x0d7f, 0x0c7f, 0x0078, 0x8960, 0x1078, 0x7a05, 0x0078, 0x8908,
+ 0x1078, 0x7a28, 0x0078, 0x8908, 0x0d7e, 0x2c68, 0x6104, 0x1078,
+ 0x8ef5, 0x0d7f, 0x0040, 0x89a0, 0x1078, 0x753d, 0x0078, 0x89b7,
+ 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038, 0x600a, 0x2001,
+ 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c,
+ 0x0d7f, 0x0c7f, 0x1078, 0x7a05, 0x1078, 0x2813, 0x0e7e, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x2839, 0x6013, 0x0000, 0x601f, 0x0007,
+ 0x6017, 0x0398, 0x127f, 0x0e7f, 0x007c, 0x6000, 0xa08a, 0x0010,
+ 0x10c8, 0x1328, 0x1079, 0x89d5, 0x007c, 0x89e5, 0x89e5, 0x89e5,
+ 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x89e5, 0x8827, 0x89e5,
+ 0x882f, 0x89e7, 0x882f, 0x89f5, 0x89e5, 0x1078, 0x1328, 0x6004,
+ 0xa086, 0x008b, 0x0040, 0x89f5, 0x6007, 0x008b, 0x6003, 0x000d,
+ 0x1078, 0x5bf8, 0x1078, 0x6109, 0x007c, 0x1078, 0x8bf4, 0x1078,
+ 0x8a44, 0x0040, 0x8a2d, 0x1078, 0x2813, 0x0d7e, 0x1078, 0x8a44,
+ 0x0040, 0x8a0f, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+ 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x1078, 0x4982, 0x2c68,
+ 0x1078, 0x74d7, 0x0040, 0x8a1d, 0x6818, 0x601a, 0x0c7e, 0x2d60,
+ 0x1078, 0x8c01, 0x0c7f, 0x0078, 0x8a1e, 0x2d60, 0x0d7f, 0x6013,
+ 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078,
+ 0x5c45, 0x1078, 0x6109, 0x0078, 0x8a2f, 0x1078, 0x8c01, 0x007c,
+ 0xa284, 0x000f, 0x00c0, 0x8a41, 0xa282, 0xaa00, 0x0048, 0x8a41,
+ 0x2001, 0xa315, 0x2004, 0xa202, 0x00c8, 0x8a41, 0xa085, 0x0001,
+ 0x007c, 0xa006, 0x0078, 0x8a40, 0x027e, 0x0e7e, 0x2071, 0xa300,
+ 0x6210, 0x7058, 0xa202, 0x0048, 0x8a56, 0x705c, 0xa202, 0x00c8,
+ 0x8a56, 0xa085, 0x0001, 0x0e7f, 0x027f, 0x007c, 0xa006, 0x0078,
+ 0x8a53, 0x0e7e, 0x0c7e, 0x037e, 0x007e, 0x127e, 0x2091, 0x8000,
+ 0x2061, 0xaa00, 0x2071, 0xa300, 0x7344, 0x7060, 0xa302, 0x00c8,
+ 0x8a83, 0x601c, 0xa206, 0x00c0, 0x8a7b, 0x1078, 0x8d66, 0x0040,
+ 0x8a7b, 0x1078, 0x8c3b, 0x00c0, 0x8a77, 0x1078, 0x7a05, 0x0c7e,
+ 0x1078, 0x753d, 0x0c7f, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8,
+ 0x8a83, 0x0078, 0x8a64, 0x127f, 0x007f, 0x037f, 0x0c7f, 0x0e7f,
+ 0x007c, 0x0e7e, 0x0c7e, 0x017e, 0xa188, 0xa434, 0x210c, 0x81ff,
+ 0x0040, 0x8aa1, 0x2061, 0xaa00, 0x2071, 0xa300, 0x017e, 0x1078,
+ 0x74d7, 0x017f, 0x0040, 0x8aa4, 0x611a, 0x1078, 0x2813, 0x1078,
+ 0x753d, 0xa006, 0x0078, 0x8aa6, 0xa085, 0x0001, 0x017f, 0x0c7f,
+ 0x0e7f, 0x007c, 0x0c7e, 0x057e, 0x127e, 0x2091, 0x8000, 0x0c7e,
+ 0x1078, 0x74d7, 0x057f, 0x0040, 0x8ac3, 0x6612, 0x651a, 0x601f,
+ 0x0003, 0x2009, 0x004b, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+ 0x057f, 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8abf, 0x0c7e, 0x057e,
+ 0x127e, 0x2091, 0x8000, 0x62a0, 0x0c7e, 0x1078, 0x74d7, 0x057f,
+ 0x0040, 0x8af1, 0x6013, 0x0000, 0x651a, 0x601f, 0x0003, 0x0c7e,
+ 0x2560, 0x1078, 0x471b, 0x0c7f, 0x1078, 0x5d53, 0x077e, 0x2039,
+ 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2009,
+ 0x004c, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x057f, 0x0c7f,
+ 0x007c, 0xa006, 0x0078, 0x8aed, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e,
+ 0x1078, 0x74d7, 0x2c78, 0x0c7f, 0x0040, 0x8b0e, 0x7e12, 0x2c00,
+ 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60,
+ 0x2009, 0x004d, 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f,
+ 0x0f7f, 0x007c, 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7,
+ 0x2c78, 0x0c7f, 0x0040, 0x8b2c, 0x7e12, 0x2c00, 0x781a, 0x781f,
+ 0x0003, 0x2021, 0x0005, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x004e,
+ 0x1078, 0x756c, 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c,
+ 0x0f7e, 0x0c7e, 0x047e, 0x0c7e, 0x1078, 0x74d7, 0x2c78, 0x0c7f,
+ 0x0040, 0x8b4a, 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021,
+ 0x0004, 0x1078, 0x8b4e, 0x2f60, 0x2009, 0x0052, 0x1078, 0x756c,
+ 0xa085, 0x0001, 0x047f, 0x0c7f, 0x0f7f, 0x007c, 0x097e, 0x077e,
+ 0x127e, 0x2091, 0x8000, 0x1078, 0x46a7, 0x0040, 0x8b5b, 0x2001,
+ 0x8b53, 0x0078, 0x8b61, 0x1078, 0x466d, 0x0040, 0x8b6a, 0x2001,
+ 0x8b5b, 0x007e, 0xa00e, 0x2400, 0x1078, 0x4a60, 0x1078, 0x4982,
+ 0x007f, 0x007a, 0x2418, 0x1078, 0x5fa7, 0x62a0, 0x087e, 0x2041,
+ 0x0001, 0x2039, 0x0001, 0x2608, 0x1078, 0x5d6d, 0x087f, 0x1078,
+ 0x5c78, 0x2f08, 0x2648, 0x1078, 0x9c38, 0x613c, 0x81ff, 0x1040,
+ 0x5e21, 0x127f, 0x077f, 0x097f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+ 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8b9e, 0x660a,
+ 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x001f, 0x1078,
+ 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+ 0x8b9b, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+ 0x017f, 0x0040, 0x8bba, 0x660a, 0x611a, 0x601f, 0x0008, 0x2d00,
+ 0x6012, 0x2009, 0x0021, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+ 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8bb7, 0x0c7e, 0x127e, 0x2091,
+ 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8bd6, 0x660a,
+ 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x003d, 0x1078,
+ 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+ 0x8bd3, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7,
+ 0x017f, 0x0040, 0x8bf1, 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012,
+ 0x2009, 0x0000, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f,
+ 0x007c, 0xa006, 0x0078, 0x8bee, 0x027e, 0x0d7e, 0x6218, 0x2268,
+ 0x6a3c, 0x82ff, 0x0040, 0x8bfe, 0x8211, 0x6a3e, 0x0d7f, 0x027f,
+ 0x007c, 0x007e, 0x6000, 0xa086, 0x0000, 0x0040, 0x8c13, 0x6013,
+ 0x0000, 0x601f, 0x0007, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078,
+ 0xa134, 0x603f, 0x0000, 0x007f, 0x007c, 0x067e, 0x0c7e, 0x0d7e,
+ 0x2031, 0xa352, 0x2634, 0xd6e4, 0x0040, 0x8c23, 0x6618, 0x2660,
+ 0x6e48, 0x1078, 0x461b, 0x0d7f, 0x0c7f, 0x067f, 0x007c, 0x007e,
+ 0x017e, 0x6004, 0xa08e, 0x0002, 0x0040, 0x8c38, 0xa08e, 0x0003,
+ 0x0040, 0x8c38, 0xa08e, 0x0004, 0x0040, 0x8c38, 0xa085, 0x0001,
+ 0x017f, 0x007f, 0x007c, 0x007e, 0x0d7e, 0x6010, 0xa06d, 0x0040,
+ 0x8c48, 0x6838, 0xd0fc, 0x0040, 0x8c48, 0xa006, 0x0078, 0x8c4a,
+ 0xa085, 0x0001, 0x0d7f, 0x007f, 0x007c, 0x0c7e, 0x127e, 0x2091,
+ 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8c67, 0x611a,
+ 0x601f, 0x0001, 0x2d00, 0x6012, 0x1078, 0x2813, 0x2009, 0x0028,
+ 0x1078, 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006,
+ 0x0078, 0x8c64, 0xa186, 0x0015, 0x00c0, 0x8c7f, 0x2011, 0xa31f,
+ 0x2204, 0xa086, 0x0074, 0x00c0, 0x8c7f, 0x1078, 0x7d0d, 0x6003,
+ 0x0001, 0x6007, 0x0029, 0x1078, 0x5c45, 0x0078, 0x8c83, 0x1078,
+ 0x7a05, 0x1078, 0x753d, 0x007c, 0xa186, 0x0016, 0x00c0, 0x8c8e,
+ 0x2001, 0x0004, 0x1078, 0x443f, 0x0078, 0x8caf, 0xa186, 0x0015,
+ 0x00c0, 0x8cb3, 0x2011, 0xa31f, 0x2204, 0xa086, 0x0014, 0x00c0,
+ 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x1078, 0x457d, 0x0d7f, 0x1078,
+ 0x7dba, 0x00c0, 0x8cb3, 0x0d7e, 0x6018, 0x2068, 0x6890, 0x0d7f,
+ 0xa005, 0x0040, 0x8cb3, 0x2001, 0x0006, 0x1078, 0x443f, 0x1078,
+ 0x7608, 0x0078, 0x8cb7, 0x1078, 0x7a05, 0x1078, 0x753d, 0x007c,
+ 0x6848, 0xa086, 0x0005, 0x00c0, 0x8cbf, 0x1078, 0x8cc0, 0x007c,
+ 0x6850, 0xc0ad, 0x6852, 0x007c, 0x0e7e, 0x2071, 0xa88c, 0x7014,
+ 0xd0e4, 0x0040, 0x8cd5, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007,
+ 0x0050, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x007c, 0x0c7e,
+ 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x0040, 0x8ce4, 0x601c,
+ 0xa084, 0x000f, 0x1079, 0x8ce6, 0x0c7f, 0x007c, 0x8827, 0x8cf1,
+ 0x8cf4, 0x8cf7, 0x9f00, 0x9f1c, 0x9f1f, 0x8827, 0x8827, 0x1078,
+ 0x1328, 0x0005, 0x0005, 0x007c, 0x0005, 0x0005, 0x007c, 0x1078,
+ 0x8cfa, 0x007c, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0040, 0x8d29,
+ 0x1078, 0x74d7, 0x00c0, 0x8d0a, 0x2001, 0xa5a2, 0x2004, 0x783e,
+ 0x0078, 0x8d29, 0x7818, 0x601a, 0x781c, 0xa086, 0x0003, 0x0040,
+ 0x8d17, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0078, 0x8d1b, 0x7808,
+ 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007, 0x0035,
+ 0x6003, 0x0001, 0x7920, 0x6122, 0x1078, 0x5bf8, 0x1078, 0x6109,
+ 0x2f60, 0x0f7f, 0x007c, 0x017e, 0x0f7e, 0x682c, 0x6032, 0xa08e,
+ 0x0001, 0x0040, 0x8d3c, 0xa086, 0x0005, 0x0040, 0x8d40, 0xa006,
+ 0x602a, 0x602e, 0x0078, 0x8d51, 0x6824, 0xc0f4, 0xc0d5, 0x6826,
+ 0x6810, 0x2078, 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103,
+ 0x00c8, 0x8d37, 0x6834, 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a,
+ 0x602e, 0x2d00, 0x6036, 0x6808, 0x603a, 0x6918, 0x611a, 0x6920,
+ 0x6122, 0x601f, 0x0001, 0x6007, 0x0039, 0x6003, 0x0001, 0x1078,
+ 0x5bf8, 0x6803, 0x0002, 0x0f7f, 0x017f, 0x007c, 0x007e, 0x017e,
+ 0x6004, 0xa08e, 0x0034, 0x0040, 0x8d8b, 0xa08e, 0x0035, 0x0040,
+ 0x8d8b, 0xa08e, 0x0036, 0x0040, 0x8d8b, 0xa08e, 0x0037, 0x0040,
+ 0x8d8b, 0xa08e, 0x0038, 0x0040, 0x8d8b, 0xa08e, 0x0039, 0x0040,
+ 0x8d8b, 0xa08e, 0x003a, 0x0040, 0x8d8b, 0xa08e, 0x003b, 0x0040,
+ 0x8d8b, 0xa085, 0x0001, 0x017f, 0x007f, 0x007c, 0x0f7e, 0x2c78,
+ 0x1078, 0x4893, 0x00c0, 0x8d98, 0xa085, 0x0001, 0x0078, 0x8da7,
+ 0x6024, 0xd0f4, 0x00c0, 0x8da6, 0xc0f5, 0x6026, 0x6010, 0x2078,
+ 0x7828, 0x603a, 0x782c, 0x6036, 0x1078, 0x1749, 0xa006, 0x0f7f,
+ 0x007c, 0x007e, 0x017e, 0x027e, 0x037e, 0x0e7e, 0x2001, 0xa59c,
+ 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x1078, 0x5a98, 0x2001,
+ 0xa5a0, 0x82ff, 0x00c0, 0x8dbe, 0x2011, 0x0002, 0x2202, 0x2001,
+ 0xa59e, 0x200c, 0x8000, 0x2014, 0x2071, 0xa58c, 0x711a, 0x721e,
+ 0x2001, 0x0064, 0x1078, 0x5a98, 0x2001, 0xa5a1, 0x82ff, 0x00c0,
+ 0x8dd3, 0x2011, 0x0002, 0x2202, 0x2009, 0xa5a2, 0xa280, 0x000a,
+ 0x200a, 0x0e7f, 0x037f, 0x027f, 0x017f, 0x007f, 0x007c, 0x007e,
+ 0x0e7e, 0x2001, 0xa5a0, 0x2003, 0x0028, 0x2001, 0xa5a1, 0x2003,
+ 0x0014, 0x2071, 0xa58c, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+ 0xa5a2, 0x2003, 0x001e, 0x0e7f, 0x007f, 0x007c, 0x0c7e, 0x127e,
+ 0x2091, 0x8000, 0x0c7e, 0x1078, 0x74d7, 0x017f, 0x0040, 0x8e0e,
+ 0x611a, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033, 0x1078,
+ 0x756c, 0xa085, 0x0001, 0x127f, 0x0c7f, 0x007c, 0xa006, 0x0078,
+ 0x8e0b, 0x0d7e, 0x0e7e, 0x0f7e, 0x2071, 0xa300, 0xa186, 0x0015,
+ 0x00c0, 0x8e40, 0x707c, 0xa086, 0x0018, 0x00c0, 0x8e40, 0x6010,
+ 0x2068, 0x6a3c, 0xd2e4, 0x00c0, 0x8e34, 0x2c78, 0x1078, 0x62c6,
+ 0x0040, 0x8e48, 0x7068, 0x6a50, 0xa206, 0x00c0, 0x8e3c, 0x706c,
+ 0x6a54, 0xa206, 0x00c0, 0x8e3c, 0x6218, 0xa290, 0x0028, 0x2214,
+ 0x2009, 0x0000, 0x1078, 0x285b, 0x1078, 0x7608, 0x0078, 0x8e44,
+ 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f, 0x0e7f, 0x0d7f, 0x007c,
+ 0x704c, 0xa080, 0x293f, 0x2004, 0x6a54, 0xa206, 0x0040, 0x8e34,
+ 0x0078, 0x8e3c, 0x0c7e, 0x127e, 0x2091, 0x8000, 0x0c7e, 0x1078,
+ 0x74d7, 0x017f, 0x0040, 0x8e6a, 0x611a, 0x601f, 0x0001, 0x2d00,
+ 0x6012, 0x2009, 0x0043, 0x1078, 0x756c, 0xa085, 0x0001, 0x127f,
+ 0x0c7f, 0x007c, 0xa006, 0x0078, 0x8e67, 0x0d7e, 0x0e7e, 0x0f7e,
+ 0x2071, 0xa300, 0xa186, 0x0015, 0x00c0, 0x8e93, 0x707c, 0xa086,
+ 0x0004, 0x00c0, 0x8e93, 0x6010, 0xa0e8, 0x000f, 0x2c78, 0x1078,
+ 0x62c6, 0x0040, 0x8e9b, 0x7068, 0x6a08, 0xa206, 0x00c0, 0x8e8f,
+ 0x706c, 0x6a0c, 0xa206, 0x00c0, 0x8e8f, 0x1078, 0x2813, 0x1078,
+ 0x7608, 0x0078, 0x8e97, 0x1078, 0x7a05, 0x1078, 0x753d, 0x0f7f,
+ 0x0e7f, 0x0d7f, 0x007c, 0x704c, 0xa080, 0x293f, 0x2004, 0x6a0c,
+ 0xa206, 0x0040, 0x8e8d, 0x0078, 0x8e8f, 0x017e, 0x027e, 0x684c,
+ 0xd0ac, 0x0040, 0x8ebd, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0040,
+ 0x8ebd, 0x6860, 0xa106, 0x00c0, 0x8eb9, 0x685c, 0xa206, 0x0040,
+ 0x8ebd, 0x6962, 0x6a5e, 0xa085, 0x0001, 0x027f, 0x017f, 0x007c,
+ 0x0e7e, 0x127e, 0x2071, 0xa300, 0x2091, 0x8000, 0x7544, 0xa582,
+ 0x0001, 0x0048, 0x8ef2, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000,
+ 0x0040, 0x8ede, 0xace0, 0x0010, 0x7054, 0xac02, 0x00c8, 0x8eda,
+ 0x0078, 0x8ecd, 0x2061, 0xaa00, 0x0078, 0x8ecd, 0x6003, 0x0008,
+ 0x8529, 0x7546, 0xaca8, 0x0010, 0x7054, 0xa502, 0x00c8, 0x8eee,
+ 0x754a, 0xa085, 0x0001, 0x127f, 0x0e7f, 0x007c, 0x704b, 0xaa00,
+ 0x0078, 0x8ee9, 0xa006, 0x0078, 0x8eeb, 0x0c7e, 0x027e, 0x017e,
+ 0xa186, 0x0035, 0x0040, 0x8eff, 0x6a34, 0x0078, 0x8f00, 0x6a28,
+ 0x1078, 0x8a30, 0x0040, 0x8f29, 0x2260, 0x611c, 0xa186, 0x0003,
+ 0x0040, 0x8f0e, 0xa186, 0x0006, 0x00c0, 0x8f25, 0x6834, 0xa206,
+ 0x0040, 0x8f1d, 0x6838, 0xa206, 0x00c0, 0x8f25, 0x6108, 0x6834,
+ 0xa106, 0x00c0, 0x8f25, 0x0078, 0x8f22, 0x6008, 0x6938, 0xa106,
+ 0x00c0, 0x8f25, 0x6018, 0x6918, 0xa106, 0x017f, 0x027f, 0x0c7f,
+ 0x007c, 0xa085, 0x0001, 0x0078, 0x8f25, 0x067e, 0x6000, 0xa0b2,
+ 0x0010, 0x10c8, 0x1328, 0x1079, 0x8f37, 0x067f, 0x007c, 0x8f47,
+ 0x93bb, 0x94d3, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f81,
+ 0x955e, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x8f47, 0x1078,
+ 0x1328, 0x067e, 0x6000, 0xa0b2, 0x0010, 0x10c8, 0x1328, 0x1079,
+ 0x8f53, 0x067f, 0x007c, 0x8f63, 0x99f6, 0x8f63, 0x8f63, 0x8f63,
+ 0x8f63, 0x8f63, 0x8f63, 0x99b4, 0x9a44, 0x8f63, 0xa053, 0xa087,
+ 0xa053, 0xa087, 0x8f63, 0x1078, 0x1328, 0x067e, 0x6000, 0xa0b2,
+ 0x0010, 0x10c8, 0x1328, 0x1079, 0x8f6f, 0x067f, 0x007c, 0x8f7f,
+ 0x969f, 0x976a, 0x9798, 0x9813, 0x8f7f, 0x9919, 0x98c1, 0x956a,
+ 0x9988, 0x999e, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x8f7f, 0x1078,
+ 0x1328, 0xa1b2, 0x0044, 0x10c8, 0x1328, 0x2100, 0x0079, 0x8f88,
+ 0x8fc8, 0x919a, 0x8fc8, 0x8fc8, 0x8fc8, 0x91a2, 0x8fc8, 0x8fc8,
+ 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8,
+ 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fca,
+ 0x902d, 0x9038, 0x9081, 0x909c, 0x911b, 0x918b, 0x8fc8, 0x8fc8,
+ 0x91a6, 0x8fc8, 0x8fc8, 0x91b5, 0x91bc, 0x8fc8, 0x8fc8, 0x8fc8,
+ 0x8fc8, 0x8fc8, 0x91ea, 0x8fc8, 0x8fc8, 0x91f5, 0x8fc8, 0x8fc8,
+ 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x920a, 0x8fc8, 0x8fc8, 0x8fc8,
+ 0x9291, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x8fc8, 0x9305,
+ 0x1078, 0x1328, 0x1078, 0x4897, 0x00c0, 0x8fd7, 0x2001, 0xa332,
+ 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x8fdf, 0x6007,
+ 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195, 0x1078,
+ 0x4887, 0x0e7e, 0x0c7e, 0x037e, 0x027e, 0x017e, 0x6218, 0x2270,
+ 0x72a0, 0x027e, 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039,
+ 0x0000, 0x1078, 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x017f,
+ 0x2e60, 0x1078, 0x471b, 0x017f, 0x027f, 0x037f, 0x0c7f, 0x0e7f,
+ 0x6618, 0x0c7e, 0x2660, 0x1078, 0x4513, 0x0c7f, 0xa6b0, 0x0001,
+ 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0048, 0x901f, 0x1078,
+ 0x9b6c, 0x00c0, 0x907b, 0x1078, 0x9afd, 0x00c0, 0x901b, 0x6007,
+ 0x0008, 0x0078, 0x9195, 0x6007, 0x0009, 0x0078, 0x9195, 0x1078,
+ 0x9d45, 0x0040, 0x9029, 0x1078, 0x9b6c, 0x0040, 0x9013, 0x0078,
+ 0x907b, 0x6013, 0x1900, 0x0078, 0x901b, 0x6106, 0x1078, 0x9aa8,
+ 0x6007, 0x0006, 0x0078, 0x9195, 0x6007, 0x0007, 0x0078, 0x9195,
+ 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x0d7e, 0x6618, 0x2668, 0x6e04,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x905d, 0xa686,
+ 0x0004, 0x0040, 0x905d, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+ 0x0040, 0x905d, 0xa686, 0x0004, 0x0040, 0x905d, 0xa686, 0x0005,
+ 0x0040, 0x905d, 0x0d7f, 0x0078, 0x907b, 0x1078, 0x9bd2, 0x00c0,
+ 0x9076, 0xa686, 0x0006, 0x00c0, 0x906f, 0x027e, 0x6218, 0xa290,
+ 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f, 0x1078,
+ 0x457d, 0x6007, 0x000a, 0x0d7f, 0x0078, 0x9195, 0x6007, 0x000b,
+ 0x0d7f, 0x0078, 0x9195, 0x1078, 0x2813, 0x6007, 0x0001, 0x0078,
+ 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x6618, 0x0d7e, 0x2668,
+ 0x6e04, 0x0d7f, 0xa686, 0x0707, 0x0040, 0x907b, 0x027e, 0x6218,
+ 0xa290, 0x0028, 0x2214, 0x2009, 0x0000, 0x1078, 0x285b, 0x027f,
+ 0x6007, 0x000c, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x90a9,
+ 0x2001, 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0,
+ 0x90b1, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078,
+ 0x9195, 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684,
+ 0x00ff, 0xa082, 0x0006, 0x0048, 0x90f5, 0xa6b4, 0xff00, 0x8637,
+ 0xa686, 0x0004, 0x0040, 0x90c8, 0xa686, 0x0006, 0x00c0, 0x907b,
+ 0x1078, 0x9be1, 0x00c0, 0x90d0, 0x6007, 0x000e, 0x0078, 0x9195,
+ 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff, 0x8427,
+ 0x047e, 0x1078, 0x2813, 0x047f, 0x017e, 0xa006, 0x2009, 0xa352,
+ 0x210c, 0xd1a4, 0x0040, 0x90ef, 0x2009, 0x0029, 0x1078, 0x9ec0,
+ 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x0d7f, 0x017f,
+ 0x047f, 0x6007, 0x0001, 0x0078, 0x9195, 0x2001, 0x0001, 0x1078,
+ 0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+ 0xa305, 0x2011, 0xa890, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+ 0x157f, 0xa005, 0x0040, 0x9115, 0xa6b4, 0xff00, 0x8637, 0xa686,
+ 0x0006, 0x0040, 0x90c8, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+ 0x0009, 0x0078, 0x9195, 0x1078, 0x4897, 0x00c0, 0x9128, 0x2001,
+ 0xa332, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008, 0x00c0, 0x9130,
+ 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0078, 0x9195,
+ 0x1078, 0x4887, 0x6618, 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff,
+ 0xa082, 0x0006, 0x0048, 0x9178, 0xa6b4, 0xff00, 0x8637, 0xa686,
+ 0x0004, 0x0040, 0x9147, 0xa686, 0x0006, 0x00c0, 0x907b, 0x1078,
+ 0x9c0c, 0x00c0, 0x9153, 0x1078, 0x9afd, 0x00c0, 0x9153, 0x6007,
+ 0x0010, 0x0078, 0x9195, 0x047e, 0x6418, 0xa4a0, 0x0028, 0x2424,
+ 0xa4a4, 0x00ff, 0x8427, 0x047e, 0x1078, 0x2813, 0x047f, 0x017e,
+ 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040, 0x9172, 0x2009,
+ 0x0029, 0x1078, 0x9ec0, 0x6018, 0x0d7e, 0x2068, 0x6800, 0xc0e5,
+ 0x6802, 0x0d7f, 0x017f, 0x047f, 0x6007, 0x0001, 0x0078, 0x9195,
+ 0x1078, 0x9d45, 0x0040, 0x9185, 0xa6b4, 0xff00, 0x8637, 0xa686,
+ 0x0006, 0x0040, 0x9147, 0x0078, 0x907b, 0x6013, 0x1900, 0x6007,
+ 0x0009, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0, 0x9340, 0x1078,
+ 0x9343, 0x00c0, 0x907b, 0x6007, 0x0012, 0x6003, 0x0001, 0x1078,
+ 0x5c45, 0x007c, 0x6007, 0x0001, 0x6003, 0x0001, 0x1078, 0x5c45,
+ 0x0078, 0x9199, 0x6007, 0x0005, 0x0078, 0x919c, 0x1078, 0xa0bf,
+ 0x00c0, 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6007, 0x0020,
+ 0x6003, 0x0001, 0x1078, 0x5c45, 0x007c, 0x6007, 0x0023, 0x6003,
+ 0x0001, 0x1078, 0x5c45, 0x007c, 0x1078, 0xa0bf, 0x00c0, 0x9340,
+ 0x1078, 0x9343, 0x00c0, 0x907b, 0x017e, 0x027e, 0x2011, 0xa890,
+ 0x2214, 0x2c08, 0x1078, 0x9e8c, 0x00c0, 0x91de, 0x2160, 0x6007,
+ 0x0026, 0x6013, 0x1700, 0x2011, 0xa889, 0x2214, 0xa296, 0xffff,
+ 0x00c0, 0x91e3, 0x6007, 0x0025, 0x0078, 0x91e3, 0x1078, 0x753d,
+ 0x2160, 0x6007, 0x0025, 0x6003, 0x0001, 0x1078, 0x5c45, 0x027f,
+ 0x017f, 0x007c, 0x6106, 0x1078, 0x9363, 0x6007, 0x002b, 0x0078,
+ 0x9195, 0x6007, 0x002c, 0x0078, 0x9195, 0x1078, 0xa0bf, 0x00c0,
+ 0x9340, 0x1078, 0x9343, 0x00c0, 0x907b, 0x6106, 0x1078, 0x9368,
+ 0x00c0, 0x9206, 0x6007, 0x002e, 0x0078, 0x9195, 0x6007, 0x002f,
+ 0x0078, 0x9195, 0x0e7e, 0x0d7e, 0x0c7e, 0x6018, 0xa080, 0x0001,
+ 0x200c, 0xa184, 0x00ff, 0xa086, 0x0006, 0x0040, 0x9223, 0xa184,
+ 0xff00, 0x8007, 0xa086, 0x0006, 0x0040, 0x9223, 0x0c7f, 0x0d7f,
+ 0x0e7f, 0x0078, 0x919a, 0x2001, 0xa371, 0x2004, 0xd0e4, 0x0040,
+ 0x928d, 0x2071, 0xa88c, 0x7010, 0x6036, 0x7014, 0x603a, 0x7108,
+ 0x720c, 0x2001, 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9241, 0x6018,
+ 0x2068, 0x6810, 0xa106, 0x00c0, 0x9241, 0x6814, 0xa206, 0x0040,
+ 0x9265, 0x2001, 0xa352, 0x2004, 0xd0ac, 0x00c0, 0x9281, 0x2069,
+ 0xa300, 0x686c, 0xa206, 0x00c0, 0x9281, 0x6868, 0xa106, 0x00c0,
+ 0x9281, 0x7210, 0x1078, 0x8a30, 0x0040, 0x9287, 0x1078, 0x9f31,
+ 0x0040, 0x9287, 0x622a, 0x6007, 0x0036, 0x6003, 0x0001, 0x1078,
+ 0x5bf8, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x7214, 0xa286, 0xffff,
+ 0x0040, 0x9277, 0x1078, 0x8a30, 0x0040, 0x9287, 0xa280, 0x0002,
+ 0x2004, 0x7110, 0xa106, 0x00c0, 0x9287, 0x0078, 0x9252, 0x7210,
+ 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x2160, 0x0040, 0x9287, 0x0078,
+ 0x9252, 0x6007, 0x0037, 0x6013, 0x1500, 0x0078, 0x925d, 0x6007,
+ 0x0037, 0x6013, 0x1700, 0x0078, 0x925d, 0x6007, 0x0012, 0x0078,
+ 0x925d, 0x6018, 0xa080, 0x0001, 0x2004, 0xa084, 0xff00, 0x8007,
+ 0xa086, 0x0006, 0x00c0, 0x919a, 0x0e7e, 0x0d7e, 0x0c7e, 0x2001,
+ 0xa371, 0x2004, 0xd0e4, 0x0040, 0x92fd, 0x2069, 0xa300, 0x2071,
+ 0xa88c, 0x7008, 0x6036, 0x720c, 0x623a, 0xa286, 0xffff, 0x00c0,
+ 0x92ba, 0x7208, 0x0c7e, 0x2c08, 0x1078, 0x9e8c, 0x2c10, 0x0c7f,
+ 0x0040, 0x92f1, 0x1078, 0x8a30, 0x0040, 0x92f1, 0x0c7e, 0x027e,
+ 0x2260, 0x1078, 0x874a, 0x027f, 0x0c7f, 0x7118, 0xa18c, 0xff00,
+ 0x810f, 0xa186, 0x0001, 0x0040, 0x92db, 0xa186, 0x0005, 0x0040,
+ 0x92d5, 0xa186, 0x0007, 0x00c0, 0x92e5, 0xa280, 0x0004, 0x2004,
+ 0xa005, 0x0040, 0x92e5, 0x057e, 0x7510, 0x7614, 0x1078, 0x9f46,
+ 0x057f, 0x0c7f, 0x0d7f, 0x0e7f, 0x007c, 0x6007, 0x003b, 0x602b,
+ 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x0078,
+ 0x92e1, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x1700, 0x6003,
+ 0x0001, 0x1078, 0x5bf8, 0x0078, 0x92e1, 0x6007, 0x003b, 0x602b,
+ 0x000b, 0x6013, 0x0000, 0x0078, 0x925d, 0x0e7e, 0x027e, 0x1078,
+ 0x4897, 0x0040, 0x933a, 0x1078, 0x4887, 0x1078, 0xa148, 0x00c0,
+ 0x9338, 0x2071, 0xa300, 0x70c8, 0xc085, 0x70ca, 0x0f7e, 0x2079,
+ 0x0100, 0x7294, 0xa284, 0x00ff, 0x706a, 0x78e6, 0xa284, 0xff00,
+ 0x726c, 0xa205, 0x706e, 0x78ea, 0x0f7f, 0x70d3, 0x0000, 0x2001,
+ 0xa352, 0x2004, 0xd0a4, 0x0040, 0x9331, 0x2011, 0xa5c4, 0x2013,
+ 0x07d0, 0xd0ac, 0x00c0, 0x933a, 0x1078, 0x260d, 0x0078, 0x933a,
+ 0x1078, 0xa178, 0x027f, 0x0e7f, 0x1078, 0x753d, 0x0078, 0x9199,
+ 0x1078, 0x753d, 0x007c, 0x0d7e, 0x067e, 0x6618, 0x2668, 0x6e04,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x9360, 0xa686,
+ 0x0004, 0x0040, 0x9360, 0x6e04, 0xa6b4, 0x00ff, 0xa686, 0x0006,
+ 0x0040, 0x9360, 0xa686, 0x0004, 0x0040, 0x9360, 0xa085, 0x0001,
+ 0x067f, 0x0d7f, 0x007c, 0x0d7e, 0x1078, 0x9397, 0x0d7f, 0x007c,
+ 0x0d7e, 0x1078, 0x93a6, 0x00c0, 0x9390, 0x680c, 0xa08c, 0xff00,
+ 0x6820, 0xa084, 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4,
+ 0x0040, 0x937e, 0x2009, 0x0001, 0x0078, 0x938c, 0xd1ec, 0x0040,
+ 0x9390, 0x6920, 0xa18c, 0x00ff, 0x6824, 0x1078, 0x24e3, 0x00c0,
+ 0x9390, 0x2110, 0x2009, 0x0000, 0x1078, 0x285b, 0x0078, 0x9394,
+ 0xa085, 0x0001, 0x0078, 0x9395, 0xa006, 0x0d7f, 0x007c, 0x2069,
+ 0xa88d, 0x6800, 0xa082, 0x0010, 0x00c8, 0x93a4, 0x6013, 0x0000,
+ 0xa085, 0x0001, 0x0078, 0x93a5, 0xa006, 0x007c, 0x6013, 0x0000,
+ 0x2069, 0xa88c, 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x00c0,
+ 0x93ba, 0x6800, 0xa084, 0x00ff, 0xa08e, 0x0014, 0x0040, 0x93ba,
+ 0xa08e, 0x0010, 0x007c, 0x6004, 0xa0b2, 0x0044, 0x10c8, 0x1328,
+ 0xa1b6, 0x0013, 0x00c0, 0x93c7, 0x2008, 0x0079, 0x93da, 0xa1b6,
+ 0x0027, 0x0040, 0x93cf, 0xa1b6, 0x0014, 0x10c0, 0x1328, 0x2001,
+ 0x0007, 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+ 0x6109, 0x007c, 0x941a, 0x941c, 0x941a, 0x941a, 0x941a, 0x941c,
+ 0x9424, 0x94ae, 0x9471, 0x94ae, 0x9485, 0x94ae, 0x9424, 0x94ae,
+ 0x94a6, 0x94ae, 0x94a6, 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a,
+ 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a,
+ 0x941c, 0x941a, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x941a, 0x94ae,
+ 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a,
+ 0x94ae, 0x94ae, 0x941a, 0x941a, 0x941a, 0x941a, 0x941a, 0x941c,
+ 0x94ae, 0x94ae, 0x941a, 0x941a, 0x94ae, 0x94ae, 0x941a, 0x941a,
+ 0x941a, 0x941a, 0x1078, 0x1328, 0x1078, 0x6010, 0x6003, 0x0002,
+ 0x1078, 0x6109, 0x0078, 0x94b4, 0x0f7e, 0x2079, 0xa351, 0x7804,
+ 0x0f7f, 0xd0ac, 0x00c0, 0x94ae, 0x2001, 0x0000, 0x1078, 0x442b,
+ 0x6018, 0xa080, 0x0004, 0x2004, 0xa086, 0x00ff, 0x0040, 0x94ae,
+ 0x0c7e, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x00c0, 0x9448, 0x6010,
+ 0xa005, 0x0040, 0x9448, 0x0c7f, 0x1078, 0x35f7, 0x0078, 0x94ae,
+ 0x0c7f, 0x2001, 0xa300, 0x2004, 0xa086, 0x0002, 0x00c0, 0x9457,
+ 0x0f7e, 0x2079, 0xa300, 0x788c, 0x8000, 0x788e, 0x0f7f, 0x2001,
+ 0x0002, 0x1078, 0x443f, 0x1078, 0x6010, 0x601f, 0x0001, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x1078, 0x5c45, 0x1078, 0x6109, 0x0c7e,
+ 0x6118, 0x2160, 0x2009, 0x0001, 0x1078, 0x58e1, 0x0c7f, 0x0078,
+ 0x94b4, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4, 0xff00,
+ 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0xa686, 0x0004, 0x0040,
+ 0x94ae, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0xa300, 0x2004,
+ 0xa086, 0x0003, 0x00c0, 0x948e, 0x1078, 0x35f7, 0x2001, 0x0006,
+ 0x1078, 0x94b5, 0x6618, 0x0d7e, 0x2668, 0x6e04, 0x0d7f, 0xa6b4,
+ 0xff00, 0x8637, 0xa686, 0x0006, 0x0040, 0x94ae, 0x2001, 0x0006,
+ 0x0078, 0x94ac, 0x2001, 0x0004, 0x0078, 0x94ac, 0x2001, 0x0006,
+ 0x1078, 0x94b5, 0x0078, 0x94ae, 0x1078, 0x4472, 0x1078, 0x6010,
+ 0x1078, 0x753d, 0x1078, 0x6109, 0x007c, 0x017e, 0x0d7e, 0x6118,
+ 0x2168, 0x6900, 0xd184, 0x0040, 0x94d0, 0x6104, 0xa18e, 0x000a,
+ 0x00c0, 0x94c8, 0x699c, 0xd1a4, 0x00c0, 0x94c8, 0x2001, 0x0007,
+ 0x1078, 0x443f, 0x2001, 0x0000, 0x1078, 0x442b, 0x1078, 0x2839,
+ 0x0d7f, 0x017f, 0x007c, 0x0d7e, 0x6618, 0x2668, 0x6804, 0xa084,
+ 0xff00, 0x8007, 0x0d7f, 0xa0b2, 0x000c, 0x10c8, 0x1328, 0xa1b6,
+ 0x0015, 0x00c0, 0x94e7, 0x1079, 0x94ee, 0x0078, 0x94ed, 0xa1b6,
+ 0x0016, 0x10c0, 0x1328, 0x1079, 0x94fa, 0x007c, 0x7ad0, 0x7ad0,
+ 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x9547, 0x9506, 0x7ad0, 0x7ad0,
+ 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0,
+ 0x9547, 0x954f, 0x7ad0, 0x7ad0, 0x7ad0, 0x7ad0, 0x0f7e, 0x2079,
+ 0xa351, 0x7804, 0xd0ac, 0x00c0, 0x952d, 0x6018, 0xa07d, 0x0040,
+ 0x952d, 0x7800, 0xd0f4, 0x00c0, 0x9519, 0x7810, 0xa005, 0x00c0,
+ 0x952d, 0x2001, 0x0000, 0x1078, 0x442b, 0x2001, 0x0002, 0x1078,
+ 0x443f, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x1078,
+ 0x5c45, 0x1078, 0x6109, 0x0078, 0x9545, 0x2011, 0xa883, 0x2204,
+ 0x8211, 0x220c, 0x1078, 0x24e3, 0x00c0, 0x9545, 0x0c7e, 0x1078,
+ 0x4501, 0x0040, 0x9540, 0x0c7f, 0x1078, 0x753d, 0x0078, 0x9545,
+ 0x1078, 0x4235, 0x0c7f, 0x1078, 0x753d, 0x0f7f, 0x007c, 0x6604,
+ 0xa6b6, 0x001e, 0x00c0, 0x954e, 0x1078, 0x753d, 0x007c, 0x1078,
+ 0x7d0a, 0x00c0, 0x955b, 0x6003, 0x0001, 0x6007, 0x0001, 0x1078,
+ 0x5c45, 0x0078, 0x955d, 0x1078, 0x753d, 0x007c, 0x6004, 0xa08a,
+ 0x0044, 0x10c8, 0x1328, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078,
+ 0x6109, 0x007c, 0xa182, 0x0040, 0x0079, 0x956e, 0x9581, 0x9581,
+ 0x9581, 0x9581, 0x9583, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+ 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581, 0x9581,
+ 0x9581, 0x1078, 0x1328, 0x0d7e, 0x0e7e, 0x0f7e, 0x157e, 0x047e,
+ 0x027e, 0x6218, 0xa280, 0x002b, 0x2004, 0xa005, 0x0040, 0x9594,
+ 0x2021, 0x0000, 0x1078, 0xa111, 0x6106, 0x2071, 0xa880, 0x7444,
+ 0xa4a4, 0xff00, 0x0040, 0x95eb, 0xa486, 0x2000, 0x00c0, 0x95a6,
+ 0x2009, 0x0001, 0x2011, 0x0200, 0x1078, 0x5a6d, 0x1078, 0x1381,
+ 0x1040, 0x1328, 0x6003, 0x0007, 0x2d00, 0x6837, 0x010d, 0x6803,
+ 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e, 0x6008, 0x68b2,
+ 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a, 0x017e, 0xa084,
+ 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036, 0x1078, 0x4982,
+ 0x017f, 0xa486, 0x2000, 0x00c0, 0x95d3, 0x2019, 0x0017, 0x1078,
+ 0x9e3b, 0x0078, 0x9645, 0xa486, 0x0400, 0x00c0, 0x95dd, 0x2019,
+ 0x0002, 0x1078, 0x9dec, 0x0078, 0x9645, 0xa486, 0x0200, 0x00c0,
+ 0x95e3, 0x1078, 0x9dd1, 0xa486, 0x1000, 0x00c0, 0x95e9, 0x1078,
+ 0x9e20, 0x0078, 0x9645, 0x2069, 0xa62d, 0x6a00, 0xd284, 0x0040,
+ 0x969b, 0xa284, 0x0300, 0x00c0, 0x9693, 0x6804, 0xa005, 0x0040,
+ 0x9683, 0x2d78, 0x6003, 0x0007, 0x1078, 0x1366, 0x0040, 0x964c,
+ 0x7800, 0xd08c, 0x00c0, 0x9607, 0x7804, 0x8001, 0x7806, 0x6013,
+ 0x0000, 0x6803, 0x0000, 0x6837, 0x0116, 0x683b, 0x0000, 0x6008,
+ 0x68b2, 0x2c00, 0x684a, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130,
+ 0x6986, 0x6846, 0x6853, 0x003d, 0x7244, 0xa294, 0x0003, 0xa286,
+ 0x0002, 0x00c0, 0x9627, 0x684f, 0x0040, 0x0078, 0x9631, 0xa286,
+ 0x0001, 0x00c0, 0x962f, 0x684f, 0x0080, 0x0078, 0x9631, 0x684f,
+ 0x0000, 0x20a9, 0x000a, 0x2001, 0xa890, 0xad90, 0x0015, 0x200c,
+ 0x810f, 0x2112, 0x8000, 0x8210, 0x00f0, 0x9637, 0x200c, 0x6982,
+ 0x8000, 0x200c, 0x697e, 0x1078, 0x4982, 0x027f, 0x047f, 0x157f,
+ 0x0f7f, 0x0e7f, 0x0d7f, 0x007c, 0x6013, 0x0100, 0x6003, 0x0001,
+ 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645,
+ 0x2069, 0xa892, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x00c0,
+ 0x9677, 0x2069, 0xa880, 0x686c, 0xa084, 0x00ff, 0x017e, 0x6110,
+ 0xa18c, 0x0700, 0xa10d, 0x6112, 0x017f, 0x6003, 0x0001, 0x6007,
+ 0x0043, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9645, 0x6013,
+ 0x0200, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+ 0x6109, 0x0078, 0x9645, 0x6013, 0x0300, 0x0078, 0x9689, 0x6013,
+ 0x0100, 0x6003, 0x0001, 0x6007, 0x0041, 0x1078, 0x5bf8, 0x1078,
+ 0x6109, 0x0078, 0x9645, 0x6013, 0x0500, 0x0078, 0x9689, 0x6013,
+ 0x0600, 0x0078, 0x9658, 0x6013, 0x0200, 0x0078, 0x9658, 0xa186,
+ 0x0013, 0x00c0, 0x96b1, 0x6004, 0xa08a, 0x0040, 0x1048, 0x1328,
+ 0xa08a, 0x0053, 0x10c8, 0x1328, 0xa082, 0x0040, 0x2008, 0x0079,
+ 0x9725, 0xa186, 0x0051, 0x0040, 0x96be, 0xa186, 0x0047, 0x00c0,
+ 0x96d7, 0x6004, 0xa086, 0x0041, 0x0040, 0x96e5, 0x2001, 0x0109,
+ 0x2004, 0xd084, 0x0040, 0x96e5, 0x127e, 0x2091, 0x2200, 0x007e,
+ 0x017e, 0x027e, 0x1078, 0x5ad2, 0x027f, 0x017f, 0x007f, 0x127f,
+ 0x6000, 0xa086, 0x0002, 0x00c0, 0x96e5, 0x0078, 0x976a, 0xa186,
+ 0x0027, 0x0040, 0x96df, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6004,
+ 0xa082, 0x0040, 0x2008, 0x0079, 0x96e8, 0x1078, 0x7583, 0x007c,
+ 0x96fb, 0x96fd, 0x96fd, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+ 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb, 0x96fb,
+ 0x96fb, 0x96fb, 0x96fb, 0x1078, 0x1328, 0x1078, 0x6010, 0x1078,
+ 0x6109, 0x037e, 0x0d7e, 0x6010, 0xa06d, 0x0040, 0x9722, 0xad84,
+ 0xf000, 0x0040, 0x9722, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc,
+ 0x00c0, 0x9722, 0x2019, 0x0004, 0x1078, 0x9e70, 0x6013, 0x0000,
+ 0x6014, 0xa005, 0x00c0, 0x9720, 0x2001, 0xa5a1, 0x2004, 0x6016,
+ 0x6003, 0x0007, 0x0d7f, 0x037f, 0x007c, 0x9738, 0x9757, 0x9741,
+ 0x9764, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+ 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738, 0x9738,
+ 0x1078, 0x1328, 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400,
+ 0x200a, 0x1078, 0x6010, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4,
+ 0x0040, 0x9752, 0x6003, 0x0007, 0x2009, 0x0043, 0x1078, 0x756c,
+ 0x0078, 0x9754, 0x6003, 0x0002, 0x1078, 0x6109, 0x007c, 0x1078,
+ 0x6010, 0x1078, 0xa0c6, 0x00c0, 0x9761, 0x1078, 0x5a41, 0x1078,
+ 0x753d, 0x1078, 0x6109, 0x007c, 0x1078, 0x6010, 0x2009, 0x0041,
+ 0x0078, 0x98c1, 0xa182, 0x0040, 0x0079, 0x976e, 0x9781, 0x9783,
+ 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9784, 0x9781, 0x9781,
+ 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x9781, 0x978f,
+ 0x9781, 0x1078, 0x1328, 0x007c, 0x6003, 0x0004, 0x6110, 0x20e1,
+ 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x1078, 0x15ec, 0x007c, 0x0d7e,
+ 0x1078, 0x5a41, 0x0d7f, 0x1078, 0xa134, 0x1078, 0x753d, 0x007c,
+ 0xa182, 0x0040, 0x0079, 0x979c, 0x97af, 0x97af, 0x97af, 0x97af,
+ 0x97af, 0x97af, 0x97af, 0x97b1, 0x97af, 0x97b4, 0x97df, 0x97af,
+ 0x97af, 0x97af, 0x97af, 0x97df, 0x97af, 0x97af, 0x97af, 0x1078,
+ 0x1328, 0x1078, 0x7583, 0x007c, 0x1078, 0x60b8, 0x1078, 0x61d3,
+ 0x6010, 0x0d7e, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x97ca, 0xa08c,
+ 0x0003, 0xa18e, 0x0002, 0x0040, 0x97d2, 0x2009, 0x0041, 0x0d7f,
+ 0x0078, 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41,
+ 0x0d7f, 0x007c, 0x1078, 0xa0c6, 0x0040, 0x97d8, 0x0d7f, 0x007c,
+ 0x1078, 0x5a41, 0x1078, 0x753d, 0x0d7f, 0x0078, 0x97d1, 0x037e,
+ 0x1078, 0x60b8, 0x1078, 0x61d3, 0x6010, 0x0d7e, 0x2068, 0x6018,
+ 0x2004, 0xd0bc, 0x0040, 0x97ff, 0x684c, 0xa084, 0x0003, 0xa086,
+ 0x0002, 0x0040, 0x97fb, 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880,
+ 0x6328, 0xa31b, 0x632a, 0x6003, 0x0002, 0x0078, 0x9810, 0x2019,
+ 0x0004, 0x1078, 0x9e70, 0x6014, 0xa005, 0x00c0, 0x980c, 0x2001,
+ 0xa5a1, 0x2004, 0x8003, 0x6016, 0x6013, 0x0000, 0x6003, 0x0007,
+ 0x0d7f, 0x037f, 0x007c, 0xa186, 0x0013, 0x00c0, 0x9821, 0x6004,
+ 0xa086, 0x0042, 0x10c0, 0x1328, 0x1078, 0x6010, 0x1078, 0x6109,
+ 0x007c, 0xa186, 0x0027, 0x0040, 0x9829, 0xa186, 0x0014, 0x00c0,
+ 0x9839, 0x6004, 0xa086, 0x0042, 0x10c0, 0x1328, 0x2001, 0x0007,
+ 0x1078, 0x4472, 0x1078, 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109,
+ 0x007c, 0xa182, 0x0040, 0x0079, 0x983d, 0x9850, 0x9850, 0x9850,
+ 0x9850, 0x9850, 0x9850, 0x9850, 0x9852, 0x985e, 0x9850, 0x9850,
+ 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850, 0x9850,
+ 0x1078, 0x1328, 0x037e, 0x047e, 0x20e1, 0x0005, 0x3d18, 0x3e20,
+ 0x2c10, 0x1078, 0x15ec, 0x047f, 0x037f, 0x007c, 0x6010, 0x0d7e,
+ 0x2068, 0x6810, 0x6a14, 0x6118, 0x210c, 0xd1bc, 0x0040, 0x987d,
+ 0x6124, 0xd1f4, 0x00c0, 0x987d, 0x007e, 0x047e, 0x057e, 0x6c7c,
+ 0xa422, 0x6d80, 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028,
+ 0xa529, 0x652a, 0x057f, 0x047f, 0x007f, 0xa20d, 0x00c0, 0x9891,
+ 0x684c, 0xd0fc, 0x0040, 0x9889, 0x2009, 0x0041, 0x0d7f, 0x0078,
+ 0x98c1, 0x6003, 0x0007, 0x6017, 0x0000, 0x1078, 0x5a41, 0x0d7f,
+ 0x007c, 0x007e, 0x0f7e, 0x2c78, 0x1078, 0x4893, 0x0f7f, 0x007f,
+ 0x0040, 0x989e, 0x6003, 0x0002, 0x0d7f, 0x007c, 0x2009, 0xa30d,
+ 0x210c, 0xd19c, 0x0040, 0x98a8, 0x6003, 0x0007, 0x0078, 0x98aa,
+ 0x6003, 0x0006, 0x1078, 0x98b0, 0x1078, 0x5a43, 0x0d7f, 0x007c,
+ 0xd2fc, 0x0040, 0x98bc, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000,
+ 0x2009, 0x0009, 0x0078, 0x98be, 0x2009, 0x0015, 0x6a6a, 0x6866,
+ 0x007c, 0xa182, 0x0040, 0x0048, 0x98c7, 0x0079, 0x98d4, 0xa186,
+ 0x0013, 0x0040, 0x98cf, 0xa186, 0x0014, 0x10c0, 0x1328, 0x6024,
+ 0xd0dc, 0x1040, 0x1328, 0x007c, 0x98e7, 0x98ee, 0x98fa, 0x9906,
+ 0x98e7, 0x98e7, 0x98e7, 0x9915, 0x98e7, 0x98e9, 0x98e9, 0x98e7,
+ 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x98e7, 0x1078,
+ 0x1328, 0x6024, 0xd0dc, 0x1040, 0x1328, 0x007c, 0x6003, 0x0001,
+ 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091, 0x8000, 0x1078, 0x6109,
+ 0x127f, 0x007c, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x127e,
+ 0x2091, 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x6003, 0x0003,
+ 0x6106, 0x2c10, 0x1078, 0x1cab, 0x127e, 0x2091, 0x8000, 0x1078,
+ 0x5c64, 0x1078, 0x61d3, 0x127f, 0x007c, 0xa016, 0x1078, 0x15ec,
+ 0x007c, 0x127e, 0x2091, 0x8000, 0x037e, 0x0d7e, 0xa182, 0x0040,
+ 0x1079, 0x9926, 0x0d7f, 0x037f, 0x127f, 0x007c, 0x9936, 0x9938,
+ 0x994d, 0x996c, 0x9936, 0x9936, 0x9936, 0x9984, 0x9936, 0x9936,
+ 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x9936, 0x1078, 0x1328,
+ 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003,
+ 0xa39e, 0x0003, 0x0040, 0x9962, 0x6003, 0x0001, 0x6106, 0x1078,
+ 0x5bf8, 0x1078, 0x6109, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c,
+ 0xd0fc, 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040,
+ 0x9962, 0x6003, 0x0001, 0x6106, 0x1078, 0x5bf8, 0x1078, 0x6109,
+ 0x0078, 0x9987, 0x6013, 0x0000, 0x6017, 0x0000, 0x2019, 0x0004,
+ 0x1078, 0x9e70, 0x0078, 0x9987, 0x6010, 0x2068, 0x684c, 0xd0fc,
+ 0x0040, 0x9962, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0040, 0x9962,
+ 0x6003, 0x0003, 0x6106, 0x2c10, 0x1078, 0x1cab, 0x1078, 0x5c64,
+ 0x1078, 0x61d3, 0x0078, 0x9987, 0xa016, 0x1078, 0x15ec, 0x007c,
+ 0x1078, 0x6010, 0x6110, 0x81ff, 0x0040, 0x9999, 0x0d7e, 0x2168,
+ 0x1078, 0xa181, 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f,
+ 0x0d7f, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x1078, 0x60b8,
+ 0x6110, 0x81ff, 0x0040, 0x99af, 0x0d7e, 0x2168, 0x1078, 0xa181,
+ 0x037e, 0x2019, 0x0029, 0x1078, 0x9e70, 0x037f, 0x0d7f, 0x1078,
+ 0x8c01, 0x1078, 0x61d3, 0x007c, 0xa182, 0x0085, 0x0079, 0x99b8,
+ 0x99c1, 0x99bf, 0x99bf, 0x99cd, 0x99bf, 0x99bf, 0x99bf, 0x1078,
+ 0x1328, 0x6003, 0x000b, 0x6106, 0x1078, 0x5bf8, 0x127e, 0x2091,
+ 0x8000, 0x1078, 0x6109, 0x127f, 0x007c, 0x027e, 0x0e7e, 0x1078,
+ 0xa0bf, 0x0040, 0x99d7, 0x1078, 0x753d, 0x0078, 0x99f3, 0x2071,
+ 0xa880, 0x7224, 0x6212, 0x7220, 0x1078, 0x9d10, 0x0040, 0x99e4,
+ 0x6007, 0x0086, 0x0078, 0x99ed, 0x6007, 0x0087, 0x7224, 0xa296,
+ 0xffff, 0x00c0, 0x99ed, 0x6007, 0x0086, 0x6003, 0x0001, 0x1078,
+ 0x5bf8, 0x1078, 0x6109, 0x0e7f, 0x027f, 0x007c, 0xa186, 0x0013,
+ 0x00c0, 0x9a07, 0x6004, 0xa08a, 0x0085, 0x1048, 0x1328, 0xa08a,
+ 0x008c, 0x10c8, 0x1328, 0xa082, 0x0085, 0x0079, 0x9a1e, 0xa186,
+ 0x0027, 0x0040, 0x9a13, 0xa186, 0x0014, 0x0040, 0x9a13, 0x1078,
+ 0x7583, 0x0078, 0x9a1d, 0x2001, 0x0007, 0x1078, 0x4472, 0x1078,
+ 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0x9a25, 0x9a27,
+ 0x9a27, 0x9a25, 0x9a25, 0x9a25, 0x9a25, 0x1078, 0x1328, 0x1078,
+ 0x6010, 0x1078, 0x8c01, 0x1078, 0x6109, 0x007c, 0xa182, 0x0085,
+ 0x1048, 0x1328, 0xa182, 0x008c, 0x10c8, 0x1328, 0xa182, 0x0085,
+ 0x0079, 0x9a3a, 0x9a41, 0x9a41, 0x9a41, 0x9a43, 0x9a41, 0x9a41,
+ 0x9a41, 0x1078, 0x1328, 0x007c, 0xa186, 0x0013, 0x0040, 0x9a54,
+ 0xa186, 0x0014, 0x0040, 0x9a54, 0xa186, 0x0027, 0x0040, 0x9a54,
+ 0x1078, 0x7583, 0x0078, 0x9a5a, 0x1078, 0x6010, 0x1078, 0x8c01,
+ 0x1078, 0x6109, 0x007c, 0x037e, 0x1078, 0xa134, 0x603f, 0x0000,
+ 0x2019, 0x000b, 0x1078, 0x9a6a, 0x601f, 0x0006, 0x6003, 0x0007,
+ 0x037f, 0x007c, 0x127e, 0x037e, 0x2091, 0x8000, 0x087e, 0x2c40,
+ 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x00c0,
+ 0x9aa5, 0x077e, 0x2c38, 0x1078, 0x7105, 0x077f, 0x00c0, 0x9aa5,
+ 0x6000, 0xa086, 0x0000, 0x0040, 0x9aa5, 0x601c, 0xa086, 0x0007,
+ 0x0040, 0x9aa5, 0x0d7e, 0x6000, 0xa086, 0x0004, 0x00c0, 0x9a96,
+ 0x1078, 0xa134, 0x601f, 0x0007, 0x1078, 0x1749, 0x6010, 0x2068,
+ 0x1078, 0x8a44, 0x0040, 0x9a9e, 0x1078, 0x9e70, 0x0d7f, 0x6013,
+ 0x0000, 0x1078, 0xa134, 0x601f, 0x0007, 0x037f, 0x127f, 0x007c,
+ 0x0f7e, 0x0c7e, 0x037e, 0x157e, 0x2079, 0xa880, 0x7938, 0x783c,
+ 0x1078, 0x24e3, 0x00c0, 0x9af6, 0x017e, 0x0c7e, 0x1078, 0x4501,
+ 0x00c0, 0x9af6, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9, 0x0004,
+ 0x1078, 0x7e55, 0x00c0, 0x9af6, 0x017f, 0x027f, 0x027e, 0x017e,
+ 0x2019, 0x0029, 0x1078, 0x71e0, 0x1078, 0x5d53, 0x077e, 0x2039,
+ 0x0000, 0x1078, 0x5c78, 0x077f, 0x017f, 0x077e, 0x2039, 0x0000,
+ 0x1078, 0x9c38, 0x077f, 0x1078, 0x471b, 0x027e, 0x6204, 0xa294,
+ 0xff00, 0x8217, 0xa286, 0x0006, 0x0040, 0x9aea, 0xa286, 0x0004,
+ 0x00c0, 0x9aed, 0x62a0, 0x1078, 0x28d5, 0x027f, 0x017f, 0x1078,
+ 0x4235, 0x6612, 0x6516, 0xa006, 0x0078, 0x9af8, 0x0c7f, 0x017f,
+ 0x157f, 0x037f, 0x0c7f, 0x0f7f, 0x007c, 0x0c7e, 0x0d7e, 0x0e7e,
+ 0x017e, 0x2009, 0xa31f, 0x2104, 0xa086, 0x0074, 0x00c0, 0x9b60,
+ 0x2069, 0xa88e, 0x690c, 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908,
+ 0xa184, 0x8000, 0x0040, 0x9b5c, 0x6018, 0x2070, 0x7010, 0xa084,
+ 0x00ff, 0x0040, 0x9b1f, 0x7000, 0xd0f4, 0x0040, 0x9b23, 0xa184,
+ 0x0800, 0x0040, 0x9b5c, 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54,
+ 0x6914, 0x2069, 0xa8ae, 0x6904, 0x81ff, 0x00c0, 0x9b48, 0x690c,
+ 0xa182, 0x0100, 0x0048, 0x9b50, 0x6908, 0x81ff, 0x00c0, 0x9b4c,
+ 0x6910, 0xa18a, 0x0001, 0x0048, 0x9b54, 0x6918, 0xa18a, 0x0001,
+ 0x0048, 0x9b5c, 0x0078, 0x9b66, 0x6013, 0x0100, 0x0078, 0x9b62,
+ 0x6013, 0x0300, 0x0078, 0x9b62, 0x6013, 0x0500, 0x0078, 0x9b62,
+ 0x6013, 0x0700, 0x0078, 0x9b62, 0x6013, 0x0900, 0x0078, 0x9b62,
+ 0x6013, 0x0b00, 0x0078, 0x9b62, 0x6013, 0x0f00, 0x0078, 0x9b62,
+ 0x6013, 0x2d00, 0xa085, 0x0001, 0x0078, 0x9b67, 0xa006, 0x017f,
+ 0x0e7f, 0x0d7f, 0x0c7f, 0x007c, 0x0c7e, 0x0d7e, 0x027e, 0x037e,
+ 0x157e, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff, 0xa286, 0x0006,
+ 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040, 0x9b90, 0xa394, 0xff00,
+ 0x8217, 0xa286, 0x0006, 0x0040, 0x9b90, 0xa286, 0x0004, 0x0040,
+ 0x9b90, 0x0c7e, 0x2d60, 0x1078, 0x4513, 0x0c7f, 0x0078, 0x9bcb,
+ 0x2011, 0xa896, 0xad98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55,
+ 0x00c0, 0x9bcc, 0x2011, 0xa89a, 0xad98, 0x0006, 0x20a9, 0x0004,
+ 0x1078, 0x7e55, 0x00c0, 0x9bcc, 0x047e, 0x017e, 0x6aa0, 0xa294,
+ 0x00ff, 0x8227, 0xa006, 0x2009, 0xa352, 0x210c, 0xd1a4, 0x0040,
+ 0x9bb8, 0x2009, 0x0029, 0x1078, 0x9ec0, 0x6800, 0xc0e5, 0x6802,
+ 0x2019, 0x0029, 0x1078, 0x5d53, 0x077e, 0x2039, 0x0000, 0x1078,
+ 0x5c78, 0x2c08, 0x1078, 0x9c38, 0x077f, 0x2001, 0x0007, 0x1078,
+ 0x4472, 0x017f, 0x047f, 0xa006, 0x157f, 0x037f, 0x027f, 0x0d7f,
+ 0x0c7f, 0x007c, 0x0d7e, 0x2069, 0xa88e, 0x6800, 0xa086, 0x0800,
+ 0x0040, 0x9bde, 0x6013, 0x0000, 0x0078, 0x9bdf, 0xa006, 0x0d7f,
+ 0x007c, 0x0c7e, 0x0f7e, 0x017e, 0x027e, 0x037e, 0x157e, 0x2079,
+ 0xa88c, 0x7930, 0x7834, 0x1078, 0x24e3, 0x00c0, 0x9c05, 0x1078,
+ 0x4501, 0x00c0, 0x9c05, 0x2011, 0xa890, 0xac98, 0x000a, 0x20a9,
+ 0x0004, 0x1078, 0x7e55, 0x00c0, 0x9c05, 0x2011, 0xa894, 0xac98,
+ 0x0006, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x157f, 0x037f, 0x027f,
+ 0x017f, 0x0f7f, 0x0c7f, 0x007c, 0x0c7e, 0x007e, 0x017e, 0x027e,
+ 0x037e, 0x157e, 0x2011, 0xa883, 0x2204, 0x8211, 0x220c, 0x1078,
+ 0x24e3, 0x00c0, 0x9c31, 0x1078, 0x4501, 0x00c0, 0x9c31, 0x2011,
+ 0xa896, 0xac98, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+ 0x9c31, 0x2011, 0xa89a, 0xac98, 0x0006, 0x20a9, 0x0004, 0x1078,
+ 0x7e55, 0x157f, 0x037f, 0x027f, 0x017f, 0x007f, 0x0c7f, 0x007c,
+ 0x0e7e, 0x0c7e, 0x087e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e,
+ 0x127e, 0x2091, 0x8000, 0x2740, 0x2029, 0xa5b4, 0x252c, 0x2021,
+ 0xa5ba, 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060,
+ 0x81ff, 0x0040, 0x9c59, 0x8001, 0xa602, 0x00c8, 0x9cc3, 0x0078,
+ 0x9c5c, 0xa606, 0x0040, 0x9cc3, 0x2100, 0xac06, 0x0040, 0x9cb9,
+ 0x1078, 0x9ee5, 0x0040, 0x9cb9, 0x671c, 0xa786, 0x0001, 0x0040,
+ 0x9cde, 0xa786, 0x0004, 0x0040, 0x9cde, 0xa786, 0x0007, 0x0040,
+ 0x9cb9, 0x2500, 0xac06, 0x0040, 0x9cb9, 0x2400, 0xac06, 0x0040,
+ 0x9cb9, 0x1078, 0x9ef9, 0x00c0, 0x9cb9, 0x88ff, 0x0040, 0x9c84,
+ 0x6020, 0xa906, 0x00c0, 0x9cb9, 0x0d7e, 0x6000, 0xa086, 0x0004,
+ 0x00c0, 0x9c8e, 0x017e, 0x1078, 0x1749, 0x017f, 0xa786, 0x0008,
+ 0x00c0, 0x9c9d, 0x1078, 0x8c3b, 0x00c0, 0x9c9d, 0x1078, 0x7a05,
+ 0x0d7f, 0x1078, 0x8c01, 0x0078, 0x9cb9, 0x6010, 0x2068, 0x1078,
+ 0x8a44, 0x0040, 0x9cb6, 0xa786, 0x0003, 0x00c0, 0x9ccd, 0x6837,
+ 0x0103, 0x6b4a, 0x6847, 0x0000, 0x1078, 0xa181, 0x017e, 0x1078,
+ 0x8cb8, 0x1078, 0x4982, 0x017f, 0x1078, 0x8bf4, 0x0d7f, 0x1078,
+ 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+ 0x9cc3, 0x0078, 0x9c4c, 0x127f, 0x027f, 0x047f, 0x057f, 0x067f,
+ 0x077f, 0x087f, 0x0c7f, 0x0e7f, 0x007c, 0xa786, 0x0006, 0x00c0,
+ 0x9ca7, 0xa386, 0x0005, 0x0040, 0x9cdb, 0x1078, 0xa181, 0x1078,
+ 0x9e70, 0x0078, 0x9cb6, 0x0d7f, 0x0078, 0x9cb9, 0x1078, 0x9ef9,
+ 0x00c0, 0x9cb9, 0x81ff, 0x0040, 0x9cb9, 0xa180, 0x0001, 0x2004,
+ 0xa086, 0x0018, 0x0040, 0x9cf3, 0xa180, 0x0001, 0x2004, 0xa086,
+ 0x002d, 0x00c0, 0x9cb9, 0x6000, 0xa086, 0x0002, 0x00c0, 0x9cb9,
+ 0x1078, 0x8c27, 0x0040, 0x9d04, 0x1078, 0x8c3b, 0x00c0, 0x9cb9,
+ 0x1078, 0x7a05, 0x0078, 0x9d0c, 0x1078, 0x2839, 0x1078, 0x8c3b,
+ 0x00c0, 0x9d0c, 0x1078, 0x7a05, 0x1078, 0x8c01, 0x0078, 0x9cb9,
+ 0x0c7e, 0x0e7e, 0x017e, 0x2c08, 0x2170, 0x1078, 0x9e8c, 0x017f,
+ 0x0040, 0x9d1f, 0x601c, 0xa084, 0x000f, 0x1079, 0x9d22, 0x0e7f,
+ 0x0c7f, 0x007c, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a, 0x9d2a,
+ 0x9d2c, 0x9d2a, 0xa006, 0x007c, 0x047e, 0x017e, 0x7018, 0xa080,
+ 0x0028, 0x2024, 0xa4a4, 0x00ff, 0x8427, 0x2c00, 0x2009, 0x0020,
+ 0x1078, 0x9ec0, 0x017f, 0x047f, 0x037e, 0x2019, 0x0002, 0x1078,
+ 0x9a6a, 0x037f, 0xa085, 0x0001, 0x007c, 0x2001, 0x0001, 0x1078,
+ 0x442b, 0x157e, 0x017e, 0x027e, 0x037e, 0x20a9, 0x0004, 0x2019,
+ 0xa305, 0x2011, 0xa896, 0x1078, 0x7e55, 0x037f, 0x027f, 0x017f,
+ 0x157f, 0xa005, 0x007c, 0x0f7e, 0x0e7e, 0x0c7e, 0x087e, 0x077e,
+ 0x067e, 0x027e, 0x127e, 0x2091, 0x8000, 0x2740, 0x2061, 0xaa00,
+ 0x2079, 0x0001, 0x8fff, 0x0040, 0x9dc3, 0x2071, 0xa300, 0x7644,
+ 0x7060, 0x8001, 0xa602, 0x00c8, 0x9dc3, 0x88ff, 0x0040, 0x9d7e,
+ 0x2800, 0xac06, 0x00c0, 0x9db9, 0x2079, 0x0000, 0x1078, 0x9ee5,
+ 0x0040, 0x9db9, 0x2400, 0xac06, 0x0040, 0x9db9, 0x671c, 0xa786,
+ 0x0006, 0x00c0, 0x9db9, 0xa786, 0x0007, 0x0040, 0x9db9, 0x88ff,
+ 0x00c0, 0x9d9d, 0x6018, 0xa206, 0x00c0, 0x9db9, 0x85ff, 0x0040,
+ 0x9d9d, 0x6020, 0xa106, 0x00c0, 0x9db9, 0x0d7e, 0x6000, 0xa086,
+ 0x0004, 0x00c0, 0x9da9, 0x1078, 0xa134, 0x601f, 0x0007, 0x1078,
+ 0x1749, 0x6010, 0x2068, 0x1078, 0x8a44, 0x0040, 0x9db3, 0x047e,
+ 0x1078, 0x9e70, 0x047f, 0x0d7f, 0x1078, 0x8c01, 0x88ff, 0x00c0,
+ 0x9dcd, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02, 0x00c8,
+ 0x9dc3, 0x0078, 0x9d6a, 0xa006, 0x127f, 0x027f, 0x067f, 0x077f,
+ 0x087f, 0x0c7f, 0x0e7f, 0x0f7f, 0x007c, 0xa8c5, 0x0001, 0x0078,
+ 0x9dc4, 0x077e, 0x057e, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+ 0x2c20, 0x2019, 0x0002, 0x6218, 0x097e, 0x2049, 0x0000, 0x1078,
+ 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x1078,
+ 0x9d5b, 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e,
+ 0x0c7e, 0x157e, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009, 0x0000,
+ 0x017e, 0x037e, 0x1078, 0x4501, 0x00c0, 0x9e14, 0x2c10, 0x057e,
+ 0x087e, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x097e, 0x2049,
+ 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000, 0x1078,
+ 0x7105, 0x1078, 0x9d5b, 0x057f, 0x037f, 0x017f, 0x8108, 0x00f0,
+ 0x9df8, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+ 0x077e, 0x057e, 0x6218, 0x087e, 0x2041, 0x0000, 0x2029, 0x0001,
+ 0x2019, 0x0048, 0x097e, 0x2049, 0x0000, 0x1078, 0x7058, 0x097f,
+ 0x087f, 0x2039, 0x0000, 0x1078, 0x7105, 0x2c20, 0x1078, 0x9d5b,
+ 0x057f, 0x077f, 0x007c, 0x027e, 0x047e, 0x057e, 0x077e, 0x0c7e,
+ 0x157e, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x017e, 0x037e,
+ 0x1078, 0x4501, 0x00c0, 0x9e64, 0x2c10, 0x087e, 0x2041, 0x0000,
+ 0x2828, 0x047e, 0x2021, 0x0001, 0x1078, 0xa111, 0x047f, 0x097e,
+ 0x2049, 0x0000, 0x1078, 0x7058, 0x097f, 0x087f, 0x2039, 0x0000,
+ 0x1078, 0x7105, 0x1078, 0x9d5b, 0x037f, 0x017f, 0x8108, 0x00f0,
+ 0x9e46, 0x157f, 0x0c7f, 0x077f, 0x057f, 0x047f, 0x027f, 0x007c,
+ 0x017e, 0x0f7e, 0xad82, 0xca00, 0x0048, 0x9e89, 0xad82, 0xffff,
+ 0x00c8, 0x9e89, 0x6800, 0xa07d, 0x0040, 0x9e86, 0x6803, 0x0000,
+ 0x6b52, 0x1078, 0x4982, 0x2f68, 0x0078, 0x9e7a, 0x6b52, 0x1078,
+ 0x4982, 0x0f7f, 0x017f, 0x007c, 0x0e7e, 0x047e, 0x037e, 0x2061,
+ 0xaa00, 0x2071, 0xa300, 0x7444, 0x7060, 0x8001, 0xa402, 0x00c8,
+ 0x9ebb, 0x2100, 0xac06, 0x0040, 0x9ead, 0x6000, 0xa086, 0x0000,
+ 0x0040, 0x9ead, 0x6008, 0xa206, 0x00c0, 0x9ead, 0x6018, 0xa1a0,
+ 0x0006, 0x2424, 0xa406, 0x0040, 0x9eb7, 0xace0, 0x0010, 0x2001,
+ 0xa315, 0x2004, 0xac02, 0x00c8, 0x9ebb, 0x0078, 0x9e91, 0xa085,
+ 0x0001, 0x0078, 0x9ebc, 0xa006, 0x037f, 0x047f, 0x0e7f, 0x007c,
+ 0x0d7e, 0x007e, 0x1078, 0x1381, 0x007f, 0x1040, 0x1328, 0x6837,
+ 0x010d, 0x685e, 0x027e, 0x2010, 0x1078, 0x8a30, 0x2001, 0x0000,
+ 0x0040, 0x9ed6, 0x2200, 0xa080, 0x0008, 0x2004, 0x027f, 0x684a,
+ 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006, 0x68b2, 0x6802, 0x683a,
+ 0x685a, 0x1078, 0x4982, 0x0d7f, 0x007c, 0x6700, 0xa786, 0x0000,
+ 0x0040, 0x9ef8, 0xa786, 0x0001, 0x0040, 0x9ef8, 0xa786, 0x000a,
+ 0x0040, 0x9ef8, 0xa786, 0x0009, 0x0040, 0x9ef8, 0xa085, 0x0001,
+ 0x007c, 0x0e7e, 0x6018, 0x2070, 0x70a0, 0xa206, 0x0e7f, 0x007c,
+ 0x017e, 0x6004, 0xa08e, 0x001e, 0x00c0, 0x9f1a, 0x8007, 0x6130,
+ 0xa18c, 0x00ff, 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b,
+ 0x601f, 0x0005, 0x2001, 0xa5a1, 0x2004, 0x6016, 0x1078, 0x5bf8,
+ 0x1078, 0x6109, 0x017f, 0x007c, 0x0005, 0x0005, 0x007c, 0x6024,
+ 0xd0e4, 0x0040, 0x9f30, 0xd0cc, 0x0040, 0x9f2a, 0x1078, 0x8cfa,
+ 0x0078, 0x9f30, 0x1078, 0xa134, 0x1078, 0x5a41, 0x1078, 0x753d,
+ 0x007c, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f, 0x0079, 0x9f38,
+ 0x9f41, 0x9f41, 0x9f41, 0x9f43, 0x9f41, 0x9f43, 0x9f43, 0x9f41,
+ 0x9f43, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa280, 0x0007,
+ 0x2004, 0xa084, 0x000f, 0x0079, 0x9f4d, 0x9f56, 0x9f56, 0x9f56,
+ 0x9f56, 0x9f56, 0x9f56, 0x9f61, 0x9f56, 0x9f56, 0x6007, 0x003b,
+ 0x602b, 0x0009, 0x6013, 0x2a00, 0x6003, 0x0001, 0x1078, 0x5bf8,
+ 0x007c, 0x0c7e, 0x2260, 0x1078, 0xa134, 0x603f, 0x0000, 0x6024,
+ 0xc0f4, 0xc0cc, 0x6026, 0x0c7f, 0x0d7e, 0x2268, 0xa186, 0x0007,
+ 0x00c0, 0x9fc2, 0x6810, 0xa005, 0x0040, 0x9f7f, 0xa080, 0x0013,
+ 0x2004, 0xd0fc, 0x00c0, 0x9f7f, 0x0d7f, 0x0078, 0x9f56, 0x6007,
+ 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109, 0x0c7e,
+ 0x2d60, 0x6100, 0xa186, 0x0002, 0x00c0, 0xa050, 0x6010, 0xa005,
+ 0x00c0, 0x9f99, 0x6000, 0xa086, 0x0007, 0x10c0, 0x1328, 0x0078,
+ 0xa050, 0xa08c, 0xf000, 0x00c0, 0x9fa5, 0x0078, 0x9fa5, 0x2068,
+ 0x6800, 0xa005, 0x00c0, 0x9f9f, 0x2d00, 0xa080, 0x0013, 0x2004,
+ 0xa084, 0x0003, 0xa086, 0x0002, 0x00c0, 0x9fbe, 0x6010, 0x2068,
+ 0x684c, 0xc0dc, 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852,
+ 0x2009, 0x0043, 0x1078, 0x98c1, 0x0078, 0xa050, 0x2009, 0x0041,
+ 0x0078, 0xa04a, 0xa186, 0x0005, 0x00c0, 0xa009, 0x6810, 0xa080,
+ 0x0013, 0x2004, 0xd0bc, 0x00c0, 0x9fd0, 0x0d7f, 0x0078, 0x9f56,
+ 0xd0b4, 0x0040, 0x9fd8, 0xd0fc, 0x1040, 0x1328, 0x0078, 0x9f72,
+ 0x6007, 0x003a, 0x6003, 0x0001, 0x1078, 0x5bf8, 0x1078, 0x6109,
+ 0x0c7e, 0x2d60, 0x6100, 0xa186, 0x0002, 0x0040, 0x9feb, 0xa186,
+ 0x0004, 0x00c0, 0xa050, 0x2071, 0xa5e1, 0x7000, 0xa086, 0x0003,
+ 0x00c0, 0x9ff8, 0x7004, 0xac06, 0x00c0, 0x9ff8, 0x7003, 0x0000,
+ 0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+ 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0078,
+ 0xa04a, 0x037e, 0x0d7e, 0x0d7e, 0x1078, 0x1381, 0x037f, 0x1040,
+ 0x1328, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+ 0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+ 0x2360, 0x6024, 0xc0dd, 0x6026, 0x6018, 0xa080, 0x0028, 0x2004,
+ 0xa084, 0x00ff, 0x8007, 0x6320, 0x6b4a, 0x6846, 0x684f, 0x0000,
+ 0x6d6a, 0x6e66, 0x686f, 0x0001, 0x1078, 0x4982, 0x2019, 0x0045,
+ 0x6008, 0x2068, 0x1078, 0x9a6a, 0x2d00, 0x600a, 0x601f, 0x0006,
+ 0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x0d7f, 0x037f,
+ 0x0078, 0xa051, 0x603f, 0x0000, 0x6003, 0x0007, 0x1078, 0x98c1,
+ 0x0c7f, 0x0d7f, 0x007c, 0xa186, 0x0013, 0x00c0, 0xa05d, 0x6004,
+ 0xa082, 0x0085, 0x2008, 0x0079, 0xa077, 0xa186, 0x0027, 0x00c0,
+ 0xa070, 0x1078, 0x6010, 0x037e, 0x0d7e, 0x6010, 0x2068, 0x2019,
+ 0x0004, 0x1078, 0x9e70, 0x0d7f, 0x037f, 0x1078, 0x6109, 0x007c,
+ 0xa186, 0x0014, 0x0040, 0xa061, 0x1078, 0x7583, 0x007c, 0xa080,
+ 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa07e, 0xa080, 0x1078, 0x1328,
+ 0x1078, 0x6010, 0x6003, 0x000c, 0x1078, 0x6109, 0x007c, 0xa182,
+ 0x008c, 0x00c8, 0xa091, 0xa182, 0x0085, 0x0048, 0xa091, 0x0079,
+ 0xa094, 0x1078, 0x7583, 0x007c, 0xa09b, 0xa09b, 0xa09b, 0xa09b,
+ 0xa09d, 0xa0bc, 0xa09b, 0x1078, 0x1328, 0x0d7e, 0x2c68, 0x1078,
+ 0x74d7, 0x0040, 0xa0b7, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009,
+ 0xa88e, 0x210c, 0x6136, 0x2009, 0xa88f, 0x210c, 0x613a, 0x600b,
+ 0xffff, 0x6918, 0x611a, 0x601f, 0x0004, 0x1078, 0x5bf8, 0x2d60,
+ 0x1078, 0x753d, 0x0d7f, 0x007c, 0x1078, 0x753d, 0x007c, 0x0e7e,
+ 0x6018, 0x2070, 0x7000, 0xd0ec, 0x0e7f, 0x007c, 0x6010, 0xa080,
+ 0x0013, 0x200c, 0xd1ec, 0x0040, 0xa110, 0x2001, 0xa371, 0x2004,
+ 0xd0ec, 0x0040, 0xa110, 0x6003, 0x0002, 0x6024, 0xc0e5, 0x6026,
+ 0xd1ac, 0x0040, 0xa0ee, 0x0f7e, 0x2c78, 0x1078, 0x488f, 0x0f7f,
+ 0x0040, 0xa0ee, 0x2001, 0xa5a2, 0x2004, 0x603e, 0x2009, 0xa371,
+ 0x210c, 0xd1f4, 0x00c0, 0xa10e, 0x0078, 0xa100, 0x2009, 0xa371,
+ 0x210c, 0xd1f4, 0x0040, 0xa0fa, 0x6024, 0xc0e4, 0x6026, 0xa006,
+ 0x0078, 0xa110, 0x2001, 0xa5a2, 0x200c, 0x8103, 0xa100, 0x603e,
+ 0x6018, 0xa088, 0x002b, 0x2104, 0xa005, 0x0040, 0xa10b, 0xa088,
+ 0x0003, 0x0078, 0xa103, 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001,
+ 0x007c, 0x017e, 0x0c7e, 0x0e7e, 0x6120, 0xa2f0, 0x002b, 0x2e04,
+ 0x2060, 0x8cff, 0x0040, 0xa130, 0x84ff, 0x00c0, 0xa123, 0x6020,
+ 0xa106, 0x00c0, 0xa12b, 0x600c, 0x2072, 0x1078, 0x5a41, 0x1078,
+ 0x753d, 0x0078, 0xa12d, 0xacf0, 0x0003, 0x2e64, 0x0078, 0xa119,
+ 0x0e7f, 0x0c7f, 0x017f, 0x007c, 0x0d7e, 0x6018, 0xa0e8, 0x002b,
+ 0x2d04, 0xa005, 0x0040, 0xa146, 0xac06, 0x0040, 0xa144, 0x2d04,
+ 0xa0e8, 0x0003, 0x0078, 0xa138, 0x600c, 0x206a, 0x0d7f, 0x007c,
+ 0x027e, 0x037e, 0x157e, 0x2011, 0xa325, 0x2204, 0xa084, 0x00ff,
+ 0x2019, 0xa88e, 0x2334, 0xa636, 0x00c0, 0xa174, 0x8318, 0x2334,
+ 0x2204, 0xa084, 0xff00, 0xa636, 0x00c0, 0xa174, 0x2011, 0xa890,
+ 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004, 0x1078, 0x7e55, 0x00c0,
+ 0xa174, 0x2011, 0xa894, 0x6018, 0xa098, 0x0006, 0x20a9, 0x0004,
+ 0x1078, 0x7e55, 0x00c0, 0xa174, 0x157f, 0x037f, 0x027f, 0x007c,
+ 0x0e7e, 0x2071, 0xa300, 0x1078, 0x41f5, 0x1078, 0x260d, 0x0e7f,
+ 0x007c, 0x0e7e, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0040, 0xa18a,
+ 0x1078, 0xa18c, 0x0e7f, 0x007c, 0x6850, 0xc0e5, 0x6852, 0x007c,
+ 0x0e7e, 0x0c7e, 0x077e, 0x067e, 0x057e, 0x047e, 0x027e, 0x017e,
+ 0x127e, 0x2091, 0x8000, 0x2029, 0xa5b4, 0x252c, 0x2021, 0xa5ba,
+ 0x2424, 0x2061, 0xaa00, 0x2071, 0xa300, 0x7644, 0x7060, 0xa606,
+ 0x0040, 0xa1e4, 0x671c, 0xa786, 0x0001, 0x0040, 0xa1b3, 0xa786,
+ 0x0008, 0x00c0, 0xa1da, 0x2500, 0xac06, 0x0040, 0xa1da, 0x2400,
+ 0xac06, 0x0040, 0xa1da, 0x1078, 0x9ee5, 0x0040, 0xa1da, 0x1078,
+ 0x9ef9, 0x00c0, 0xa1da, 0x6000, 0xa086, 0x0004, 0x00c0, 0xa1cc,
+ 0x017e, 0x1078, 0x1749, 0x017f, 0x1078, 0x8c27, 0x00c0, 0xa1d2,
+ 0x1078, 0x2839, 0x1078, 0x8c3b, 0x00c0, 0xa1d8, 0x1078, 0x7a05,
+ 0x1078, 0x8c01, 0xace0, 0x0010, 0x2001, 0xa315, 0x2004, 0xac02,
+ 0x00c8, 0xa1e4, 0x0078, 0xa1a3, 0x127f, 0x017f, 0x027f, 0x047f,
+ 0x057f, 0x067f, 0x077f, 0x0c7f, 0x0e7f, 0x007c, 0x127e, 0x007e,
+ 0x0e7e, 0x2091, 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa1fb,
+ 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0040, 0xa201, 0x7030, 0x8000,
+ 0x7032, 0xd5ac, 0x0040, 0xa208, 0x2071, 0xa34a, 0x1078, 0xa237,
+ 0x0e7f, 0x007f, 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091,
+ 0x8000, 0x2071, 0xa340, 0xd5a4, 0x0040, 0xa219, 0x7034, 0x8000,
+ 0x7036, 0xd5b4, 0x0040, 0xa21f, 0x7030, 0x8000, 0x7032, 0xd5ac,
+ 0x0040, 0xa226, 0x2071, 0xa34a, 0x1078, 0xa237, 0x0e7f, 0x007f,
+ 0x127f, 0x007c, 0x127e, 0x007e, 0x0e7e, 0x2091, 0x8000, 0x2071,
+ 0xa342, 0x1078, 0xa237, 0x0e7f, 0x007f, 0x127f, 0x007c, 0x2e04,
+ 0x8000, 0x2072, 0x00c8, 0xa240, 0x8e70, 0x2e04, 0x8000, 0x2072,
+ 0x007c, 0x0e7e, 0x2071, 0xa340, 0x1078, 0xa237, 0x0e7f, 0x007c,
+ 0x0e7e, 0x2071, 0xa344, 0x1078, 0xa237, 0x0e7f, 0x007c, 0x0001,
+ 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100,
+ 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x6286
+};
+
+/************************************************************************
+ * *
+ * --- ISP2200 Initiator/Target Firmware --- *
+ * with Fabric (Public Loop), Point-point, and *
+ * expanded LUN addressing for FCTAPE *
+ * *
+ ************************************************************************
+ Copyright (C) 2000 and 2100 Qlogic Corporation
+ (www.qlogic.com)
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+************************************************************************/
+
+/*
+ * Firmware Version 2.01.27 (11:07 Dec 18, 2000)
+ */
+
+unsigned short risc_code_length2200 = 0x9cbf;
+unsigned short risc_code2200[] = {
+ 0x0470, 0x0000, 0x0000, 0x9cbf, 0x0000, 0x0002, 0x0001, 0x001b,
+ 0x0017, 0x2043, 0x4f50, 0x5952, 0x4947, 0x4854, 0x2031, 0x3939,
+ 0x3920, 0x514c, 0x4f47, 0x4943, 0x2043, 0x4f52, 0x504f, 0x5241,
+ 0x5449, 0x4f4e, 0x2049, 0x5350, 0x3232, 0x3030, 0x2046, 0x6972,
+ 0x6d77, 0x6172, 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030,
+ 0x322e, 0x3031, 0x2e32, 0x3720, 0x2020, 0x2020, 0x2400, 0x20c1,
+ 0x0005, 0x2001, 0x017f, 0x2003, 0x0000, 0x20c9, 0xb1ff, 0x2091,
+ 0x2000, 0x2059, 0x0000, 0x2b78, 0x7823, 0x0004, 0x2089, 0x27b5,
+ 0x2051, 0xad00, 0x2a70, 0x2029, 0xe400, 0x2031, 0xffff, 0x2039,
+ 0xe3e9, 0x2021, 0x0200, 0x0804, 0x1449, 0x20a1, 0xacbf, 0xa00e,
+ 0x20a9, 0x0741, 0x41a4, 0x3400, 0x755e, 0x7662, 0x775a, 0x7466,
+ 0x746a, 0x20a1, 0xb400, 0x7160, 0x810d, 0x810d, 0x810d, 0x810d,
+ 0xa18c, 0x000f, 0x2001, 0x000b, 0xa112, 0xa00e, 0x21a8, 0x41a4,
+ 0x3400, 0x8211, 0x1dd8, 0x7160, 0x3400, 0xa102, 0x0120, 0x0218,
+ 0x20a8, 0xa00e, 0x41a4, 0x3800, 0xd08c, 0x01d8, 0x2009, 0xad00,
+ 0x810d, 0x810d, 0x810d, 0x810d, 0xa18c, 0x000f, 0x2001, 0x0001,
+ 0xa112, 0x20a1, 0x1000, 0xa00e, 0x21a8, 0x41a4, 0x8211, 0x1de0,
+ 0x2009, 0xad00, 0x3400, 0xa102, 0x0120, 0x0218, 0x20a8, 0xa00e,
+ 0x41a4, 0x080c, 0x13fc, 0x080c, 0x1613, 0x080c, 0x17ac, 0x080c,
+ 0x1e67, 0x080c, 0x492e, 0x080c, 0x801a, 0x080c, 0x159c, 0x080c,
+ 0x2ce6, 0x080c, 0x5a01, 0x080c, 0x5045, 0x080c, 0x6487, 0x080c,
+ 0x236a, 0x080c, 0x6686, 0x080c, 0x5fae, 0x080c, 0x226b, 0x080c,
+ 0x2338, 0x2091, 0x3009, 0x7823, 0x0000, 0x1004, 0x10c5, 0x7820,
+ 0xa086, 0x0002, 0x1150, 0x7823, 0x4000, 0x0e04, 0x10bd, 0x781b,
+ 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x2a70, 0x7003, 0x0000,
+ 0x2a70, 0x7000, 0xa08e, 0x0003, 0x1158, 0x080c, 0x3c98, 0x080c,
+ 0x2d0d, 0x080c, 0x5a4f, 0x080c, 0x51f4, 0x080c, 0x64a2, 0x0c80,
+ 0x000b, 0x0c98, 0x10e4, 0x10e5, 0x1203, 0x10e2, 0x12cc, 0x13f9,
+ 0x13fa, 0x13fb, 0x080c, 0x14f6, 0x0005, 0x0126, 0x00f6, 0x2091,
+ 0x8000, 0x7000, 0xa086, 0x0001, 0x1904, 0x11d1, 0x080c, 0x1569,
+ 0x080c, 0x574f, 0x0150, 0x080c, 0x5775, 0x1580, 0x2079, 0x0100,
+ 0x7828, 0xa085, 0x1800, 0x782a, 0x0448, 0x080c, 0x569a, 0x7000,
+ 0xa086, 0x0001, 0x1904, 0x11d1, 0x7088, 0xa086, 0x0028, 0x1904,
+ 0x11d1, 0x2079, 0x0100, 0x7827, 0xffff, 0x7a28, 0xa295, 0x1e2f,
+ 0x7a2a, 0x2011, 0x566e, 0x080c, 0x650d, 0x2011, 0x567b, 0x080c,
+ 0x650d, 0x2011, 0x481b, 0x080c, 0x650d, 0x2011, 0x8030, 0x2019,
+ 0x0000, 0x7087, 0x0000, 0x080c, 0x1d0f, 0x00e8, 0x080c, 0x41d1,
+ 0x2079, 0x0100, 0x7844, 0xa005, 0x1904, 0x11d1, 0x2011, 0x481b,
+ 0x080c, 0x650d, 0x2011, 0x567b, 0x080c, 0x650d, 0x080c, 0x1d0f,
+ 0x2001, 0xaf8c, 0x2004, 0x780e, 0x7840, 0xa084, 0xfffb, 0x7842,
+ 0x2011, 0x8010, 0x73c8, 0x080c, 0x3c5c, 0x7238, 0xc284, 0x723a,
+ 0x2001, 0xad0c, 0x200c, 0xc1ac, 0x2102, 0x080c, 0x79bd, 0x2011,
+ 0x0004, 0x080c, 0x959c, 0x080c, 0x4f71, 0x080c, 0x574f, 0x0158,
+ 0x080c, 0x4917, 0x0140, 0x7087, 0x0001, 0x70c3, 0x0000, 0x080c,
+ 0x436e, 0x0804, 0x11d1, 0x080c, 0x502d, 0x0120, 0x7a0c, 0xc2b4,
+ 0x7a0e, 0x0050, 0x080c, 0x9937, 0x70d0, 0xd09c, 0x1128, 0x709c,
+ 0xa005, 0x0110, 0x080c, 0x48f5, 0x70db, 0x0000, 0x70d7, 0x0000,
+ 0x72d0, 0x080c, 0x574f, 0x1178, 0x2011, 0x0000, 0x0016, 0x080c,
+ 0x2744, 0x2019, 0xaf8e, 0x211a, 0x001e, 0x704f, 0xffff, 0x7053,
+ 0x00ef, 0x7073, 0x0000, 0x2079, 0xad51, 0x7804, 0xd0ac, 0x0108,
+ 0xc295, 0x72d2, 0x080c, 0x574f, 0x0118, 0xa296, 0x0004, 0x0508,
+ 0x2011, 0x0001, 0x080c, 0x959c, 0x7097, 0x0000, 0x709b, 0xffff,
+ 0x7003, 0x0002, 0x00fe, 0x080c, 0x28fa, 0x2011, 0x0005, 0x080c,
+ 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148, 0x00c6, 0x2061,
+ 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e, 0x00ce, 0x012e,
+ 0x00d0, 0x7097, 0x0000, 0x709b, 0xffff, 0x7003, 0x0002, 0x2011,
+ 0x0005, 0x080c, 0x7adf, 0x080c, 0x6c50, 0x080c, 0x574f, 0x0148,
+ 0x00c6, 0x2061, 0x0100, 0x0016, 0x080c, 0x2744, 0x61e2, 0x001e,
+ 0x00ce, 0x00fe, 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1118,
+ 0x20a9, 0x0100, 0x0010, 0x20a9, 0x0082, 0x080c, 0x574f, 0x1118,
+ 0x2009, 0x0000, 0x0010, 0x2009, 0x007e, 0x0016, 0x0026, 0x0036,
+ 0x2110, 0x0026, 0x2019, 0x0029, 0x080c, 0x7cf4, 0x002e, 0x080c,
+ 0xac07, 0x003e, 0x002e, 0x001e, 0x080c, 0x2bc9, 0x8108, 0x1f04,
+ 0x11e5, 0x00ce, 0x706f, 0x0000, 0x7070, 0xa084, 0x00ff, 0x7072,
+ 0x709f, 0x0000, 0x0005, 0x0126, 0x2091, 0x8000, 0x7000, 0xa086,
+ 0x0002, 0x1904, 0x12ca, 0x7098, 0xa086, 0xffff, 0x0130, 0x080c,
+ 0x28fa, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d0, 0xd0ac, 0x1110,
+ 0xd09c, 0x0540, 0xd084, 0x0530, 0x0006, 0x0016, 0x2001, 0x0103,
+ 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e, 0xd08c, 0x01d0,
+ 0x70d4, 0xa086, 0xffff, 0x0190, 0x080c, 0x2a56, 0x080c, 0x6c50,
+ 0x70d0, 0xd094, 0x1904, 0x12ca, 0x2011, 0x0001, 0x2019, 0x0000,
+ 0x080c, 0x2a8c, 0x080c, 0x6c50, 0x0804, 0x12ca, 0x70d8, 0xa005,
+ 0x1904, 0x12ca, 0x7094, 0xa005, 0x1904, 0x12ca, 0x70d0, 0xd0a4,
+ 0x0118, 0xd0b4, 0x0904, 0x12ca, 0x080c, 0x502d, 0x1904, 0x12ca,
+ 0x2001, 0xad52, 0x2004, 0xd0ac, 0x01c8, 0x0156, 0x00c6, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1118, 0x6000,
+ 0xd0ec, 0x1138, 0x001e, 0x8108, 0x1f04, 0x125b, 0x00ce, 0x015e,
+ 0x0028, 0x001e, 0x00ce, 0x015e, 0x0804, 0x12ca, 0x0006, 0x0016,
+ 0x2001, 0x0103, 0x2009, 0xaf8c, 0x210c, 0x2102, 0x001e, 0x000e,
+ 0xa006, 0x2009, 0x0700, 0x20a9, 0x0002, 0x20a1, 0xafb5, 0x40a1,
+ 0x706c, 0x8007, 0x7170, 0x810f, 0x20a9, 0x0002, 0x40a1, 0x2009,
+ 0x0000, 0x080c, 0x14dc, 0x2001, 0x0000, 0x810f, 0x20a9, 0x0002,
+ 0x40a1, 0xa006, 0x2009, 0x0200, 0x20a9, 0x0002, 0x20a1, 0xafc5,
+ 0x40a1, 0x7030, 0xc08c, 0x7032, 0x7003, 0x0003, 0x709b, 0xffff,
+ 0x080c, 0x1562, 0xa006, 0x080c, 0x261e, 0x080c, 0x3cce, 0x00f6,
+ 0x2079, 0x0100, 0x080c, 0x5775, 0x0150, 0x080c, 0x574f, 0x7828,
+ 0x0118, 0xa084, 0xe1ff, 0x0010, 0xa084, 0xffdf, 0x782a, 0x00fe,
+ 0x2001, 0xafc8, 0x2004, 0xa086, 0x0005, 0x1120, 0x2011, 0x0000,
+ 0x080c, 0x7adf, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c, 0x6c50,
+ 0x080c, 0x6d0d, 0x012e, 0x0005, 0x0016, 0x0046, 0x00f6, 0x0126,
+ 0x2091, 0x8000, 0x2079, 0x0100, 0x2009, 0xad33, 0x2104, 0xa005,
+ 0x1110, 0x080c, 0x2770, 0x2009, 0x00f7, 0x080c, 0x48de, 0x7940,
+ 0xa18c, 0x0010, 0x7942, 0x7924, 0xd1b4, 0x0110, 0x7827, 0x0040,
+ 0xd19c, 0x0110, 0x7827, 0x0008, 0x0006, 0x0036, 0x0156, 0x7954,
+ 0xd1ac, 0x1904, 0x133a, 0x080c, 0x5761, 0x0158, 0x080c, 0x5775,
+ 0x1128, 0x2001, 0xaf9d, 0x2003, 0x0000, 0x0070, 0x080c, 0x5757,
+ 0x0dc0, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+ 0x0001, 0x080c, 0x569a, 0x0058, 0x080c, 0x574f, 0x0140, 0x2009,
+ 0x00f8, 0x080c, 0x48de, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9,
+ 0x09c4, 0x7820, 0xd09c, 0x1138, 0x080c, 0x574f, 0x0138, 0x7824,
+ 0xd0ac, 0x1904, 0x13e0, 0x1f04, 0x1319, 0x0070, 0x7824, 0x080c,
+ 0x576b, 0x0118, 0xd0ac, 0x1904, 0x13e0, 0xa084, 0x1800, 0x0d98,
+ 0x7003, 0x0001, 0x0804, 0x13e0, 0x2001, 0x0001, 0x080c, 0x261e,
+ 0x0804, 0x13ef, 0x7850, 0xa084, 0x0180, 0x7852, 0x782f, 0x0020,
+ 0x20a9, 0x0046, 0x1d04, 0x1342, 0x2091, 0x6000, 0x1f04, 0x1342,
+ 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x782f, 0x0000,
+ 0x080c, 0x5761, 0x0158, 0x080c, 0x5775, 0x1128, 0x2001, 0xaf9d,
+ 0x2003, 0x0000, 0x0070, 0x080c, 0x5757, 0x0dc0, 0x2001, 0xaf9d,
+ 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x080c, 0x569a,
+ 0x0020, 0x2009, 0x00f8, 0x080c, 0x48de, 0x20a9, 0x000e, 0xe000,
+ 0x1f04, 0x136f, 0x7850, 0xa084, 0x0180, 0xa085, 0x1400, 0x7852,
+ 0x080c, 0x574f, 0x0120, 0x7843, 0x0090, 0x7843, 0x0010, 0x2021,
+ 0xe678, 0x2019, 0xea60, 0x7820, 0xd09c, 0x1558, 0x080c, 0x574f,
+ 0x05b8, 0x7824, 0xd0ac, 0x1904, 0x13e0, 0x080c, 0x5775, 0x1508,
+ 0x0046, 0x2021, 0x0190, 0x8421, 0x1df0, 0x004e, 0x8421, 0x11c8,
+ 0x7827, 0x0048, 0x20a9, 0x01f4, 0x1d04, 0x139c, 0x2091, 0x6000,
+ 0x1f04, 0x139c, 0x7824, 0xa084, 0x0068, 0x15a8, 0x2001, 0xaf9d,
+ 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x7003, 0x0001,
+ 0x0478, 0x8319, 0x1980, 0x2009, 0xad33, 0x2104, 0x8000, 0x200a,
+ 0xa084, 0xfff0, 0x0120, 0x200b, 0x0000, 0x080c, 0x2770, 0x00d8,
+ 0x080c, 0x5761, 0x1140, 0xa4a2, 0x0064, 0x1128, 0x080c, 0x5726,
+ 0x7003, 0x0001, 0x00a8, 0x7827, 0x1800, 0xe000, 0xe000, 0x7824,
+ 0x080c, 0x576b, 0x0110, 0xd0ac, 0x1158, 0xa084, 0x1800, 0x09c8,
+ 0x7003, 0x0001, 0x0028, 0x2001, 0x0001, 0x080c, 0x261e, 0x0048,
+ 0x2001, 0xad33, 0x2003, 0x0000, 0x7827, 0x0048, 0x7828, 0xc09d,
+ 0x782a, 0x7850, 0xa084, 0x0180, 0xa085, 0x0400, 0x7852, 0x015e,
+ 0x003e, 0x000e, 0x080c, 0x1539, 0x012e, 0x00fe, 0x004e, 0x001e,
+ 0x0005, 0x0005, 0x0005, 0x0005, 0x2a70, 0x2001, 0xaf9d, 0x2003,
+ 0x0000, 0x7087, 0x0000, 0x2009, 0x0100, 0x2104, 0xa082, 0x0002,
+ 0x0218, 0x704f, 0xffff, 0x0010, 0x704f, 0x0000, 0x7057, 0xffff,
+ 0x706f, 0x0000, 0x7073, 0x0000, 0x080c, 0x9937, 0x2061, 0xaf8d,
+ 0x6003, 0x0909, 0x6007, 0x0000, 0x600b, 0x8800, 0x600f, 0x0200,
+ 0x6013, 0x00ff, 0x6017, 0x0003, 0x601b, 0x0000, 0x601f, 0x07d0,
+ 0x2061, 0xaf95, 0x6003, 0x8000, 0x6007, 0x0000, 0x600b, 0x0000,
+ 0x600f, 0x0200, 0x6013, 0x00ff, 0x6017, 0x0000, 0x601b, 0x0001,
+ 0x601f, 0x0000, 0x2061, 0xafa6, 0x6003, 0x514c, 0x6007, 0x4f47,
+ 0x600b, 0x4943, 0x600f, 0x2020, 0x2001, 0xad27, 0x2003, 0x0000,
+ 0x0005, 0x04a0, 0x2011, 0x0000, 0x81ff, 0x0570, 0xa186, 0x0001,
+ 0x1148, 0x2031, 0x8fff, 0x2039, 0xcc01, 0x2021, 0x0100, 0x2029,
+ 0xcc00, 0x00e8, 0xa186, 0x0002, 0x1118, 0x2011, 0x0000, 0x00b8,
+ 0xa186, 0x0005, 0x1118, 0x2011, 0x0001, 0x0088, 0xa186, 0x0009,
+ 0x1118, 0x2011, 0x0002, 0x0058, 0xa186, 0x000a, 0x1118, 0x2011,
+ 0x0002, 0x0028, 0xa186, 0x0055, 0x1110, 0x2011, 0x0003, 0x3800,
+ 0xa084, 0xfffc, 0xa205, 0x20c0, 0x0804, 0x104d, 0xa00e, 0x2011,
+ 0x0003, 0x2019, 0x1485, 0x0804, 0x14d6, 0x2019, 0xaaaa, 0x2061,
+ 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000, 0x2c04, 0xa306, 0x2262,
+ 0x1110, 0xc1b5, 0xc1a5, 0x2011, 0x0000, 0x2019, 0x1498, 0x04f0,
+ 0x2019, 0xaaaa, 0x2061, 0xffff, 0x2c14, 0x2362, 0xe000, 0xe000,
+ 0x2c1c, 0x2061, 0x7fff, 0xe000, 0xe000, 0x2c04, 0x2061, 0xffff,
+ 0x2262, 0xa306, 0x0110, 0xc18d, 0x0008, 0xc185, 0x2011, 0x0002,
+ 0x2019, 0x14b3, 0x0418, 0x2061, 0xffff, 0x2019, 0xaaaa, 0x2c14,
+ 0x2362, 0xe000, 0xe000, 0x2c04, 0x2262, 0xa306, 0x1180, 0x2c14,
+ 0x2362, 0xe000, 0xe000, 0x2c1c, 0x2061, 0x7fff, 0x2c04, 0x2061,
+ 0xffff, 0x2262, 0xa306, 0x1110, 0xc195, 0x0008, 0xc19d, 0x2011,
+ 0x0001, 0x2019, 0x14d4, 0x0010, 0x0804, 0x144a, 0x3800, 0xa084,
+ 0xfffc, 0xa205, 0x20c0, 0x0837, 0x2011, 0x0000, 0x080c, 0x4cdc,
+ 0x1178, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0128, 0xa0c4,
+ 0xff00, 0xa8c6, 0x0600, 0x1120, 0xa186, 0x0080, 0x0108, 0x8210,
+ 0x8108, 0xa186, 0x0100, 0x1d50, 0x2208, 0x0005, 0x2091, 0x8000,
+ 0x0e04, 0x14f8, 0x0006, 0x0016, 0x2079, 0x0000, 0x7818, 0xd084,
+ 0x1de8, 0x001e, 0x792e, 0x000e, 0x782a, 0x000e, 0x7826, 0x3900,
+ 0x783a, 0x7823, 0x8002, 0x781b, 0x0001, 0x2091, 0x5000, 0x0126,
+ 0x0156, 0x0146, 0x20a9, 0x0010, 0x20a1, 0xb0c8, 0x2091, 0x2000,
+ 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2200, 0x40a1, 0x20a9, 0x0010,
+ 0x2091, 0x2400, 0x40a1, 0x20a9, 0x0010, 0x2091, 0x2600, 0x40a1,
+ 0x20a9, 0x0010, 0x2091, 0x2800, 0x40a1, 0x014e, 0x015e, 0x012e,
+ 0x2079, 0xad00, 0x7803, 0x0005, 0x2091, 0x4080, 0x04c9, 0x0cf8,
+ 0x0005, 0x0006, 0x080c, 0x1584, 0x1518, 0x00f6, 0x2079, 0xad23,
+ 0x2f04, 0x8000, 0x207a, 0xa082, 0x000f, 0x0258, 0xa006, 0x207a,
+ 0x2079, 0xad25, 0x2f04, 0xa084, 0x0001, 0xa086, 0x0001, 0x207a,
+ 0x0070, 0x2079, 0xad25, 0x2f7c, 0x8fff, 0x1128, 0x2001, 0x0c03,
+ 0x2003, 0x0040, 0x0020, 0x2001, 0x0c03, 0x2003, 0x00c0, 0x00fe,
+ 0x000e, 0x0005, 0x0409, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0080,
+ 0x0005, 0x00d1, 0x1120, 0x2001, 0x0c03, 0x2003, 0x0040, 0x0005,
+ 0x0006, 0x0091, 0x1178, 0x2001, 0x0c03, 0x2003, 0x0040, 0x2009,
+ 0x0fff, 0x00a1, 0x2001, 0x0c03, 0x2003, 0x0080, 0x2009, 0x0fff,
+ 0x0069, 0x0c88, 0x000e, 0x0005, 0x00c6, 0x2061, 0x0c00, 0x2c04,
+ 0xa084, 0x00ff, 0xa086, 0x00aa, 0x00ce, 0x0005, 0x0156, 0x0126,
+ 0xa18c, 0x0fff, 0x21a8, 0x1d04, 0x1593, 0x2091, 0x6000, 0x1f04,
+ 0x1593, 0x012e, 0x015e, 0x0005, 0x2071, 0xad00, 0x715c, 0x712e,
+ 0x2021, 0x0001, 0xa190, 0x0030, 0xa298, 0x0030, 0x0240, 0x7060,
+ 0xa302, 0x1228, 0x220a, 0x2208, 0x2310, 0x8420, 0x0ca8, 0x3800,
+ 0xd08c, 0x0148, 0x7060, 0xa086, 0xad00, 0x0128, 0x7063, 0xad00,
+ 0x2011, 0x1000, 0x0c48, 0x200b, 0x0000, 0x74ae, 0x74b2, 0x0005,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x70b0, 0xa0ea,
+ 0x0010, 0x0268, 0x8001, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e,
+ 0x206b, 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e,
+ 0x0cd8, 0x00e6, 0x2071, 0xad00, 0x0126, 0x2091, 0x8000, 0x70b0,
+ 0x8001, 0x0260, 0x70b2, 0x702c, 0x2068, 0x2d04, 0x702e, 0x206b,
+ 0x0000, 0x6807, 0x0000, 0x012e, 0x00ee, 0x0005, 0xa06e, 0x0cd8,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00, 0x702c, 0x206a,
+ 0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x012e, 0x00ee, 0x0005,
+ 0x8dff, 0x0138, 0x6804, 0x6807, 0x0000, 0x0006, 0x0c49, 0x00de,
+ 0x0cb8, 0x0005, 0x00e6, 0x2071, 0xad00, 0x70b0, 0xa08a, 0x0010,
+ 0xa00d, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7007, 0x0000,
+ 0x701b, 0x0000, 0x701f, 0x0000, 0x2071, 0x0000, 0x7010, 0xa085,
+ 0x8004, 0x7012, 0x00ee, 0x0005, 0x00e6, 0x2270, 0x700b, 0x0000,
+ 0x2071, 0xafec, 0x7018, 0xa088, 0xaff5, 0x220a, 0x8000, 0xa084,
+ 0x0007, 0x701a, 0x7004, 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010,
+ 0x0081, 0x00fe, 0x00ee, 0x0005, 0x00e6, 0x2071, 0xafec, 0x7004,
+ 0xa005, 0x1128, 0x00f6, 0x2079, 0x0010, 0x0019, 0x00fe, 0x00ee,
+ 0x0005, 0x7000, 0x0002, 0x164f, 0x16b3, 0x16d0, 0x16d0, 0x7018,
+ 0x711c, 0xa106, 0x1118, 0x7007, 0x0000, 0x0005, 0x00d6, 0xa180,
+ 0xaff5, 0x2004, 0x700a, 0x2068, 0x8108, 0xa18c, 0x0007, 0x711e,
+ 0x7803, 0x0026, 0x6824, 0x7832, 0x6828, 0x7836, 0x682c, 0x783a,
+ 0x6830, 0x783e, 0x6810, 0x700e, 0x680c, 0x7016, 0x6804, 0x00de,
+ 0xd084, 0x0120, 0x7007, 0x0001, 0x0029, 0x0005, 0x7007, 0x0002,
+ 0x00b1, 0x0005, 0x0016, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182,
+ 0x0040, 0x1210, 0x2110, 0xa006, 0x700e, 0x7212, 0x8203, 0x7822,
+ 0x7803, 0x0020, 0x7803, 0x0041, 0x002e, 0x001e, 0x0005, 0x0016,
+ 0x0026, 0x0136, 0x0146, 0x0156, 0x7014, 0x2098, 0x20a1, 0x0014,
+ 0x7803, 0x0026, 0x710c, 0x2011, 0x0040, 0xa182, 0x0040, 0x1210,
+ 0x2110, 0xa006, 0x700e, 0x22a8, 0x53a6, 0x8203, 0x7822, 0x7803,
+ 0x0020, 0x3300, 0x7016, 0x7803, 0x0001, 0x015e, 0x014e, 0x013e,
+ 0x002e, 0x001e, 0x0005, 0x0136, 0x0146, 0x0156, 0x2099, 0xadf9,
+ 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+ 0x2091, 0x8000, 0x7803, 0x0041, 0x7007, 0x0003, 0x7000, 0xc084,
+ 0x7002, 0x700b, 0xadf4, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+ 0x0136, 0x0146, 0x0156, 0x2001, 0xae28, 0x209c, 0x20a1, 0x0014,
+ 0x7803, 0x0026, 0x2001, 0xae29, 0x20ac, 0x53a6, 0x2099, 0xae2a,
+ 0x20a1, 0x0018, 0x20a9, 0x0008, 0x53a3, 0x7803, 0x0020, 0x0126,
+ 0x2091, 0x8000, 0x7803, 0x0001, 0x7007, 0x0004, 0x7000, 0xc08c,
+ 0x7002, 0x700b, 0xae25, 0x012e, 0x015e, 0x014e, 0x013e, 0x0005,
+ 0x0016, 0x00e6, 0x2071, 0xafec, 0x00f6, 0x2079, 0x0010, 0x7904,
+ 0x7803, 0x0002, 0xd1fc, 0x0120, 0xa18c, 0x0700, 0x7004, 0x0023,
+ 0x00fe, 0x00ee, 0x001e, 0x0005, 0x1649, 0x1713, 0x1741, 0x176b,
+ 0x179b, 0x1712, 0x0cf8, 0xa18c, 0x0700, 0x1528, 0x0136, 0x0146,
+ 0x0156, 0x7014, 0x20a0, 0x2099, 0x0014, 0x7803, 0x0040, 0x7010,
+ 0x20a8, 0x53a5, 0x3400, 0x7016, 0x015e, 0x014e, 0x013e, 0x700c,
+ 0xa005, 0x0570, 0x7830, 0x7832, 0x7834, 0x7836, 0x080c, 0x167a,
+ 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0100, 0x7007, 0x0000,
+ 0x080c, 0x1649, 0x0005, 0x7008, 0xa080, 0x0002, 0x2003, 0x0200,
+ 0x0ca8, 0xa18c, 0x0700, 0x1150, 0x700c, 0xa005, 0x0188, 0x7830,
+ 0x7832, 0x7834, 0x7836, 0x080c, 0x168f, 0x0005, 0x7008, 0xa080,
+ 0x0002, 0x2003, 0x0200, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005,
+ 0x00d6, 0x7008, 0x2068, 0x7830, 0x6826, 0x7834, 0x682a, 0x7838,
+ 0x682e, 0x783c, 0x6832, 0x680b, 0x0100, 0x00de, 0x7007, 0x0000,
+ 0x080c, 0x1649, 0x0005, 0xa18c, 0x0700, 0x1540, 0x0136, 0x0146,
+ 0x0156, 0x2001, 0xadf7, 0x2004, 0xa080, 0x000d, 0x20a0, 0x2099,
+ 0x0014, 0x7803, 0x0040, 0x20a9, 0x0020, 0x53a5, 0x2001, 0xadf9,
+ 0x2004, 0xd0bc, 0x0148, 0x2001, 0xae02, 0x2004, 0xa080, 0x000d,
+ 0x20a0, 0x20a9, 0x0020, 0x53a5, 0x015e, 0x014e, 0x013e, 0x7007,
+ 0x0000, 0x080c, 0x5ae6, 0x080c, 0x1649, 0x0005, 0x2011, 0x8003,
+ 0x080c, 0x3c5c, 0x0cf8, 0xa18c, 0x0700, 0x1148, 0x2001, 0xae27,
+ 0x2003, 0x0100, 0x7007, 0x0000, 0x080c, 0x1649, 0x0005, 0x2011,
+ 0x8004, 0x080c, 0x3c5c, 0x0cf8, 0x0126, 0x2091, 0x2200, 0x2079,
+ 0x0030, 0x2071, 0xaffd, 0x7003, 0x0000, 0x700f, 0xb003, 0x7013,
+ 0xb003, 0x780f, 0x00f6, 0x7803, 0x0004, 0x012e, 0x0005, 0x6934,
+ 0xa184, 0x0007, 0x0002, 0x17cb, 0x1809, 0x17cb, 0x17cb, 0x17cb,
+ 0x17f1, 0x17d8, 0x17cf, 0xa085, 0x0001, 0x0804, 0x1823, 0x684c,
+ 0xd0bc, 0x0dc8, 0x6860, 0x682e, 0x685c, 0x682a, 0x6858, 0x04c8,
+ 0xa18c, 0x00ff, 0xa186, 0x001e, 0x1d70, 0x684c, 0xd0bc, 0x0d58,
+ 0x6860, 0x682e, 0x685c, 0x682a, 0x6804, 0x681a, 0xa080, 0x000d,
+ 0x2004, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832, 0x6858,
+ 0x0440, 0xa18c, 0x00ff, 0xa186, 0x0015, 0x19a8, 0x684c, 0xd0ac,
+ 0x0990, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+ 0xa080, 0x2186, 0x2005, 0x6832, 0xa006, 0x682e, 0x682a, 0x6858,
+ 0x0080, 0x684c, 0xd0ac, 0x0904, 0x17cb, 0xa006, 0x682e, 0x682a,
+ 0x6858, 0xa18c, 0x000f, 0xa188, 0x2186, 0x210d, 0x6932, 0x2d08,
+ 0x691a, 0x6826, 0x684c, 0xc0dd, 0x684e, 0xa006, 0x680a, 0x697c,
+ 0x6912, 0x6980, 0x6916, 0x0005, 0x20e1, 0x0007, 0x20e1, 0x2000,
+ 0x2001, 0x020a, 0x2004, 0x82ff, 0x01a8, 0xa280, 0x0004, 0x00d6,
+ 0x206c, 0x684c, 0xd0dc, 0x1150, 0x080c, 0x17bf, 0x0138, 0x00de,
+ 0xa280, 0x0000, 0x2003, 0x0002, 0xa016, 0x0020, 0x6808, 0x8000,
+ 0x680a, 0x00de, 0x0126, 0x0046, 0x0036, 0x0026, 0x2091, 0x2200,
+ 0x002e, 0x003e, 0x004e, 0x7000, 0xa005, 0x01d0, 0x710c, 0x220a,
+ 0x8108, 0x230a, 0x8108, 0x240a, 0x8108, 0xa182, 0xb01e, 0x0210,
+ 0x2009, 0xb003, 0x710e, 0x7010, 0xa102, 0xa082, 0x0009, 0x0118,
+ 0xa080, 0x001b, 0x1118, 0x2009, 0x0138, 0x200a, 0x012e, 0x0005,
+ 0x7206, 0x2001, 0x1866, 0x0006, 0x2260, 0x0804, 0x197a, 0x0126,
+ 0x0026, 0x0036, 0x00c6, 0x0006, 0x2091, 0x2200, 0x000e, 0x004e,
+ 0x003e, 0x002e, 0x00d6, 0x00c6, 0x2460, 0x6110, 0x2168, 0x6a62,
+ 0x6b5e, 0xa005, 0x0904, 0x18c8, 0x6808, 0xa005, 0x0904, 0x18ff,
+ 0x7000, 0xa005, 0x1108, 0x0488, 0x700c, 0x7110, 0xa106, 0x1904,
+ 0x1907, 0x7004, 0xa406, 0x1548, 0x2001, 0x0005, 0x2004, 0xd08c,
+ 0x0168, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010, 0xa080,
+ 0x0002, 0x2004, 0xa005, 0x0904, 0x18ff, 0x0c10, 0x2001, 0x0207,
+ 0x2004, 0xd09c, 0x1d48, 0x7804, 0xa084, 0x6000, 0x0120, 0xa086,
+ 0x6000, 0x0108, 0x0c08, 0x7818, 0x6812, 0x781c, 0x6816, 0x7803,
+ 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x6100, 0xa18e, 0x0004,
+ 0x1904, 0x1907, 0x2009, 0x0048, 0x080c, 0x80a7, 0x0804, 0x1907,
+ 0x6808, 0xa005, 0x05a0, 0x7000, 0xa005, 0x0588, 0x700c, 0x7110,
+ 0xa106, 0x1118, 0x7004, 0xa406, 0x1550, 0x2001, 0x0005, 0x2004,
+ 0xd08c, 0x0160, 0x0046, 0x080c, 0x1a6c, 0x004e, 0x2460, 0x6010,
+ 0xa080, 0x0002, 0x2004, 0xa005, 0x01d0, 0x0c28, 0x2001, 0x0207,
+ 0x2004, 0xd09c, 0x1d50, 0x2001, 0x0005, 0x2004, 0xd08c, 0x1d50,
+ 0x7804, 0xa084, 0x6000, 0x0118, 0xa086, 0x6000, 0x19f0, 0x7818,
+ 0x6812, 0x781c, 0x6816, 0x7803, 0x0004, 0x7003, 0x0000, 0x6100,
+ 0xa18e, 0x0004, 0x1120, 0x2009, 0x0048, 0x080c, 0x80a7, 0x00ce,
+ 0x00de, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x0026, 0x0036, 0x0046,
+ 0x0056, 0x080c, 0x1d86, 0x0026, 0x0056, 0x2071, 0xaffd, 0x7000,
+ 0xa086, 0x0000, 0x0580, 0x7004, 0xac06, 0x11f8, 0x2079, 0x0030,
+ 0x7000, 0xa086, 0x0003, 0x01c8, 0x7804, 0xd0fc, 0x1198, 0x2001,
+ 0x0207, 0x2004, 0xd09c, 0x1dc0, 0x7803, 0x0004, 0x7804, 0xd0ac,
+ 0x1de8, 0x7803, 0x0002, 0x7803, 0x0009, 0x7003, 0x0003, 0x7007,
+ 0x0000, 0x0018, 0x080c, 0x1a6c, 0x08d0, 0x0156, 0x20a9, 0x0009,
+ 0x2009, 0xb003, 0x2104, 0xac06, 0x1108, 0x200a, 0xa188, 0x0003,
+ 0x1f04, 0x1942, 0x015e, 0x005e, 0x002e, 0x2001, 0x015d, 0x201c,
+ 0x831a, 0x2302, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202,
+ 0x005e, 0x004e, 0x003e, 0x002e, 0x00ee, 0x00fe, 0x0005, 0x700c,
+ 0x7110, 0xa106, 0x0904, 0x19dd, 0x2104, 0x7006, 0x2060, 0x8108,
+ 0x211c, 0x8108, 0x2124, 0x8108, 0xa182, 0xb01e, 0x0210, 0x2009,
+ 0xb003, 0x7112, 0x700c, 0xa106, 0x1128, 0x080c, 0x2744, 0x2001,
+ 0x0138, 0x2102, 0x8cff, 0x0588, 0x6010, 0x2068, 0x2d58, 0x6828,
+ 0xa406, 0x1580, 0x682c, 0xa306, 0x1568, 0x7004, 0x2060, 0x6020,
+ 0xc0d4, 0x6022, 0x684c, 0xd0f4, 0x0128, 0x6817, 0xffff, 0x6813,
+ 0xffff, 0x00d8, 0x6850, 0xd0f4, 0x1130, 0x7803, 0x0004, 0x6810,
+ 0x781a, 0x6814, 0x781e, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830,
+ 0x2040, 0x6034, 0xa0cc, 0x000f, 0x2009, 0x0011, 0x04c9, 0x0118,
+ 0x2009, 0x0001, 0x04a9, 0x2d58, 0x0005, 0x080c, 0x1ced, 0x0904,
+ 0x195f, 0x0cd0, 0x6020, 0xd0d4, 0x01b8, 0x6038, 0xa402, 0x6034,
+ 0xa303, 0x0108, 0x1288, 0x643a, 0x6336, 0x6c2a, 0x6b2e, 0x0046,
+ 0x0036, 0x2400, 0x6c7c, 0xa402, 0x6812, 0x2300, 0x6b80, 0xa303,
+ 0x6816, 0x003e, 0x004e, 0x0018, 0x080c, 0x98cb, 0x09f0, 0x601c,
+ 0xa08e, 0x0008, 0x0904, 0x1985, 0xa08e, 0x000a, 0x0904, 0x1985,
+ 0x080c, 0x21a6, 0x1990, 0x0804, 0x1985, 0x7003, 0x0000, 0x0005,
+ 0x8aff, 0x0904, 0x1a46, 0xa03e, 0x2730, 0x6850, 0xd0fc, 0x11b8,
+ 0xd0f4, 0x1528, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1a30,
+ 0x1a15, 0x1a15, 0x1a30, 0x1a30, 0x1a29, 0x1a30, 0x1a15, 0x1a30,
+ 0x1a1a, 0x1a1a, 0x1a30, 0x1a30, 0x1a30, 0x1a21, 0x1a1a, 0x7803,
+ 0x0004, 0xc0fc, 0x6852, 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0x00d6,
+ 0xd99c, 0x0548, 0x2805, 0xac68, 0x6f08, 0x6e0c, 0x0420, 0xc0f4,
+ 0x6852, 0x6b6c, 0x6a70, 0x00d6, 0x0428, 0x6b08, 0x6a0c, 0x6d00,
+ 0x6c04, 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c,
+ 0x0090, 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e,
+ 0x1138, 0x00de, 0x080c, 0x2148, 0x1904, 0x19e0, 0xa00e, 0x00b0,
+ 0x00de, 0x080c, 0x14f6, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+ 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x00de, 0x6828, 0xa300,
+ 0x682a, 0x682c, 0xa201, 0x682e, 0x080c, 0x2148, 0x0005, 0x080c,
+ 0x14f6, 0x080c, 0x1e1a, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068,
+ 0x7003, 0x0000, 0x080c, 0x1d22, 0x080c, 0x9596, 0x0170, 0x6808,
+ 0x8001, 0x680a, 0x697c, 0x6912, 0x6980, 0x6916, 0x682b, 0xffff,
+ 0x682f, 0xffff, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c,
+ 0x0804, 0x1c5e, 0x080c, 0x14f6, 0x0126, 0x2091, 0x2200, 0x0006,
+ 0x0016, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+ 0x0700, 0x1978, 0xa184, 0x0003, 0xa086, 0x0003, 0x0d58, 0x7000,
+ 0x0002, 0x1a89, 0x1a8f, 0x1b92, 0x1c39, 0x1c4d, 0x1a89, 0x1a89,
+ 0x1a89, 0x7804, 0xd09c, 0x1904, 0x1c5e, 0x080c, 0x14f6, 0x8001,
+ 0x7002, 0xa184, 0x0880, 0x1190, 0xd19c, 0x1904, 0x1b20, 0x8aff,
+ 0x0904, 0x1b20, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0904, 0x1c5e,
+ 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1b00, 0x0026, 0x0036, 0x7c20,
+ 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816, 0x2001,
+ 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128, 0x7803,
+ 0x0009, 0x7003, 0x0004, 0x0010, 0x080c, 0x1c62, 0x6b28, 0x6a2c,
+ 0x2400, 0x686e, 0xa31a, 0x2500, 0x6872, 0xa213, 0x6b2a, 0x6a2e,
+ 0x00c6, 0x7004, 0x2060, 0x6020, 0xd0f4, 0x1110, 0x633a, 0x6236,
+ 0x00ce, 0x003e, 0x002e, 0x6e1e, 0x6f22, 0x080c, 0x215e, 0x2a00,
+ 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6850, 0xc0fd, 0x6852,
+ 0x6808, 0x8001, 0x680a, 0x1148, 0x684c, 0xd0e4, 0x0130, 0x7004,
+ 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7, 0x7000, 0xa086, 0x0004,
+ 0x0904, 0x1c5e, 0x7003, 0x0000, 0x080c, 0x195f, 0x0804, 0x1c5e,
+ 0x0056, 0x7d0c, 0xd5bc, 0x1110, 0x080c, 0xac73, 0x005e, 0x080c,
+ 0x1d22, 0x00f6, 0x7004, 0x2078, 0x080c, 0x5029, 0x0118, 0x7820,
+ 0xc0f5, 0x7822, 0x00fe, 0x682b, 0xffff, 0x682f, 0xffff, 0x6808,
+ 0x8001, 0x680a, 0x697c, 0x791a, 0x6980, 0x791e, 0x0804, 0x1c5e,
+ 0x7004, 0x00c6, 0x2060, 0x6020, 0x00ce, 0xd0f4, 0x0128, 0x6808,
+ 0x8001, 0x680a, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x7a1c, 0x6a16,
+ 0xd19c, 0x0160, 0xa205, 0x0150, 0x7004, 0xa080, 0x0007, 0x2004,
+ 0xa084, 0xfffd, 0xa086, 0x0008, 0x1904, 0x1aa6, 0x684c, 0xc0f5,
+ 0x684e, 0x7814, 0xa005, 0x1180, 0x7003, 0x0000, 0x6808, 0x8001,
+ 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048, 0x080c, 0x80a7,
+ 0x080c, 0x195f, 0x0804, 0x1c5e, 0x7818, 0x6812, 0x781c, 0x6816,
+ 0x7814, 0x7908, 0xa18c, 0x0fff, 0xa188, 0x0007, 0x8114, 0x8214,
+ 0x8214, 0xa10a, 0x8104, 0x8004, 0x8004, 0xa20a, 0x810b, 0x810b,
+ 0x810b, 0x080c, 0x1da5, 0x7803, 0x0004, 0x780f, 0xffff, 0x7803,
+ 0x0001, 0x7804, 0xd0fc, 0x0de8, 0x7803, 0x0002, 0x7803, 0x0004,
+ 0x780f, 0x00f6, 0x7004, 0x7007, 0x0000, 0x2060, 0x2009, 0x0048,
+ 0x080c, 0x80a7, 0x080c, 0x1dd7, 0x0958, 0x7908, 0xd1ec, 0x1118,
+ 0x2009, 0x0009, 0x0010, 0x2009, 0x0019, 0x7902, 0x7003, 0x0003,
+ 0x0804, 0x1c5e, 0x8001, 0x7002, 0xd194, 0x01a8, 0x7804, 0xd0fc,
+ 0x1904, 0x1c2c, 0xd09c, 0x0130, 0x7804, 0xd0fc, 0x1904, 0x1a74,
+ 0xd09c, 0x11a8, 0x8aff, 0x0904, 0x1c5e, 0x2009, 0x0001, 0x080c,
+ 0x19e0, 0x0804, 0x1c5e, 0xa184, 0x0888, 0x1148, 0x8aff, 0x0904,
+ 0x1c5e, 0x2009, 0x0001, 0x080c, 0x19e0, 0x0804, 0x1c5e, 0x7818,
+ 0x6812, 0x7a1c, 0x6a16, 0xa205, 0x0904, 0x1b3e, 0x7803, 0x0004,
+ 0x7003, 0x0000, 0xd1bc, 0x1904, 0x1c0f, 0x6834, 0xa084, 0x00ff,
+ 0xa086, 0x0029, 0x1118, 0xd19c, 0x1904, 0x1b3e, 0x0026, 0x0036,
+ 0x7c20, 0x7d24, 0x7e30, 0x7f34, 0x7818, 0x6812, 0x781c, 0x6816,
+ 0x2001, 0x0201, 0x2004, 0xa005, 0x0140, 0x7808, 0xd0ec, 0x1128,
+ 0x7803, 0x0009, 0x7003, 0x0004, 0x0020, 0x0016, 0x080c, 0x1c62,
+ 0x001e, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6, 0x2805, 0xac68,
+ 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c, 0xa213, 0x0020,
+ 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0xd194, 0x0904, 0x1ac8,
+ 0x2a00, 0x6826, 0x2c00, 0x681a, 0x2800, 0x6832, 0x6808, 0x8001,
+ 0x680a, 0x6b2a, 0x6a2e, 0x003e, 0x002e, 0x0804, 0x1b50, 0x0056,
+ 0x7d0c, 0x080c, 0xac73, 0x005e, 0x080c, 0x1d22, 0x00f6, 0x7004,
+ 0x2078, 0x080c, 0x5029, 0x0118, 0x7820, 0xc0f5, 0x7822, 0x00fe,
+ 0x682b, 0xffff, 0x682f, 0xffff, 0x6808, 0x8001, 0x680a, 0x697c,
+ 0x791a, 0x6980, 0x791e, 0x0490, 0x7804, 0xd09c, 0x0904, 0x1a74,
+ 0x7c20, 0x7824, 0xa405, 0x1904, 0x1a74, 0x7803, 0x0002, 0x0804,
+ 0x1bb7, 0x7803, 0x0004, 0x7003, 0x0000, 0x7004, 0xa00d, 0x0150,
+ 0x6808, 0x8001, 0x680a, 0x1130, 0x7004, 0x2060, 0x2009, 0x0048,
+ 0x080c, 0x80a7, 0x080c, 0x195f, 0x0088, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0x7004, 0x2060, 0x6010, 0xa005, 0x0da0, 0x2068, 0x6808,
+ 0x8000, 0x680a, 0x6c28, 0x6b2c, 0x080c, 0x197a, 0x001e, 0x000e,
+ 0x012e, 0x0005, 0x700c, 0x7110, 0xa106, 0x0904, 0x1ce1, 0x7004,
+ 0x0016, 0x210c, 0xa106, 0x001e, 0x0904, 0x1ce1, 0x00d6, 0x00c6,
+ 0x216c, 0x2d00, 0xa005, 0x0904, 0x1cdf, 0x6820, 0xd0d4, 0x1904,
+ 0x1cdf, 0x6810, 0x2068, 0x6850, 0xd0fc, 0x0558, 0x8108, 0x2104,
+ 0x6b2c, 0xa306, 0x1904, 0x1cdf, 0x8108, 0x2104, 0x6a28, 0xa206,
+ 0x1904, 0x1cdf, 0x6850, 0xc0fc, 0xc0f5, 0x6852, 0x686c, 0x7822,
+ 0x6870, 0x7826, 0x681c, 0x7832, 0x6820, 0x7836, 0x6818, 0x2060,
+ 0x6034, 0xd09c, 0x0150, 0x6830, 0x2005, 0x00d6, 0xac68, 0x6808,
+ 0x783a, 0x680c, 0x783e, 0x00de, 0x04a0, 0xa006, 0x783a, 0x783e,
+ 0x0480, 0x8108, 0x2104, 0xa005, 0x1590, 0x8108, 0x2104, 0xa005,
+ 0x1570, 0x6850, 0xc0f5, 0x6852, 0x6830, 0x2005, 0x6918, 0xa160,
+ 0xa180, 0x000d, 0x2004, 0xd09c, 0x1170, 0x6008, 0x7822, 0x686e,
+ 0x600c, 0x7826, 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0xa006,
+ 0x783a, 0x783e, 0x0070, 0x6010, 0x7822, 0x686e, 0x6014, 0x7826,
+ 0x6872, 0x6000, 0x7832, 0x6004, 0x7836, 0x6008, 0x783a, 0x600c,
+ 0x783e, 0x6810, 0x781a, 0x6814, 0x781e, 0x7803, 0x0011, 0x00ce,
+ 0x00de, 0x0005, 0x2011, 0x0201, 0x2009, 0x003c, 0x2204, 0xa005,
+ 0x1118, 0x8109, 0x1dd8, 0x0005, 0x0005, 0x0ca1, 0x01e0, 0x7908,
+ 0xd1ec, 0x1160, 0x080c, 0x1dd7, 0x0148, 0x7803, 0x0009, 0x7904,
+ 0xd1fc, 0x0de8, 0x7803, 0x0006, 0x0c29, 0x0168, 0x780c, 0xd0a4,
+ 0x1150, 0x7007, 0x0000, 0x080c, 0x1dd7, 0x0140, 0x7803, 0x0019,
+ 0x7003, 0x0003, 0x0018, 0x00b1, 0xa085, 0x0001, 0x0005, 0x0126,
+ 0x2091, 0x2200, 0x7000, 0xa086, 0x0003, 0x1150, 0x700c, 0x7110,
+ 0xa106, 0x0130, 0x20e1, 0x9028, 0x700f, 0xb003, 0x7013, 0xb003,
+ 0x012e, 0x0005, 0x00c6, 0x080c, 0x574f, 0x1550, 0x2001, 0x0160,
+ 0x2003, 0x0000, 0x2001, 0x0138, 0x2003, 0x0000, 0x2011, 0x00c8,
+ 0xe000, 0xe000, 0x8211, 0x1de0, 0x080c, 0x1d7e, 0x700c, 0x7110,
+ 0xa106, 0x0190, 0x2104, 0xa005, 0x0130, 0x2060, 0x6010, 0x2060,
+ 0x6008, 0x8001, 0x600a, 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210,
+ 0x2009, 0xb003, 0x7112, 0x0c50, 0x080c, 0x57d1, 0x00ce, 0x0005,
+ 0x04a9, 0x20e1, 0x9028, 0x700c, 0x7110, 0xa106, 0x01d0, 0x2104,
+ 0xa005, 0x0130, 0x2060, 0x6010, 0x2060, 0x6008, 0x8001, 0x600a,
+ 0xa188, 0x0003, 0xa182, 0xb01e, 0x0210, 0x2009, 0xb003, 0x7112,
+ 0x700c, 0xa106, 0x1d40, 0x080c, 0x2744, 0x2001, 0x0138, 0x2102,
+ 0x0c10, 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x2001, 0x0160,
+ 0x2502, 0x2001, 0x0138, 0x2202, 0x00ce, 0x0005, 0x20e1, 0x9028,
+ 0x2001, 0x015d, 0x200c, 0x810a, 0x2102, 0x0005, 0x2001, 0x0138,
+ 0x2014, 0x2003, 0x0000, 0x2001, 0x0160, 0x202c, 0x2003, 0x0000,
+ 0x2021, 0xb015, 0x2001, 0x0141, 0x201c, 0xd3dc, 0x1168, 0x2001,
+ 0x0109, 0x201c, 0xa39c, 0x0048, 0x1138, 0x2001, 0x0111, 0x201c,
+ 0x83ff, 0x1110, 0x8421, 0x1d70, 0x0005, 0x00e6, 0x2071, 0x0200,
+ 0x7808, 0xa084, 0xf000, 0xa10d, 0x08c9, 0x2019, 0x5000, 0x8319,
+ 0x0168, 0x2001, 0xb01e, 0x2004, 0xa086, 0x0000, 0x0138, 0x2001,
+ 0x0021, 0xd0fc, 0x0da0, 0x080c, 0x1ff4, 0x0c78, 0x20e1, 0x7000,
+ 0x7324, 0x7420, 0x7028, 0x7028, 0x7426, 0x7037, 0x0001, 0x810f,
+ 0x712e, 0x702f, 0x0100, 0x7037, 0x0008, 0x7326, 0x7422, 0x2001,
+ 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x00ee, 0x0005, 0x7908,
+ 0xa18c, 0x0fff, 0xa182, 0x0009, 0x0218, 0xa085, 0x0001, 0x0088,
+ 0x2001, 0x020a, 0x81ff, 0x0130, 0x20e1, 0x6000, 0x200c, 0x200c,
+ 0x200c, 0x200c, 0x20e1, 0x7000, 0x200c, 0x200c, 0x7003, 0x0000,
+ 0xa006, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x0026, 0x2071, 0xaffd,
+ 0x2079, 0x0030, 0x2011, 0x0050, 0x7000, 0xa086, 0x0000, 0x01a8,
+ 0x8211, 0x0188, 0x2001, 0x0005, 0x2004, 0xd08c, 0x0dc8, 0x7904,
+ 0xa18c, 0x0780, 0x0016, 0x080c, 0x1a6c, 0x001e, 0x81ff, 0x1118,
+ 0x2011, 0x0050, 0x0c48, 0xa085, 0x0001, 0x002e, 0x001e, 0x00ee,
+ 0x00fe, 0x0005, 0x7803, 0x0004, 0x2009, 0x0064, 0x7804, 0xd0ac,
+ 0x0904, 0x1e66, 0x8109, 0x1dd0, 0x2009, 0x0100, 0x210c, 0xa18a,
+ 0x0003, 0x0a0c, 0x14f6, 0x080c, 0x20f2, 0x00e6, 0x00f6, 0x2071,
+ 0xafec, 0x2079, 0x0010, 0x7004, 0xa086, 0x0000, 0x0538, 0x7800,
+ 0x0006, 0x7820, 0x0006, 0x7830, 0x0006, 0x7834, 0x0006, 0x7838,
+ 0x0006, 0x783c, 0x0006, 0x7803, 0x0004, 0xe000, 0xe000, 0x2079,
+ 0x0030, 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x2079, 0x0010, 0x000e,
+ 0x783e, 0x000e, 0x783a, 0x000e, 0x7836, 0x000e, 0x7832, 0x000e,
+ 0x7822, 0x000e, 0x7802, 0x00fe, 0x00ee, 0x0030, 0x00fe, 0x00ee,
+ 0x7804, 0xd0ac, 0x190c, 0x14f6, 0x080c, 0x6d0d, 0x0005, 0x00e6,
+ 0x2071, 0xb01e, 0x7003, 0x0000, 0x00ee, 0x0005, 0x00d6, 0xa280,
+ 0x0004, 0x206c, 0x694c, 0xd1dc, 0x1904, 0x1ee4, 0x6934, 0xa184,
+ 0x0007, 0x0002, 0x1e82, 0x1ecf, 0x1e82, 0x1e82, 0x1e82, 0x1eb6,
+ 0x1e95, 0x1e84, 0x080c, 0x14f6, 0x684c, 0xd0b4, 0x0904, 0x1fcc,
+ 0x6860, 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a,
+ 0x6880, 0x680e, 0x6958, 0x0804, 0x1ed7, 0x6834, 0xa084, 0x00ff,
+ 0xa086, 0x001e, 0x1d38, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6860,
+ 0x682e, 0x6816, 0x685c, 0x682a, 0x6812, 0x687c, 0x680a, 0x6880,
+ 0x680e, 0x6804, 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f,
+ 0xa080, 0x2186, 0x2005, 0x6832, 0x6958, 0x0450, 0xa18c, 0x00ff,
+ 0xa186, 0x0015, 0x1548, 0x684c, 0xd0b4, 0x0904, 0x1fcc, 0x6804,
+ 0x681a, 0xa080, 0x000d, 0x2004, 0xa084, 0x000f, 0xa080, 0x2186,
+ 0x2005, 0x6832, 0x6958, 0xa006, 0x682e, 0x682a, 0x0088, 0x684c,
+ 0xd0b4, 0x0904, 0x1a47, 0x6958, 0xa006, 0x682e, 0x682a, 0x2d00,
+ 0x681a, 0x6834, 0xa084, 0x000f, 0xa080, 0x2186, 0x2005, 0x6832,
+ 0x6926, 0x684c, 0xc0dd, 0x684e, 0x00de, 0x0005, 0x00f6, 0x2079,
+ 0x0020, 0x7804, 0xd0fc, 0x190c, 0x1ff4, 0x00e6, 0x00d6, 0x2071,
+ 0xb01e, 0x7000, 0xa005, 0x1904, 0x1f4c, 0x00c6, 0x7206, 0xa280,
+ 0x0004, 0x205c, 0x7004, 0x2068, 0x7803, 0x0004, 0x6818, 0x00d6,
+ 0x2068, 0x686c, 0x7812, 0x6890, 0x00f6, 0x20e1, 0x9040, 0x2079,
+ 0x0200, 0x781a, 0x2079, 0x0100, 0x8004, 0x78d6, 0x00fe, 0x00de,
+ 0x2b68, 0x6824, 0x2050, 0x6818, 0x2060, 0x6830, 0x2040, 0x6034,
+ 0xa0cc, 0x000f, 0x6908, 0x791a, 0x7116, 0x680c, 0x781e, 0x701a,
+ 0xa006, 0x700e, 0x7012, 0x7004, 0x692c, 0x6814, 0xa106, 0x1120,
+ 0x6928, 0x6810, 0xa106, 0x0158, 0x0036, 0x0046, 0x6b14, 0x6c10,
+ 0x080c, 0x21a6, 0x004e, 0x003e, 0x0110, 0x00ce, 0x00a8, 0x8aff,
+ 0x1120, 0x00ce, 0xa085, 0x0001, 0x0078, 0x0126, 0x2091, 0x8000,
+ 0x2079, 0x0020, 0x2009, 0x0001, 0x0059, 0x0118, 0x2009, 0x0001,
+ 0x0039, 0x012e, 0x00ce, 0xa006, 0x00de, 0x00ee, 0x00fe, 0x0005,
+ 0x0076, 0x0066, 0x0056, 0x0046, 0x0036, 0x0026, 0x8aff, 0x0904,
+ 0x1fc5, 0x700c, 0x7214, 0xa23a, 0x7010, 0x7218, 0xa203, 0x0a04,
+ 0x1fc4, 0xa705, 0x0904, 0x1fc4, 0xa03e, 0x2730, 0x6850, 0xd0fc,
+ 0x11a8, 0x00d6, 0x2805, 0xac68, 0x2900, 0x0002, 0x1fa7, 0x1f8c,
+ 0x1f8c, 0x1fa7, 0x1fa7, 0x1fa0, 0x1fa7, 0x1f8c, 0x1fa7, 0x1f91,
+ 0x1f91, 0x1fa7, 0x1fa7, 0x1fa7, 0x1f98, 0x1f91, 0xc0fc, 0x6852,
+ 0x6b6c, 0x6a70, 0x6d1c, 0x6c20, 0xd99c, 0x0528, 0x00d6, 0x2805,
+ 0xac68, 0x6f08, 0x6e0c, 0x00f0, 0x6b08, 0x6a0c, 0x6d00, 0x6c04,
+ 0x00c8, 0x6b10, 0x6a14, 0x6d00, 0x6c04, 0x6f08, 0x6e0c, 0x0090,
+ 0x00de, 0x00d6, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x1138,
+ 0x00de, 0x080c, 0x2148, 0x1904, 0x1f56, 0xa00e, 0x00f0, 0x00de,
+ 0x080c, 0x14f6, 0x00de, 0x7b22, 0x7a26, 0x7d32, 0x7c36, 0x7f3a,
+ 0x7e3e, 0x7902, 0x7000, 0x8000, 0x7002, 0x6828, 0xa300, 0x682a,
+ 0x682c, 0xa201, 0x682e, 0x700c, 0xa300, 0x700e, 0x7010, 0xa201,
+ 0x7012, 0x080c, 0x2148, 0x0008, 0xa006, 0x002e, 0x003e, 0x004e,
+ 0x005e, 0x006e, 0x007e, 0x0005, 0x080c, 0x14f6, 0x0026, 0x2001,
+ 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0x7004, 0x2060, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596,
+ 0x0118, 0x6850, 0xc0bd, 0x6852, 0x00de, 0x080c, 0x929c, 0x20e1,
+ 0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x080c,
+ 0x6d0d, 0x002e, 0x0804, 0x20ad, 0x0126, 0x2091, 0x2400, 0x0006,
+ 0x0016, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x2079, 0x0020, 0x2071,
+ 0xb01e, 0x2b68, 0x6818, 0x2060, 0x7904, 0x7803, 0x0002, 0xa184,
+ 0x0700, 0x1920, 0x7000, 0x0002, 0x20ad, 0x2010, 0x2080, 0x20ab,
+ 0x8001, 0x7002, 0xd19c, 0x1170, 0x8aff, 0x05d0, 0x2009, 0x0001,
+ 0x080c, 0x1f50, 0x0904, 0x20ad, 0x2009, 0x0001, 0x080c, 0x1f50,
+ 0x0804, 0x20ad, 0x7803, 0x0004, 0xd194, 0x0148, 0x6850, 0xc0fc,
+ 0x6852, 0x8aff, 0x11d8, 0x684c, 0xc0f5, 0x684e, 0x00b8, 0x0026,
+ 0x0036, 0x6b28, 0x6a2c, 0x7820, 0x686e, 0xa31a, 0x7824, 0x6872,
+ 0xa213, 0x7830, 0x681e, 0x7834, 0x6822, 0x6b2a, 0x6a2e, 0x003e,
+ 0x002e, 0x080c, 0x215e, 0x6850, 0xc0fd, 0x6852, 0x2a00, 0x6826,
+ 0x2c00, 0x681a, 0x2800, 0x6832, 0x7003, 0x0000, 0x0804, 0x20ad,
+ 0x00f6, 0x0026, 0x781c, 0x0006, 0x7818, 0x0006, 0x2079, 0x0100,
+ 0x7a14, 0xa284, 0x0184, 0xa085, 0x0012, 0x7816, 0x0036, 0x2019,
+ 0x1000, 0x8319, 0x090c, 0x14f6, 0x7820, 0xd0bc, 0x1dd0, 0x003e,
+ 0x79c8, 0x000e, 0xa102, 0x001e, 0x0006, 0x0016, 0x79c4, 0x000e,
+ 0xa103, 0x78c6, 0x000e, 0x78ca, 0xa284, 0x0184, 0xa085, 0x0012,
+ 0x7816, 0x002e, 0x00fe, 0x7803, 0x0008, 0x7003, 0x0000, 0x0468,
+ 0x8001, 0x7002, 0xd194, 0x0168, 0x7804, 0xd0fc, 0x1904, 0x2004,
+ 0xd19c, 0x11f8, 0x8aff, 0x0508, 0x2009, 0x0001, 0x080c, 0x1f50,
+ 0x00e0, 0x0026, 0x0036, 0x6b28, 0x6a2c, 0x080c, 0x215e, 0x00d6,
+ 0x2805, 0xac68, 0x6034, 0xd09c, 0x1128, 0x6808, 0xa31a, 0x680c,
+ 0xa213, 0x0020, 0x6810, 0xa31a, 0x6814, 0xa213, 0x00de, 0x0804,
+ 0x2033, 0x0804, 0x202f, 0x080c, 0x14f6, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x001e, 0x000e, 0x012e, 0x0005, 0x00f6, 0x00e6, 0x2071,
+ 0xb01e, 0x7000, 0xa086, 0x0000, 0x0590, 0x2079, 0x0020, 0x0016,
+ 0x2009, 0x0207, 0x210c, 0xd194, 0x0158, 0x2009, 0x020c, 0x210c,
+ 0xa184, 0x0003, 0x0128, 0x20e1, 0x9040, 0x2001, 0x020c, 0x2102,
+ 0x2009, 0x0206, 0x2104, 0x2009, 0x0203, 0x210c, 0xa106, 0x1110,
+ 0x20e1, 0x9040, 0x7804, 0xd0fc, 0x0d18, 0x080c, 0x1ff4, 0x7000,
+ 0xa086, 0x0000, 0x19e8, 0x001e, 0x7803, 0x0004, 0x7804, 0xd0ac,
+ 0x1de8, 0x20e1, 0x9040, 0x7803, 0x0002, 0x7003, 0x0000, 0x00ee,
+ 0x00fe, 0x0005, 0x0026, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2071,
+ 0xb01e, 0x2079, 0x0020, 0x7000, 0xa086, 0x0000, 0x0540, 0x7004,
+ 0x2060, 0x6010, 0x2068, 0x080c, 0x9596, 0x0158, 0x6850, 0xc0b5,
+ 0x6852, 0x680c, 0x7a1c, 0xa206, 0x1120, 0x6808, 0x7a18, 0xa206,
+ 0x01e0, 0x2001, 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803,
+ 0x0004, 0x7003, 0x0000, 0x7004, 0x2060, 0x080c, 0x929c, 0x20e1,
+ 0x9040, 0x080c, 0x7cb8, 0x2011, 0x0000, 0x080c, 0x7ae9, 0x00fe,
+ 0x00ee, 0x00de, 0x00ce, 0x002e, 0x0005, 0x6810, 0x6a14, 0xa205,
+ 0x1d00, 0x684c, 0xc0dc, 0x684e, 0x2c10, 0x080c, 0x1e6e, 0x2001,
+ 0x0105, 0x2003, 0x0010, 0x20e1, 0x9040, 0x7803, 0x0004, 0x7003,
+ 0x0000, 0x2069, 0xafc7, 0x6833, 0x0000, 0x683f, 0x0000, 0x08f8,
+ 0x8840, 0x2805, 0xa005, 0x1170, 0x6004, 0xa005, 0x0168, 0x681a,
+ 0x2060, 0x6034, 0xa084, 0x000f, 0xa080, 0x2186, 0x2045, 0x88ff,
+ 0x090c, 0x14f6, 0x8a51, 0x0005, 0x2050, 0x0005, 0x8a50, 0x8841,
+ 0x2805, 0xa005, 0x1190, 0x2c00, 0xad06, 0x0120, 0x6000, 0xa005,
+ 0x1108, 0x2d00, 0x2060, 0x681a, 0x6034, 0xa084, 0x000f, 0xa080,
+ 0x2196, 0x2045, 0x88ff, 0x090c, 0x14f6, 0x0005, 0x0000, 0x0011,
+ 0x0015, 0x0019, 0x001d, 0x0021, 0x0025, 0x0029, 0x0000, 0x000f,
+ 0x0015, 0x001b, 0x0021, 0x0027, 0x0000, 0x0000, 0x0000, 0x217b,
+ 0x2177, 0x0000, 0x0000, 0x2185, 0x0000, 0x217b, 0x0000, 0x2182,
+ 0x217f, 0x0000, 0x0000, 0x0000, 0x2185, 0x2182, 0x0000, 0x217d,
+ 0x217d, 0x0000, 0x0000, 0x2185, 0x0000, 0x217d, 0x0000, 0x2183,
+ 0x2183, 0x0000, 0x0000, 0x0000, 0x2185, 0x2183, 0x00a6, 0x0096,
+ 0x0086, 0x6b2e, 0x6c2a, 0x6858, 0xa055, 0x0904, 0x2237, 0x2d60,
+ 0x6034, 0xa0cc, 0x000f, 0xa9c0, 0x2186, 0xa986, 0x0007, 0x0130,
+ 0xa986, 0x000e, 0x0118, 0xa986, 0x000f, 0x1120, 0x605c, 0xa422,
+ 0x6060, 0xa31a, 0x2805, 0xa045, 0x1140, 0x0310, 0x0804, 0x2237,
+ 0x6004, 0xa065, 0x0904, 0x2237, 0x0c18, 0x2805, 0xa005, 0x01a8,
+ 0xac68, 0xd99c, 0x1128, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0020,
+ 0x6810, 0xa422, 0x6814, 0xa31b, 0x0620, 0x2300, 0xa405, 0x0150,
+ 0x8a51, 0x0904, 0x2237, 0x8840, 0x0c40, 0x6004, 0xa065, 0x0904,
+ 0x2237, 0x0830, 0x8a51, 0x0904, 0x2237, 0x8840, 0x2805, 0xa005,
+ 0x1158, 0x6004, 0xa065, 0x0904, 0x2237, 0x6034, 0xa0cc, 0x000f,
+ 0xa9c0, 0x2186, 0x2805, 0x2040, 0x2b68, 0x6850, 0xc0fc, 0x6852,
+ 0x0458, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x00d6, 0x2b68,
+ 0x6c6e, 0x6b72, 0x00de, 0xd99c, 0x1168, 0x6908, 0x2400, 0xa122,
+ 0x690c, 0x2300, 0xa11b, 0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804,
+ 0xa319, 0x0060, 0x6910, 0x2400, 0xa122, 0x6914, 0x2300, 0xa11b,
+ 0x0a0c, 0x14f6, 0x6800, 0xa420, 0x6804, 0xa319, 0x2b68, 0x6c1e,
+ 0x6b22, 0x6850, 0xc0fd, 0x6852, 0x2c00, 0x681a, 0x2800, 0x6832,
+ 0x2a00, 0x6826, 0x000e, 0x000e, 0x000e, 0xa006, 0x0028, 0x008e,
+ 0x009e, 0x00ae, 0xa085, 0x0001, 0x0005, 0x2001, 0x0005, 0x2004,
+ 0xa084, 0x0007, 0x0002, 0x224b, 0x224c, 0x224f, 0x2252, 0x2257,
+ 0x225a, 0x225f, 0x2264, 0x0005, 0x080c, 0x1ff4, 0x0005, 0x080c,
+ 0x1a6c, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4, 0x0005, 0x080c,
+ 0x16f8, 0x0005, 0x080c, 0x1ff4, 0x080c, 0x16f8, 0x0005, 0x080c,
+ 0x1a6c, 0x080c, 0x16f8, 0x0005, 0x080c, 0x1a6c, 0x080c, 0x1ff4,
+ 0x080c, 0x16f8, 0x0005, 0x0126, 0x2091, 0x2600, 0x2079, 0x0200,
+ 0x2071, 0xb280, 0x2069, 0xad00, 0x2009, 0x0004, 0x7912, 0x7817,
+ 0x0004, 0x080c, 0x2651, 0x781b, 0x0002, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x20a9, 0x0080, 0x782f, 0x0000, 0x1f04, 0x2283, 0x20e1,
+ 0x9080, 0x783b, 0x001f, 0x20e1, 0x8700, 0x012e, 0x0005, 0x0126,
+ 0x2091, 0x2600, 0x781c, 0xd0a4, 0x190c, 0x2335, 0xa084, 0x0007,
+ 0x0002, 0x22b3, 0x22a1, 0x22a4, 0x22a7, 0x22ac, 0x22ae, 0x22b0,
+ 0x22b2, 0x080c, 0x5fb7, 0x0078, 0x080c, 0x5ff0, 0x0060, 0x080c,
+ 0x5fb7, 0x080c, 0x5ff0, 0x0038, 0x0041, 0x0028, 0x0031, 0x0018,
+ 0x0021, 0x0008, 0x0011, 0x012e, 0x0005, 0x0006, 0x0016, 0x0026,
+ 0x7930, 0xa184, 0x0003, 0x0118, 0x20e1, 0x9040, 0x04a0, 0xa184,
+ 0x0030, 0x01e0, 0x6a00, 0xa286, 0x0003, 0x1108, 0x00a0, 0x080c,
+ 0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+ 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+ 0x0010, 0x080c, 0x485e, 0x20e1, 0x9010, 0x00a8, 0xa184, 0x00c0,
+ 0x0168, 0x00e6, 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c,
+ 0x1d22, 0x005e, 0x004e, 0x003e, 0x00ee, 0x0028, 0xa184, 0x0300,
+ 0x0110, 0x20e1, 0x9020, 0x7932, 0x002e, 0x001e, 0x000e, 0x0005,
+ 0x0016, 0x00e6, 0x00f6, 0x2071, 0xad00, 0x7128, 0x2001, 0xaf90,
+ 0x2102, 0x2001, 0xaf98, 0x2102, 0xa182, 0x0211, 0x1218, 0x2009,
+ 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009, 0x0007, 0x00d0,
+ 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0, 0xa182, 0x0349,
+ 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421, 0x1218, 0x2009,
+ 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009, 0x0003, 0x0010,
+ 0x2009, 0x0002, 0x2079, 0x0200, 0x7912, 0x7817, 0x0004, 0x080c,
+ 0x2651, 0x00fe, 0x00ee, 0x001e, 0x0005, 0x7938, 0x080c, 0x14f6,
+ 0x0126, 0x2091, 0x2800, 0x2061, 0x0100, 0x2071, 0xad00, 0x6024,
+ 0x6026, 0x6053, 0x0030, 0x080c, 0x2690, 0x6050, 0xa084, 0xfe7f,
+ 0x6052, 0x2009, 0x00ef, 0x6132, 0x6136, 0x080c, 0x26a0, 0x60e7,
+ 0x0000, 0x61ea, 0x60e3, 0x0008, 0x604b, 0xf7f7, 0x6043, 0x0000,
+ 0x602f, 0x0080, 0x602f, 0x0000, 0x6007, 0x0e9f, 0x601b, 0x001e,
+ 0x600f, 0x00ff, 0x2001, 0xaf8c, 0x2003, 0x00ff, 0x602b, 0x002f,
+ 0x012e, 0x0005, 0x2001, 0xad31, 0x2003, 0x0000, 0x2001, 0xad30,
+ 0x2003, 0x0001, 0x0005, 0x0126, 0x2091, 0x2800, 0x0006, 0x0016,
+ 0x0026, 0x6124, 0xa184, 0x1e2c, 0x1118, 0xa184, 0x0007, 0x002a,
+ 0xa195, 0x0004, 0xa284, 0x0007, 0x0002, 0x23a7, 0x238d, 0x2390,
+ 0x2393, 0x2398, 0x239a, 0x239e, 0x23a2, 0x080c, 0x6699, 0x00b8,
+ 0x080c, 0x6774, 0x00a0, 0x080c, 0x6774, 0x080c, 0x6699, 0x0078,
+ 0x0099, 0x0068, 0x080c, 0x6699, 0x0079, 0x0048, 0x080c, 0x6774,
+ 0x0059, 0x0028, 0x080c, 0x6774, 0x080c, 0x6699, 0x0029, 0x002e,
+ 0x001e, 0x000e, 0x012e, 0x0005, 0x6124, 0xd19c, 0x1904, 0x25bf,
+ 0x080c, 0x574f, 0x0578, 0x7000, 0xa086, 0x0003, 0x0198, 0x6024,
+ 0xa084, 0x1800, 0x0178, 0x080c, 0x5775, 0x0118, 0x080c, 0x5761,
+ 0x1148, 0x6027, 0x0020, 0x6043, 0x0000, 0x2001, 0xaf9d, 0x2003,
+ 0xaaaa, 0x0458, 0x080c, 0x5775, 0x15d0, 0x6024, 0xa084, 0x1800,
+ 0x1108, 0x04a8, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e,
+ 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a,
+ 0x0804, 0x25bf, 0xd1ac, 0x1518, 0x6024, 0xd0dc, 0x1170, 0xd0e4,
+ 0x1188, 0xd0d4, 0x11a0, 0xd0cc, 0x0130, 0x7088, 0xa086, 0x0028,
+ 0x1110, 0x080c, 0x58da, 0x0804, 0x25bf, 0x2001, 0xaf9e, 0x2003,
+ 0x0000, 0x0048, 0x2001, 0xaf9e, 0x2003, 0x0002, 0x0020, 0x080c,
+ 0x584d, 0x0804, 0x25bf, 0x080c, 0x597a, 0x0804, 0x25bf, 0xd1ac,
+ 0x0904, 0x2507, 0x080c, 0x574f, 0x11d8, 0x6027, 0x0020, 0x0006,
+ 0x0026, 0x0036, 0x080c, 0x576b, 0x1170, 0x2001, 0xaf9e, 0x2003,
+ 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c, 0x569a, 0x003e,
+ 0x002e, 0x000e, 0x0005, 0x003e, 0x002e, 0x000e, 0x080c, 0x5726,
+ 0x0016, 0x0046, 0x00c6, 0x644c, 0xa486, 0xf0f0, 0x1138, 0x2061,
+ 0x0100, 0x644a, 0x6043, 0x0090, 0x6043, 0x0010, 0x74ca, 0xa48c,
+ 0xff00, 0x7034, 0xd084, 0x0178, 0xa186, 0xf800, 0x1160, 0x7038,
+ 0xd084, 0x1148, 0xc085, 0x703a, 0x0036, 0x2418, 0x2011, 0x8016,
+ 0x080c, 0x3c5c, 0x003e, 0xa196, 0xff00, 0x05b8, 0x7050, 0xa084,
+ 0x00ff, 0x810f, 0xa116, 0x0588, 0x7130, 0xd184, 0x1570, 0x2011,
+ 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011, 0xad52,
+ 0x2214, 0xd2ac, 0x1510, 0x6240, 0xa294, 0x0010, 0x0130, 0x6248,
+ 0xa294, 0xff00, 0xa296, 0xff00, 0x01c0, 0x7030, 0xd08c, 0x0904,
+ 0x24d2, 0x7034, 0xd08c, 0x1140, 0x2001, 0xad0c, 0x200c, 0xd1ac,
+ 0x1904, 0x24d2, 0xc1ad, 0x2102, 0x0036, 0x73c8, 0x2011, 0x8013,
+ 0x080c, 0x3c5c, 0x003e, 0x0804, 0x24d2, 0x7034, 0xd08c, 0x1140,
+ 0x2001, 0xad0c, 0x200c, 0xd1ac, 0x1904, 0x24d2, 0xc1ad, 0x2102,
+ 0x0036, 0x73c8, 0x2011, 0x8013, 0x080c, 0x3c5c, 0x003e, 0x7130,
+ 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x01d0, 0x0016,
+ 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019, 0x000e,
+ 0x080c, 0xa8eb, 0xa484, 0x00ff, 0xa080, 0x2be6, 0x200d, 0xa18c,
+ 0xff00, 0x810f, 0x8127, 0xa006, 0x2009, 0x000e, 0x080c, 0xa96c,
+ 0x001e, 0xd1ac, 0x1148, 0x0016, 0x2009, 0x0000, 0x2019, 0x0004,
+ 0x080c, 0x2aac, 0x001e, 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009,
+ 0x0000, 0x080c, 0x4cdc, 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04,
+ 0x24c9, 0x015e, 0x00ce, 0x004e, 0x2011, 0x0003, 0x080c, 0x7adf,
+ 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581,
+ 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3, 0x0000,
+ 0x001e, 0x2001, 0xad00, 0x2014, 0xa296, 0x0004, 0x1128, 0xd19c,
+ 0x1118, 0x6228, 0xc29d, 0x622a, 0x2003, 0x0001, 0x2001, 0xad22,
+ 0x2003, 0x0000, 0x6027, 0x0020, 0x080c, 0x5775, 0x1140, 0x0016,
+ 0x2009, 0x07d0, 0x2011, 0x567b, 0x080c, 0x6593, 0x001e, 0xd194,
+ 0x0904, 0x25bf, 0x0016, 0x6220, 0xd2b4, 0x0904, 0x2570, 0x080c,
+ 0x6581, 0x080c, 0x7834, 0x6027, 0x0004, 0x00f6, 0x2019, 0xafd0,
+ 0x2304, 0xa07d, 0x0570, 0x7804, 0xa086, 0x0032, 0x1550, 0x00d6,
+ 0x00c6, 0x00e6, 0x2069, 0x0140, 0x618c, 0x6288, 0x7818, 0x608e,
+ 0x7808, 0x608a, 0x6043, 0x0002, 0x2001, 0x0003, 0x8001, 0x1df0,
+ 0x6043, 0x0000, 0x6803, 0x1000, 0x6803, 0x0000, 0x618e, 0x628a,
+ 0x080c, 0x6b73, 0x080c, 0x6c50, 0x7810, 0x2070, 0x7037, 0x0103,
+ 0x2f60, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00de, 0x00fe, 0x001e,
+ 0x0005, 0x00fe, 0x00d6, 0x2069, 0x0140, 0x6804, 0xa084, 0x4000,
+ 0x0120, 0x6803, 0x1000, 0x6803, 0x0000, 0x00de, 0x00c6, 0x2061,
+ 0xafc7, 0x6028, 0xa09a, 0x00c8, 0x1238, 0x8000, 0x602a, 0x00ce,
+ 0x080c, 0x7827, 0x0804, 0x25be, 0x2019, 0xafd0, 0x2304, 0xa065,
+ 0x0120, 0x2009, 0x0027, 0x080c, 0x80a7, 0x00ce, 0x0804, 0x25be,
+ 0xd2bc, 0x0904, 0x25be, 0x080c, 0x658e, 0x6014, 0xa084, 0x0184,
+ 0xa085, 0x0010, 0x6016, 0x6027, 0x0004, 0x00d6, 0x2069, 0x0140,
+ 0x6804, 0xa084, 0x4000, 0x0120, 0x6803, 0x1000, 0x6803, 0x0000,
+ 0x00de, 0x00c6, 0x2061, 0xafc7, 0x6044, 0xa09a, 0x00c8, 0x12f0,
+ 0x8000, 0x6046, 0x603c, 0x00ce, 0xa005, 0x0540, 0x2009, 0x07d0,
+ 0x080c, 0x6586, 0xa080, 0x0007, 0x2004, 0xa086, 0x0006, 0x1138,
+ 0x6114, 0xa18c, 0x0184, 0xa18d, 0x0012, 0x6116, 0x00b8, 0x6114,
+ 0xa18c, 0x0184, 0xa18d, 0x0016, 0x6116, 0x0080, 0x0036, 0x2019,
+ 0x0001, 0x080c, 0x7a64, 0x003e, 0x2019, 0xafd6, 0x2304, 0xa065,
+ 0x0120, 0x2009, 0x004f, 0x080c, 0x80a7, 0x00ce, 0x001e, 0xd19c,
+ 0x0904, 0x261a, 0x7034, 0xd0ac, 0x1560, 0x0016, 0x0156, 0x6027,
+ 0x0008, 0x602f, 0x0020, 0x20a9, 0x0006, 0x1d04, 0x25cd, 0x2091,
+ 0x6000, 0x1f04, 0x25cd, 0x602f, 0x0000, 0x6150, 0xa185, 0x1400,
+ 0x6052, 0x20a9, 0x0366, 0x1d04, 0x25db, 0x2091, 0x6000, 0x6020,
+ 0xd09c, 0x1130, 0x015e, 0x6152, 0x001e, 0x6027, 0x0008, 0x0490,
+ 0x080c, 0x2760, 0x1f04, 0x25db, 0x015e, 0x6152, 0x001e, 0x6027,
+ 0x0008, 0x0016, 0x6028, 0xc09c, 0x602a, 0x2011, 0x0003, 0x080c,
+ 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c, 0x79e1, 0x080c,
+ 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64, 0x003e, 0x60e3,
+ 0x0000, 0x080c, 0xac8d, 0x080c, 0xaca8, 0xa085, 0x0001, 0x080c,
+ 0x5793, 0x2001, 0xad00, 0x2003, 0x0004, 0x6027, 0x0008, 0x080c,
+ 0x12cc, 0x001e, 0xa18c, 0xffd0, 0x6126, 0x0005, 0x0006, 0x0016,
+ 0x0026, 0x00e6, 0x00f6, 0x0126, 0x2091, 0x8000, 0x2071, 0xad00,
+ 0x71c0, 0x70c2, 0xa116, 0x01f0, 0x81ff, 0x0128, 0x2011, 0x8011,
+ 0x080c, 0x3c5c, 0x00b8, 0x2011, 0x8012, 0x080c, 0x3c5c, 0x2001,
+ 0xad71, 0x2004, 0xd0fc, 0x1170, 0x0036, 0x00c6, 0x080c, 0x26eb,
+ 0x2061, 0x0100, 0x2019, 0x0028, 0x2009, 0x0000, 0x080c, 0x2aac,
+ 0x00ce, 0x003e, 0x012e, 0x00fe, 0x00ee, 0x002e, 0x001e, 0x000e,
+ 0x0005, 0x00c6, 0x00f6, 0x0006, 0x0026, 0x2061, 0x0100, 0xa190,
+ 0x2664, 0x2205, 0x60f2, 0x2011, 0x2671, 0x2205, 0x60ee, 0x002e,
+ 0x000e, 0x00fe, 0x00ce, 0x0005, 0x0840, 0x0840, 0x0840, 0x0580,
+ 0x0420, 0x0348, 0x02c0, 0x0258, 0x0210, 0x01a8, 0x01a8, 0x01a8,
+ 0x01a8, 0x0140, 0x00f8, 0x00d0, 0x00b0, 0x00a0, 0x2028, 0xa18c,
+ 0x00ff, 0x2130, 0xa094, 0xff00, 0x1110, 0x81ff, 0x0118, 0x080c,
+ 0x6278, 0x0038, 0xa080, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f,
+ 0xa006, 0x0005, 0xa080, 0x2be6, 0x200d, 0xa18c, 0x00ff, 0x0005,
+ 0x00d6, 0x2069, 0x0140, 0x2001, 0xad14, 0x2003, 0x00ef, 0x20a9,
+ 0x0010, 0xa006, 0x6852, 0x6856, 0x1f04, 0x269b, 0x00de, 0x0005,
+ 0x0006, 0x00d6, 0x0026, 0x2069, 0x0140, 0x2001, 0xad14, 0x2102,
+ 0x8114, 0x8214, 0x8214, 0x8214, 0x20a9, 0x0010, 0x6853, 0x0000,
+ 0xa006, 0x82ff, 0x1128, 0xa184, 0x000f, 0xa080, 0xacae, 0x2005,
+ 0x6856, 0x8211, 0x1f04, 0x26b0, 0x002e, 0x00de, 0x000e, 0x0005,
+ 0x00c6, 0x2061, 0xad00, 0x6030, 0x0110, 0xc09d, 0x0008, 0xc09c,
+ 0x6032, 0x00ce, 0x0005, 0x0156, 0x00d6, 0x0026, 0x0016, 0x0006,
+ 0x2069, 0x0140, 0x6980, 0xa116, 0x0180, 0xa112, 0x1230, 0x8212,
+ 0x8210, 0x22a8, 0x2001, 0x0402, 0x0018, 0x22a8, 0x2001, 0x0404,
+ 0x680e, 0x1f04, 0x26e0, 0x680f, 0x0000, 0x000e, 0x001e, 0x002e,
+ 0x00de, 0x015e, 0x0005, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+ 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002e, 0x080c,
+ 0xa96c, 0x004e, 0x0005, 0x00f6, 0x0016, 0x0026, 0x2079, 0x0140,
+ 0x78c4, 0xd0dc, 0x0548, 0xa084, 0x0700, 0xa08e, 0x0300, 0x1520,
+ 0x2011, 0x0000, 0x2009, 0x0002, 0x2300, 0xa080, 0x0020, 0x2018,
+ 0x2300, 0x080c, 0x6665, 0x2011, 0x0030, 0x2200, 0x8007, 0xa085,
+ 0x004c, 0x78c2, 0x2009, 0x0204, 0x210c, 0x2200, 0xa100, 0x2009,
+ 0x0138, 0x200a, 0x080c, 0x574f, 0x1118, 0x2009, 0xaf8e, 0x200a,
+ 0x002e, 0x001e, 0x00fe, 0x0005, 0x78c3, 0x0000, 0x0cc8, 0x0126,
+ 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x2001, 0x0170, 0x200c,
+ 0x8000, 0x2014, 0xa184, 0x0003, 0x0110, 0x0804, 0x1a6a, 0x002e,
+ 0x001e, 0x000e, 0x012e, 0x0005, 0x0006, 0x2001, 0x0100, 0x2004,
+ 0xa082, 0x0005, 0x000e, 0x0268, 0x2001, 0x0170, 0x200c, 0xa18c,
+ 0x00ff, 0xa18e, 0x004c, 0x1128, 0x200c, 0xa18c, 0xff00, 0x810f,
+ 0x0010, 0x2009, 0x0000, 0x2001, 0x0204, 0x2004, 0xa108, 0x0005,
+ 0x0006, 0x0156, 0x00f6, 0x2079, 0x0100, 0x20a9, 0x000a, 0x7854,
+ 0xd08c, 0x1110, 0x1f04, 0x2767, 0x00fe, 0x015e, 0x000e, 0x0005,
+ 0x0016, 0x00c6, 0x0006, 0x2061, 0x0100, 0x6030, 0x0006, 0x6048,
+ 0x0006, 0x60e4, 0x0006, 0x60e8, 0x0006, 0x6050, 0x0006, 0x60f0,
+ 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006, 0x6004, 0x0006, 0x6028,
+ 0x0006, 0x60e0, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000, 0xe000,
+ 0xe000, 0xe000, 0xe000, 0x602f, 0x0040, 0x602f, 0x0000, 0x000e,
+ 0x60e2, 0x000e, 0x602a, 0x000e, 0x6006, 0x000e, 0x600e, 0x000e,
+ 0x60ee, 0x000e, 0x60f2, 0x000e, 0x6052, 0x000e, 0x60ea, 0x000e,
+ 0x60e6, 0x000e, 0x604a, 0x000e, 0x6032, 0x6036, 0x2008, 0x080c,
+ 0x26a0, 0x000e, 0x00ce, 0x001e, 0x0005, 0x2845, 0x2849, 0x284d,
+ 0x2853, 0x2859, 0x285f, 0x2865, 0x286d, 0x2875, 0x287b, 0x2881,
+ 0x2889, 0x2891, 0x2899, 0x28a1, 0x28ab, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b7, 0x28b7, 0x28bc,
+ 0x28bc, 0x28c3, 0x28c3, 0x28ca, 0x28ca, 0x28d3, 0x28d3, 0x28da,
+ 0x28da, 0x28e3, 0x28e3, 0x28ec, 0x28ec, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5,
+ 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x28b5, 0x0106, 0x0006, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+ 0x2373, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106,
+ 0x0006, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+ 0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+ 0x2373, 0x080c, 0x223d, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c,
+ 0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x228f, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x228f, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x080c, 0x223d, 0x080c, 0x228f, 0x0804,
+ 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c, 0x223d, 0x080c,
+ 0x228f, 0x0804, 0x28f7, 0x0106, 0x0006, 0x080c, 0x2373, 0x080c,
+ 0x223d, 0x080c, 0x228f, 0x0804, 0x28f7, 0xe000, 0x0cf0, 0x0106,
+ 0x0006, 0x080c, 0x272f, 0x04d8, 0x0106, 0x0006, 0x080c, 0x272f,
+ 0x080c, 0x2373, 0x04a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+ 0x223d, 0x0468, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+ 0x080c, 0x223d, 0x0420, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+ 0x228f, 0x00e8, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c, 0x2373,
+ 0x080c, 0x228f, 0x00a0, 0x0106, 0x0006, 0x080c, 0x272f, 0x080c,
+ 0x223d, 0x080c, 0x228f, 0x0058, 0x0106, 0x0006, 0x080c, 0x272f,
+ 0x080c, 0x2373, 0x080c, 0x223d, 0x080c, 0x228f, 0x0000, 0x000e,
+ 0x010e, 0x000d, 0x00c6, 0x0026, 0x0046, 0x2021, 0x0000, 0x080c,
+ 0x502d, 0x1904, 0x29d4, 0x72d0, 0x2001, 0xaf9d, 0x2004, 0xa005,
+ 0x1110, 0xd29c, 0x0148, 0xd284, 0x1138, 0xd2bc, 0x1904, 0x29d4,
+ 0x080c, 0x29d8, 0x0804, 0x29d4, 0x080c, 0x574f, 0x1120, 0x709b,
+ 0xffff, 0x0804, 0x29d4, 0xd294, 0x0120, 0x709b, 0xffff, 0x0804,
+ 0x29d4, 0x2001, 0xad14, 0x203c, 0x7284, 0xd284, 0x0904, 0x2976,
+ 0xd28c, 0x1904, 0x2976, 0x0036, 0x7398, 0xa38e, 0xffff, 0x1110,
+ 0x2019, 0x0001, 0x8314, 0xa2e0, 0xb3c0, 0x2c04, 0xa38c, 0x0001,
+ 0x0120, 0xa084, 0xff00, 0x8007, 0x0010, 0xa084, 0x00ff, 0xa70e,
+ 0x0560, 0xa08e, 0x0000, 0x0548, 0xa08e, 0x00ff, 0x1150, 0x7230,
+ 0xd284, 0x1538, 0x7284, 0xc28d, 0x7286, 0x709b, 0xffff, 0x003e,
+ 0x0428, 0x2009, 0x0000, 0x080c, 0x2676, 0x080c, 0x4c80, 0x11b8,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1150, 0x7030, 0xd08c,
+ 0x0118, 0x6000, 0xd0bc, 0x0120, 0x080c, 0x29eb, 0x0140, 0x0028,
+ 0x080c, 0x2b1a, 0x080c, 0x2a19, 0x0110, 0x8318, 0x0818, 0x739a,
+ 0x0010, 0x709b, 0xffff, 0x003e, 0x0804, 0x29d4, 0xa780, 0x2be6,
+ 0x203d, 0xa7bc, 0xff00, 0x873f, 0x2041, 0x007e, 0x7098, 0xa096,
+ 0xffff, 0x1120, 0x2009, 0x0000, 0x28a8, 0x0050, 0xa812, 0x0220,
+ 0x2008, 0xa802, 0x20a8, 0x0020, 0x709b, 0xffff, 0x0804, 0x29d4,
+ 0x2700, 0x0156, 0x0016, 0xa106, 0x05a0, 0xc484, 0x080c, 0x4cdc,
+ 0x0120, 0x080c, 0x4c80, 0x15a8, 0x0008, 0xc485, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x1130, 0x7030, 0xd08c, 0x01e8, 0x6000,
+ 0xd0bc, 0x11d0, 0x7284, 0xd28c, 0x0188, 0x6004, 0xa084, 0x00ff,
+ 0xa082, 0x0006, 0x02b0, 0xd484, 0x1118, 0x080c, 0x4c9f, 0x0028,
+ 0x080c, 0x2b9c, 0x0170, 0x080c, 0x2bc9, 0x0058, 0x080c, 0x2b1a,
+ 0x080c, 0x2a19, 0x0170, 0x0028, 0x080c, 0x2b9c, 0x0110, 0x0419,
+ 0x0140, 0x001e, 0x8108, 0x015e, 0x1f04, 0x2990, 0x709b, 0xffff,
+ 0x0018, 0x001e, 0x015e, 0x719a, 0x004e, 0x002e, 0x00ce, 0x0005,
+ 0x00c6, 0x0016, 0x709b, 0x0000, 0x2009, 0x007e, 0x080c, 0x4c80,
+ 0x1138, 0x080c, 0x2b1a, 0x04a9, 0x0118, 0x70d0, 0xc0bd, 0x70d2,
+ 0x001e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68,
+ 0x2001, 0xad56, 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807,
+ 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2001,
+ 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0000, 0x080c, 0x4c30, 0x0126,
+ 0x2091, 0x8000, 0x7094, 0x8000, 0x7096, 0x012e, 0x2009, 0x0004,
+ 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e,
+ 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6, 0x2c68, 0x2001, 0xad56,
+ 0x2004, 0xa084, 0x00ff, 0x6842, 0x080c, 0x9807, 0x0550, 0x2d00,
+ 0x601a, 0x6800, 0xc0c4, 0x6802, 0x68a0, 0xa086, 0x007e, 0x0140,
+ 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1110, 0x080c, 0x2ad9,
+ 0x080c, 0x9956, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e,
+ 0x2001, 0x0002, 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x7094,
+ 0x8000, 0x7096, 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+ 0x0001, 0x00ce, 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x0026,
+ 0x2009, 0x0080, 0x080c, 0x4c80, 0x1120, 0x0031, 0x0110, 0x70d7,
+ 0xffff, 0x002e, 0x00ce, 0x0005, 0x0016, 0x0076, 0x00d6, 0x00c6,
+ 0x2c68, 0x080c, 0x8022, 0x01d8, 0x2d00, 0x601a, 0x080c, 0x9956,
+ 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002,
+ 0x080c, 0x4c30, 0x0126, 0x2091, 0x8000, 0x70d8, 0x8000, 0x70da,
+ 0x012e, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085, 0x0001, 0x00ce,
+ 0x00de, 0x007e, 0x001e, 0x0005, 0x00c6, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x2009, 0x007f, 0x080c, 0x4c80, 0x1190, 0x2c68, 0x080c,
+ 0x8022, 0x0170, 0x2d00, 0x601a, 0x6312, 0x601f, 0x0001, 0x620a,
+ 0x080c, 0x9956, 0x2009, 0x0022, 0x080c, 0x80a7, 0xa085, 0x0001,
+ 0x012e, 0x00de, 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0066, 0x0036,
+ 0x0026, 0x080c, 0x68f3, 0x080c, 0x689d, 0x080c, 0x8a15, 0x2130,
+ 0x81ff, 0x0128, 0x20a9, 0x007e, 0x2009, 0x0000, 0x0020, 0x20a9,
+ 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1120, 0x080c,
+ 0x4ecf, 0x080c, 0x493a, 0x001e, 0x8108, 0x1f04, 0x2ac3, 0x86ff,
+ 0x1110, 0x080c, 0x11d4, 0x002e, 0x003e, 0x006e, 0x00ce, 0x00ee,
+ 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016, 0x6218, 0x2270,
+ 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+ 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x001e,
+ 0x2e60, 0x080c, 0x4ecf, 0x6210, 0x6314, 0x080c, 0x493a, 0x6212,
+ 0x6316, 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6,
+ 0x0006, 0x6018, 0xa080, 0x0028, 0x2004, 0xa086, 0x0080, 0x0150,
+ 0x2071, 0xad00, 0x7094, 0xa005, 0x0110, 0x8001, 0x7096, 0x000e,
+ 0x00ee, 0x0005, 0x2071, 0xad00, 0x70d8, 0xa005, 0x0dc0, 0x8001,
+ 0x70da, 0x0ca8, 0x6000, 0xc08c, 0x6002, 0x0005, 0x00f6, 0x00e6,
+ 0x00c6, 0x0036, 0x0026, 0x0016, 0x0156, 0x2178, 0x81ff, 0x1118,
+ 0x20a9, 0x0001, 0x0098, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0150,
+ 0xd0a4, 0x0140, 0xa006, 0x0046, 0x2020, 0x2009, 0x002d, 0x080c,
+ 0xa96c, 0x004e, 0x20a9, 0x00ff, 0x2011, 0x0000, 0x0026, 0xa28e,
+ 0x007e, 0x05c8, 0xa28e, 0x007f, 0x05b0, 0xa28e, 0x0080, 0x0598,
+ 0xa288, 0xae34, 0x210c, 0x81ff, 0x0570, 0x8fff, 0x05c1, 0x00c6,
+ 0x2160, 0x2001, 0x0001, 0x080c, 0x5037, 0x00ce, 0x2019, 0x0029,
+ 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x00c6,
+ 0x0026, 0x2160, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x1118,
+ 0x6007, 0x0404, 0x0028, 0x2001, 0x0004, 0x8007, 0xa215, 0x6206,
+ 0x002e, 0x00ce, 0x0016, 0x2c08, 0x080c, 0xa712, 0x001e, 0x007e,
+ 0x2160, 0x080c, 0x4ecf, 0x002e, 0x8210, 0x1f04, 0x2b3e, 0x015e,
+ 0x001e, 0x002e, 0x003e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x0046,
+ 0x0026, 0x0016, 0x2001, 0xad52, 0x2004, 0xd0c4, 0x0148, 0xd0a4,
+ 0x0138, 0xa006, 0x2220, 0x8427, 0x2009, 0x0029, 0x080c, 0xa96c,
+ 0x001e, 0x002e, 0x004e, 0x0005, 0x0016, 0x0026, 0x0036, 0x00c6,
+ 0x7284, 0x82ff, 0x01f8, 0x2011, 0xad52, 0x2214, 0xd2ac, 0x11d0,
+ 0x2100, 0x080c, 0x268a, 0x81ff, 0x01b8, 0x2019, 0x0001, 0x8314,
+ 0xa2e0, 0xb3c0, 0x2c04, 0xd384, 0x0120, 0xa084, 0xff00, 0x8007,
+ 0x0010, 0xa084, 0x00ff, 0xa116, 0x0138, 0xa096, 0x00ff, 0x0110,
+ 0x8318, 0x0c68, 0xa085, 0x0001, 0x00ce, 0x003e, 0x002e, 0x001e,
+ 0x0005, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0xa180, 0xae34,
+ 0x2004, 0xa065, 0x0178, 0x0016, 0x00c6, 0x080c, 0x9807, 0x001e,
+ 0x090c, 0x14f6, 0x611a, 0x080c, 0x2ad9, 0x080c, 0x8078, 0x001e,
+ 0x080c, 0x4c9f, 0x012e, 0x00ce, 0x001e, 0x0005, 0x7eef, 0x7de8,
+ 0x7ce4, 0x80e2, 0x7be1, 0x80e0, 0x80dc, 0x80da, 0x7ad9, 0x80d6,
+ 0x80d5, 0x80d4, 0x80d3, 0x80d2, 0x80d1, 0x79ce, 0x78cd, 0x80cc,
+ 0x80cb, 0x80ca, 0x80c9, 0x80c7, 0x80c6, 0x77c5, 0x76c3, 0x80bc,
+ 0x80ba, 0x75b9, 0x80b6, 0x74b5, 0x73b4, 0x72b3, 0x80b2, 0x80b1,
+ 0x80ae, 0x71ad, 0x80ac, 0x70ab, 0x6faa, 0x6ea9, 0x80a7, 0x6da6,
+ 0x6ca5, 0x6ba3, 0x6a9f, 0x699e, 0x689d, 0x809b, 0x8098, 0x6797,
+ 0x6690, 0x658f, 0x6488, 0x6384, 0x6282, 0x8081, 0x8080, 0x617c,
+ 0x607a, 0x8079, 0x5f76, 0x8075, 0x8074, 0x8073, 0x8072, 0x8071,
+ 0x806e, 0x5e6d, 0x806c, 0x5d6b, 0x5c6a, 0x5b69, 0x8067, 0x5a66,
+ 0x5965, 0x5863, 0x575c, 0x565a, 0x5559, 0x8056, 0x8055, 0x5454,
+ 0x5353, 0x5252, 0x5151, 0x504e, 0x4f4d, 0x804c, 0x804b, 0x4e4a,
+ 0x4d49, 0x8047, 0x4c46, 0x8045, 0x8043, 0x803c, 0x803a, 0x8039,
+ 0x8036, 0x4b35, 0x8034, 0x4a33, 0x4932, 0x4831, 0x802e, 0x472d,
+ 0x462c, 0x452b, 0x442a, 0x4329, 0x4227, 0x8026, 0x8025, 0x4123,
+ 0x401f, 0x3f1e, 0x3e1d, 0x3d1b, 0x3c18, 0x8017, 0x8010, 0x3b0f,
+ 0x3a08, 0x8004, 0x3902, 0x8001, 0x8000, 0x8000, 0x3800, 0x3700,
+ 0x3600, 0x8000, 0x3500, 0x8000, 0x8000, 0x8000, 0x3400, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3300, 0x3200, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x3100, 0x3000, 0x8000,
+ 0x8000, 0x2f00, 0x8000, 0x2e00, 0x2d00, 0x2c00, 0x8000, 0x8000,
+ 0x8000, 0x2b00, 0x8000, 0x2a00, 0x2900, 0x2800, 0x8000, 0x2700,
+ 0x2600, 0x2500, 0x2400, 0x2300, 0x2200, 0x8000, 0x8000, 0x2100,
+ 0x2000, 0x1f00, 0x1e00, 0x1d00, 0x1c00, 0x8000, 0x8000, 0x1b00,
+ 0x1a00, 0x8000, 0x1900, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x1800, 0x8000, 0x1700, 0x1600, 0x1500, 0x8000, 0x1400,
+ 0x1300, 0x1200, 0x1100, 0x1000, 0x0f00, 0x8000, 0x8000, 0x0e00,
+ 0x0d00, 0x0c00, 0x0b00, 0x0a00, 0x0900, 0x8000, 0x8000, 0x0800,
+ 0x0700, 0x8000, 0x0600, 0x8000, 0x8000, 0x8000, 0x0500, 0x0400,
+ 0x0300, 0x8000, 0x0200, 0x8000, 0x8000, 0x8000, 0x0100, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x0000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
+ 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x2071, 0xad81,
+ 0x7003, 0x0002, 0xa006, 0x7012, 0x7016, 0x703a, 0x703e, 0x7033,
+ 0xad91, 0x7037, 0xad91, 0x7007, 0x0001, 0x2061, 0xadd1, 0x6003,
+ 0x0002, 0x0005, 0x1004, 0x2d0c, 0x0e04, 0x2d0c, 0x2071, 0xad81,
+ 0x2b78, 0x7818, 0xd084, 0x1140, 0x2a60, 0x7820, 0xa08e, 0x0069,
+ 0x1904, 0x2df1, 0x0804, 0x2d8a, 0x0005, 0x2071, 0xad81, 0x7004,
+ 0x0002, 0x2d15, 0x2d16, 0x2d1f, 0x2d30, 0x0005, 0x1004, 0x2d1e,
+ 0x0e04, 0x2d1e, 0x2b78, 0x7818, 0xd084, 0x01e8, 0x0005, 0x2b78,
+ 0x2061, 0xadd1, 0x6008, 0xa08e, 0x0100, 0x0128, 0xa086, 0x0200,
+ 0x0904, 0x2deb, 0x0005, 0x7014, 0x2068, 0x2a60, 0x7018, 0x0807,
+ 0x7010, 0x2068, 0x6834, 0xa086, 0x0103, 0x0108, 0x0005, 0x2a60,
+ 0x2b78, 0x7018, 0x0807, 0x2a60, 0x7820, 0xa08a, 0x0040, 0x1210,
+ 0x61c0, 0x0042, 0x2100, 0xa08a, 0x003f, 0x1a04, 0x2de8, 0x61c0,
+ 0x0804, 0x2d8a, 0x2dcc, 0x2df7, 0x2dff, 0x2e03, 0x2e0b, 0x2e11,
+ 0x2e15, 0x2e21, 0x2e24, 0x2e2e, 0x2e31, 0x2de8, 0x2de8, 0x2de8,
+ 0x2e34, 0x2de8, 0x2e43, 0x2e5a, 0x2e71, 0x2ee8, 0x2eed, 0x2f16,
+ 0x2f67, 0x2f78, 0x2f96, 0x2fcd, 0x2fd7, 0x2fe4, 0x2ff7, 0x3018,
+ 0x3021, 0x3057, 0x305d, 0x2de8, 0x3086, 0x2de8, 0x2de8, 0x2de8,
+ 0x2de8, 0x2de8, 0x308d, 0x3097, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+ 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x309f, 0x2de8, 0x2de8, 0x2de8,
+ 0x2de8, 0x2de8, 0x30b1, 0x30b9, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+ 0x2de8, 0x2de8, 0x0002, 0x30cb, 0x311f, 0x317a, 0x318a, 0x2de8,
+ 0x31a4, 0x35cb, 0x3fbb, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x2de8,
+ 0x2de8, 0x2de8, 0x2de8, 0x2e2e, 0x2e31, 0x35cd, 0x2de8, 0x35da,
+ 0x403c, 0x4097, 0x40fb, 0x2de8, 0x415a, 0x4180, 0x419f, 0x2de8,
+ 0x2de8, 0x2de8, 0x2de8, 0x35de, 0x376b, 0x3785, 0x37a3, 0x3804,
+ 0x3858, 0x3863, 0x389a, 0x38a9, 0x38b8, 0x38bb, 0x38de, 0x3928,
+ 0x398e, 0x399b, 0x3a9c, 0x3bb3, 0x3bdc, 0x3cda, 0x3cfc, 0x3d08,
+ 0x3d41, 0x3e05, 0x2de8, 0x2de8, 0x2de8, 0x2de8, 0x3e6d, 0x3e88,
+ 0x3efa, 0x3fac, 0x713c, 0x0000, 0x2021, 0x4000, 0x080c, 0x3c39,
+ 0x0126, 0x2091, 0x8000, 0x0e04, 0x2dd8, 0x7818, 0xd084, 0x0110,
+ 0x012e, 0x0cb0, 0x7c22, 0x7926, 0x7a2a, 0x7b2e, 0x781b, 0x0001,
+ 0x2091, 0x4080, 0x7007, 0x0001, 0x2091, 0x5000, 0x012e, 0x0005,
+ 0x2021, 0x4001, 0x0c18, 0x2021, 0x4002, 0x0c00, 0x2021, 0x4003,
+ 0x08e8, 0x2021, 0x4005, 0x08d0, 0x2021, 0x4006, 0x08b8, 0xa02e,
+ 0x2520, 0x7b28, 0x7a2c, 0x7824, 0x7930, 0x0804, 0x3c46, 0x7823,
+ 0x0004, 0x7824, 0x0807, 0xa02e, 0x2520, 0x7b28, 0x7a2c, 0x7824,
+ 0x7930, 0x0804, 0x3c49, 0x7924, 0x7828, 0x2114, 0x200a, 0x0804,
+ 0x2dcc, 0x7924, 0x2114, 0x0804, 0x2dcc, 0x2099, 0x0009, 0x20a1,
+ 0x0009, 0x20a9, 0x0007, 0x53a3, 0x7924, 0x7a28, 0x7b2c, 0x0804,
+ 0x2dcc, 0x7824, 0x2060, 0x0090, 0x2009, 0x0002, 0x2011, 0x0001,
+ 0x2019, 0x001b, 0x783b, 0x0017, 0x0804, 0x2dcc, 0x7d38, 0x7c3c,
+ 0x0840, 0x7d38, 0x7c3c, 0x0888, 0x2061, 0x1000, 0xe10c, 0xa006,
+ 0x2c15, 0xa200, 0x8c60, 0x8109, 0x1dd8, 0x2010, 0xa005, 0x0904,
+ 0x2dcc, 0x0804, 0x2dee, 0x2069, 0xad51, 0x7824, 0x7930, 0xa11a,
+ 0x1a04, 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684a, 0x6942, 0x782c,
+ 0x6852, 0x7828, 0x6856, 0xa006, 0x685a, 0x685e, 0x080c, 0x5a1c,
+ 0x0804, 0x2dcc, 0x2069, 0xad51, 0x7824, 0x7934, 0xa11a, 0x1a04,
+ 0x2df4, 0x8019, 0x0904, 0x2df4, 0x684e, 0x6946, 0x782c, 0x6862,
+ 0x7828, 0x6866, 0xa006, 0x686a, 0x686e, 0x080c, 0x50d9, 0x0804,
+ 0x2dcc, 0xa02e, 0x2520, 0x81ff, 0x1904, 0x2df1, 0x7924, 0x7b28,
+ 0x7a2c, 0x20a9, 0x0005, 0x20a1, 0xad88, 0x41a1, 0x080c, 0x3c05,
+ 0x0904, 0x2df1, 0x2009, 0x0020, 0x080c, 0x3c46, 0x701b, 0x2e89,
+ 0x0005, 0x6834, 0x2008, 0xa084, 0x00ff, 0xa096, 0x0011, 0x0120,
+ 0xa096, 0x0019, 0x1904, 0x2df1, 0x810f, 0xa18c, 0x00ff, 0x0904,
+ 0x2df1, 0x710e, 0x700c, 0x8001, 0x0528, 0x700e, 0x080c, 0x3c05,
+ 0x0904, 0x2df1, 0x2009, 0x0020, 0x2061, 0xadd1, 0x6224, 0x6328,
+ 0x642c, 0x6530, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000,
+ 0xa5a9, 0x0000, 0x080c, 0x3c46, 0x701b, 0x2eb7, 0x0005, 0x6834,
+ 0xa084, 0x00ff, 0xa096, 0x0002, 0x0120, 0xa096, 0x000a, 0x1904,
+ 0x2df1, 0x08c0, 0x7010, 0x2068, 0x6838, 0xc0fd, 0x683a, 0x080c,
+ 0x4b7c, 0x1128, 0x7007, 0x0003, 0x701b, 0x2ed1, 0x0005, 0x080c,
+ 0x51df, 0x0126, 0x2091, 0x8000, 0x20a9, 0x0005, 0x2099, 0xad88,
+ 0x530a, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
+ 0x0000, 0xad80, 0x000d, 0x2009, 0x0020, 0x012e, 0x0804, 0x3c49,
+ 0x61a8, 0x7824, 0x60aa, 0x0804, 0x2dcc, 0x2091, 0x8000, 0x7823,
+ 0x4000, 0x7827, 0x4953, 0x782b, 0x5020, 0x782f, 0x2020, 0x2009,
+ 0x017f, 0x2104, 0x7832, 0x3f00, 0x7836, 0x2061, 0x0100, 0x6200,
+ 0x2061, 0x0200, 0x603c, 0x8007, 0xa205, 0x783a, 0x2009, 0x04fd,
+ 0x2104, 0x783e, 0x781b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
+ 0x2071, 0x0010, 0x20c1, 0x00f0, 0x0804, 0x0427, 0x81ff, 0x1904,
+ 0x2df1, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x1904,
+ 0x2df4, 0x7e38, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0210, 0x0804,
+ 0x2df4, 0x7c28, 0x7d2c, 0x080c, 0x4e96, 0xd28c, 0x1118, 0x080c,
+ 0x4e41, 0x0010, 0x080c, 0x4e6f, 0x1518, 0x2061, 0xb400, 0x0126,
+ 0x2091, 0x8000, 0x6000, 0xa086, 0x0000, 0x0148, 0x6010, 0xa06d,
+ 0x0130, 0x683c, 0xa406, 0x1118, 0x6840, 0xa506, 0x0150, 0x012e,
+ 0xace0, 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1a04, 0x2df1,
+ 0x0c30, 0x080c, 0x929c, 0x012e, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+ 0xa00e, 0x2001, 0x0005, 0x080c, 0x51df, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x9803, 0x080c, 0x510c, 0x012e, 0x0804, 0x2dcc, 0x81ff,
+ 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96,
+ 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0904, 0x2df1, 0x0804, 0x2dcc,
+ 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+ 0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0005, 0x080c, 0x4ebd, 0x0904,
+ 0x2df1, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x8003, 0x800b,
+ 0x810b, 0xa108, 0x080c, 0x6519, 0x0804, 0x2dcc, 0x0126, 0x2091,
+ 0x8000, 0x81ff, 0x0118, 0x2009, 0x0001, 0x0448, 0x2029, 0x00ff,
+ 0x644c, 0x2400, 0xa506, 0x01f0, 0x2508, 0x080c, 0x4cdc, 0x11d0,
+ 0x080c, 0x4f0d, 0x1128, 0x2009, 0x0002, 0x62b0, 0x2518, 0x00b8,
+ 0x2019, 0x0004, 0x080c, 0x4ebd, 0x1118, 0x2009, 0x0006, 0x0078,
+ 0x7824, 0xa08a, 0x1000, 0x1270, 0x8003, 0x800b, 0x810b, 0xa108,
+ 0x080c, 0x6519, 0x8529, 0x1ae8, 0x012e, 0x0804, 0x2dcc, 0x012e,
+ 0x0804, 0x2df1, 0x012e, 0x0804, 0x2df4, 0x080c, 0x3c1a, 0x0904,
+ 0x2df4, 0x080c, 0x4dfc, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff,
+ 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4ded,
+ 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c,
+ 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e71, 0x0904, 0x2df1, 0x080c,
+ 0x4bc0, 0x080c, 0x4e3a, 0x080c, 0x4e96, 0x0804, 0x2dcc, 0x080c,
+ 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x62a0,
+ 0x2019, 0x0005, 0x00c6, 0x080c, 0x4ecf, 0x2061, 0x0000, 0x080c,
+ 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2009, 0x0000,
+ 0x080c, 0xa712, 0x007e, 0x00ce, 0x080c, 0x4e96, 0x0804, 0x2dcc,
+ 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4e96, 0x2208, 0x0804,
+ 0x2dcc, 0x0156, 0x00d6, 0x00e6, 0x2069, 0xae13, 0x6810, 0x6914,
+ 0xa10a, 0x1210, 0x2009, 0x0000, 0x6816, 0x2011, 0x0000, 0x2019,
+ 0x0000, 0x20a9, 0x007e, 0x2069, 0xae34, 0x2d04, 0xa075, 0x0130,
+ 0x704c, 0x0071, 0xa210, 0x7080, 0x0059, 0xa318, 0x8d68, 0x1f04,
+ 0x3035, 0x2300, 0xa218, 0x00ee, 0x00de, 0x015e, 0x0804, 0x2dcc,
+ 0x00f6, 0x0016, 0xa07d, 0x0140, 0x2001, 0x0000, 0x8000, 0x2f0c,
+ 0x81ff, 0x0110, 0x2178, 0x0cd0, 0x001e, 0x00fe, 0x0005, 0x2069,
+ 0xae13, 0x6910, 0x62ac, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1,
+ 0x614c, 0xa190, 0x2be6, 0x2215, 0xa294, 0x00ff, 0x636c, 0x83ff,
+ 0x0108, 0x6270, 0x67d0, 0xd79c, 0x0118, 0x2031, 0x0001, 0x0090,
+ 0xd7ac, 0x0118, 0x2031, 0x0003, 0x0068, 0xd7a4, 0x0118, 0x2031,
+ 0x0002, 0x0040, 0x080c, 0x574f, 0x1118, 0x2031, 0x0004, 0x0010,
+ 0x2031, 0x0000, 0x7e3a, 0x7f3e, 0x0804, 0x2dcc, 0x613c, 0x6240,
+ 0x2019, 0xafa3, 0x231c, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+ 0x6134, 0xa006, 0x2010, 0x2018, 0x012e, 0x0804, 0x2dcc, 0x080c,
+ 0x3c2a, 0x0904, 0x2df4, 0x6244, 0x6338, 0x0804, 0x2dcc, 0x613c,
+ 0x6240, 0x7824, 0x603e, 0x7b28, 0x6342, 0x2069, 0xad51, 0x831f,
+ 0xa305, 0x6816, 0x782c, 0x2069, 0xafa3, 0x2d1c, 0x206a, 0x0804,
+ 0x2dcc, 0x0126, 0x2091, 0x8000, 0x7824, 0x6036, 0x012e, 0x0804,
+ 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x7828, 0xa00d, 0x0904,
+ 0x2df4, 0x782c, 0xa005, 0x0904, 0x2df4, 0x6244, 0x6146, 0x6338,
+ 0x603a, 0x0804, 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003,
+ 0x1904, 0x2df1, 0x00c6, 0x2061, 0x0100, 0x7924, 0x810f, 0xa18c,
+ 0x00ff, 0xa196, 0x00ff, 0x1130, 0x2001, 0xad14, 0x2004, 0xa085,
+ 0xff00, 0x0078, 0xa182, 0x007f, 0x16a0, 0xa188, 0x2be6, 0x210d,
+ 0xa18c, 0x00ff, 0x2001, 0xad14, 0x2004, 0xa116, 0x0550, 0x810f,
+ 0xa105, 0x0126, 0x2091, 0x8000, 0x0006, 0x080c, 0x8022, 0x000e,
+ 0x01e0, 0x601a, 0x600b, 0xbc09, 0x601f, 0x0001, 0x080c, 0x3c05,
+ 0x01d8, 0x6837, 0x0000, 0x7007, 0x0003, 0x6833, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x701b, 0x3173, 0x2d00, 0x6012, 0x2009, 0x0032,
+ 0x080c, 0x80a7, 0x012e, 0x00ce, 0x0005, 0x012e, 0x00ce, 0x0804,
+ 0x2df1, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x8078, 0x0cb0, 0x2001,
+ 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00c6, 0x2061,
+ 0x0100, 0x7924, 0x810f, 0xa18c, 0x00ff, 0xa196, 0x00ff, 0x1130,
+ 0x2001, 0xad14, 0x2004, 0xa085, 0xff00, 0x0078, 0xa182, 0x007f,
+ 0x16a0, 0xa188, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x2001, 0xad14,
+ 0x2004, 0xa116, 0x0550, 0x810f, 0xa105, 0x0126, 0x2091, 0x8000,
+ 0x0006, 0x080c, 0x8022, 0x000e, 0x01e0, 0x601a, 0x600b, 0xbc05,
+ 0x601f, 0x0001, 0x080c, 0x3c05, 0x01d8, 0x6837, 0x0000, 0x7007,
+ 0x0003, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x701b, 0x3173,
+ 0x2d00, 0x6012, 0x2009, 0x0032, 0x080c, 0x80a7, 0x012e, 0x00ce,
+ 0x0005, 0x012e, 0x00ce, 0x0804, 0x2df1, 0x00ce, 0x0804, 0x2df4,
+ 0x080c, 0x8078, 0x0cb0, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1,
+ 0x0804, 0x2dcc, 0x2061, 0xb048, 0x0126, 0x2091, 0x8000, 0x6000,
+ 0xd084, 0x0128, 0x6104, 0x6208, 0x012e, 0x0804, 0x2dcc, 0x012e,
+ 0x0804, 0x2df4, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0904,
+ 0x2df1, 0x0126, 0x2091, 0x8000, 0x6244, 0x6064, 0xa202, 0x0248,
+ 0xa085, 0x0001, 0x080c, 0x26c0, 0x080c, 0x436e, 0x012e, 0x0804,
+ 0x2dcc, 0x012e, 0x0804, 0x2df4, 0x0126, 0x2091, 0x8000, 0x7824,
+ 0xa084, 0x0007, 0x0002, 0x31b6, 0x31bf, 0x31c6, 0x31b3, 0x31b3,
+ 0x31b3, 0x31b3, 0x31b3, 0x012e, 0x0804, 0x2df4, 0x2009, 0x0114,
+ 0x2104, 0xa085, 0x0800, 0x200a, 0x080c, 0x332f, 0x0070, 0x2009,
+ 0x010b, 0x200b, 0x0010, 0x080c, 0x332f, 0x0038, 0x81ff, 0x0128,
+ 0x012e, 0x2021, 0x400b, 0x0804, 0x2dce, 0x0086, 0x0096, 0x00a6,
+ 0x00b6, 0x00c6, 0x00d6, 0x00e6, 0x00f6, 0x2009, 0x0101, 0x210c,
+ 0x0016, 0x2001, 0x0138, 0x200c, 0x2003, 0x0001, 0x0016, 0x2001,
+ 0x007a, 0x2034, 0x2001, 0x007b, 0x202c, 0xa006, 0x2048, 0x2050,
+ 0x2058, 0x080c, 0x3570, 0x080c, 0x34da, 0xa03e, 0x2720, 0x00f6,
+ 0x00e6, 0x00c6, 0x2d60, 0x2071, 0xb01e, 0x2079, 0x0020, 0x00d6,
+ 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0140, 0x2001, 0x007d, 0x2004,
+ 0x783e, 0x2001, 0x007c, 0x2004, 0x783a, 0x00de, 0x2011, 0x0001,
+ 0x080c, 0x3486, 0x080c, 0x3486, 0x00ce, 0x00ee, 0x00fe, 0x080c,
+ 0x33d5, 0x080c, 0x34ae, 0x080c, 0x342b, 0x080c, 0x3394, 0x080c,
+ 0x33c5, 0x00f6, 0x2079, 0x0100, 0x7824, 0xd094, 0x0530, 0x7814,
+ 0xa084, 0x0184, 0xa085, 0x0010, 0x7816, 0x2079, 0x0140, 0x080c,
+ 0x330d, 0x1110, 0x00fe, 0x0430, 0x7804, 0xd0dc, 0x0dc0, 0x2079,
+ 0x0100, 0x7827, 0x0086, 0x7814, 0xa084, 0x0184, 0xa085, 0x0032,
+ 0x7816, 0x080c, 0x330d, 0x1110, 0x00fe, 0x00a0, 0x7824, 0xd0bc,
+ 0x0dc0, 0x7827, 0x0080, 0xa026, 0x7c16, 0x7824, 0xd0ac, 0x0130,
+ 0x8b58, 0x080c, 0x3317, 0x00fe, 0x0804, 0x32d7, 0x00fe, 0x080c,
+ 0x330d, 0x1150, 0x8948, 0x2001, 0x007a, 0x2602, 0x2001, 0x007b,
+ 0x2502, 0x080c, 0x3317, 0x0088, 0x87ff, 0x0140, 0x2001, 0x0201,
+ 0x2004, 0xa005, 0x1904, 0x3211, 0x8739, 0x0038, 0x2001, 0xaffd,
+ 0x2004, 0xa086, 0x0000, 0x1904, 0x3211, 0x2001, 0x0033, 0x2003,
+ 0x00f6, 0x8631, 0x1208, 0x8529, 0x2500, 0xa605, 0x0904, 0x32d7,
+ 0x7824, 0xd0bc, 0x0128, 0x2900, 0xaa05, 0xab05, 0x1904, 0x32d7,
+ 0x6033, 0x000d, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824, 0xd0ac,
+ 0x1148, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+ 0x0009, 0x0040, 0x6027, 0x0001, 0x2001, 0x0075, 0x2004, 0xa005,
+ 0x0108, 0x6026, 0x2c00, 0x601a, 0x20e1, 0x9040, 0x2d00, 0x681a,
+ 0x6833, 0x000d, 0x7824, 0xd0a4, 0x1180, 0x6827, 0x0000, 0x00c6,
+ 0x20a9, 0x0004, 0x2061, 0x0020, 0x6003, 0x0008, 0x2001, 0x0203,
+ 0x2004, 0x1f04, 0x32ac, 0x00ce, 0x0040, 0x6827, 0x0001, 0x2001,
+ 0x0074, 0x2004, 0xa005, 0x0108, 0x6826, 0x00f6, 0x00c6, 0x2079,
+ 0x0100, 0x2061, 0x0020, 0x7827, 0x0002, 0x2001, 0x0072, 0x2004,
+ 0xa084, 0xfff8, 0x601a, 0x0006, 0x2001, 0x0073, 0x2004, 0x601e,
+ 0x78c6, 0x000e, 0x78ca, 0x00ce, 0x00fe, 0x0804, 0x31ef, 0x2061,
+ 0x0100, 0x6027, 0x0002, 0x001e, 0x61e2, 0x001e, 0x6106, 0x7824,
+ 0xa084, 0x0003, 0xa086, 0x0002, 0x0188, 0x20e1, 0x9028, 0x6050,
+ 0xa084, 0xf7ef, 0x6052, 0x602f, 0x0000, 0x602c, 0xc0ac, 0x602e,
+ 0x604b, 0xf7f7, 0x6043, 0x0090, 0x6043, 0x0010, 0x2908, 0x2a10,
+ 0x2b18, 0x2b00, 0xaa05, 0xa905, 0x00fe, 0x00ee, 0x00de, 0x00ce,
+ 0x00be, 0x00ae, 0x009e, 0x008e, 0x1118, 0x012e, 0x0804, 0x2dcc,
+ 0x012e, 0x2021, 0x400c, 0x0804, 0x2dce, 0xa085, 0x0001, 0x1d04,
+ 0x3316, 0x2091, 0x6000, 0x8420, 0xa486, 0x0064, 0x0005, 0x2001,
+ 0x0105, 0x2003, 0x0010, 0x2001, 0x0030, 0x2003, 0x0004, 0x2001,
+ 0x0020, 0x2003, 0x0004, 0x2001, 0xaffd, 0x2003, 0x0000, 0x2001,
+ 0xb01e, 0x2003, 0x0000, 0x20e1, 0xf000, 0xa026, 0x0005, 0x00f6,
+ 0x2079, 0x0100, 0x2001, 0xad14, 0x200c, 0x7932, 0x7936, 0x080c,
+ 0x26a0, 0x7850, 0xa084, 0x0980, 0xa085, 0x0030, 0x7852, 0x2019,
+ 0x01f4, 0x8319, 0x1df0, 0xa084, 0x0980, 0x7852, 0x782c, 0xc0ad,
+ 0x782e, 0x20a9, 0x0046, 0x1d04, 0x334b, 0x2091, 0x6000, 0x1f04,
+ 0x334b, 0x7850, 0xa085, 0x0400, 0x7852, 0x2001, 0x0009, 0x2004,
+ 0xa084, 0x0003, 0xa086, 0x0001, 0x1118, 0x782c, 0xc0ac, 0x782e,
+ 0x784b, 0xf7f7, 0x7843, 0x0090, 0x7843, 0x0010, 0x20a9, 0x000e,
+ 0xe000, 0x1f04, 0x3368, 0x7850, 0xa085, 0x1400, 0x7852, 0x2019,
+ 0x61a8, 0x7854, 0xe000, 0xe000, 0xd08c, 0x1110, 0x8319, 0x1dc8,
+ 0x7827, 0x0048, 0x7850, 0xa085, 0x0400, 0x7852, 0x7843, 0x0040,
+ 0x2019, 0x01f4, 0xe000, 0xe000, 0x8319, 0x1de0, 0x2001, 0x0140,
+ 0x2003, 0x0100, 0x7827, 0x0020, 0x7843, 0x0000, 0x2003, 0x0000,
+ 0x7827, 0x0048, 0x00fe, 0x0005, 0x7824, 0xd0ac, 0x11c8, 0x00f6,
+ 0x00e6, 0x2071, 0xaffd, 0x2079, 0x0030, 0x2001, 0x0201, 0x2004,
+ 0xa005, 0x0160, 0x7000, 0xa086, 0x0000, 0x1140, 0x0051, 0xd0bc,
+ 0x0108, 0x8738, 0x7003, 0x0003, 0x7803, 0x0019, 0x00ee, 0x00fe,
+ 0x0005, 0x780c, 0xa08c, 0x0070, 0x0178, 0x2009, 0x007a, 0x260a,
+ 0x2009, 0x007b, 0x250a, 0xd0b4, 0x0108, 0x8a50, 0xd0ac, 0x0108,
+ 0x8948, 0xd0a4, 0x0108, 0x8b58, 0x0005, 0x00f6, 0x2079, 0x0200,
+ 0x781c, 0xd084, 0x0140, 0x20e1, 0x0007, 0x20e1, 0x2000, 0x2001,
+ 0x020a, 0x2004, 0x0ca8, 0x00fe, 0x0005, 0x00e6, 0x2071, 0x0100,
+ 0x2009, 0xad14, 0x210c, 0x716e, 0x7063, 0x0100, 0x7166, 0x719e,
+ 0x706b, 0x0000, 0x7073, 0x0809, 0x7077, 0x0008, 0x7078, 0xa080,
+ 0x0100, 0x707a, 0x7080, 0x8000, 0x7082, 0x7087, 0xaaaa, 0xa006,
+ 0x708a, 0x708e, 0x707e, 0x70d6, 0x70ab, 0x0036, 0x70af, 0x95d5,
+ 0x7027, 0x0080, 0x7014, 0xa084, 0x0184, 0xa085, 0x0032, 0x7016,
+ 0x080c, 0x34ae, 0x080c, 0x330d, 0x1110, 0x8421, 0x0028, 0x7024,
+ 0xd0bc, 0x0db0, 0x7027, 0x0080, 0x00f6, 0x00e6, 0x2071, 0xaffd,
+ 0x2079, 0x0030, 0x00d6, 0x2069, 0x0000, 0x6824, 0xd0b4, 0x0120,
+ 0x683c, 0x783e, 0x6838, 0x783a, 0x00de, 0x2011, 0x0011, 0x080c,
+ 0x3486, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ee, 0x00fe, 0x7017,
+ 0x0000, 0x00ee, 0x0005, 0x00f6, 0x00e6, 0x2071, 0xaffd, 0x2079,
+ 0x0030, 0x7904, 0xd1fc, 0x0904, 0x3483, 0x7803, 0x0002, 0xa026,
+ 0xd19c, 0x1904, 0x347f, 0x7000, 0x0002, 0x3483, 0x3441, 0x3465,
+ 0x347f, 0xd1bc, 0x1150, 0xd1dc, 0x1150, 0x8001, 0x7002, 0x2011,
+ 0x0001, 0x04e1, 0x05c0, 0x04d1, 0x04b0, 0x780f, 0x0000, 0x7820,
+ 0x7924, 0x7803, 0x0004, 0x7822, 0x7926, 0x2001, 0x0201, 0x200c,
+ 0x81ff, 0x0de8, 0x080c, 0x33b1, 0x2009, 0x0001, 0x7808, 0xd0ec,
+ 0x0110, 0x2009, 0x0011, 0x7902, 0x00f0, 0x8001, 0x7002, 0xa184,
+ 0x0880, 0x1138, 0x7804, 0xd0fc, 0x1940, 0x2011, 0x0001, 0x00b1,
+ 0x0090, 0x6030, 0xa092, 0x0004, 0xa086, 0x0009, 0x1120, 0x6000,
+ 0x601a, 0x2011, 0x0025, 0x6232, 0xd1dc, 0x1988, 0x0870, 0x7803,
+ 0x0004, 0x7003, 0x0000, 0x00ee, 0x00fe, 0x0005, 0x6024, 0xa005,
+ 0x0520, 0x8001, 0x6026, 0x6018, 0x6130, 0xa140, 0x2804, 0x7832,
+ 0x8840, 0x2804, 0x7836, 0x8840, 0x2804, 0x7822, 0x8840, 0x2804,
+ 0x7826, 0x8840, 0x7a02, 0x7000, 0x8000, 0x7002, 0x6018, 0xa802,
+ 0xa08a, 0x0029, 0x1138, 0x6018, 0xa080, 0x0001, 0x2004, 0x601a,
+ 0x2001, 0x000d, 0x6032, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6,
+ 0x00c6, 0x2071, 0xb01e, 0x2079, 0x0020, 0x7904, 0xd1fc, 0x01f0,
+ 0x7803, 0x0002, 0x2d60, 0xa026, 0x7000, 0x0002, 0x34d6, 0x34c1,
+ 0x34cd, 0x8001, 0x7002, 0xd19c, 0x1188, 0x2011, 0x0001, 0x080c,
+ 0x3486, 0x0160, 0x080c, 0x3486, 0x0048, 0x8001, 0x7002, 0x7804,
+ 0xd0fc, 0x1d30, 0x2011, 0x0001, 0x080c, 0x3486, 0x00ce, 0x00ee,
+ 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x2061, 0x0200, 0x601b,
+ 0x0004, 0x2061, 0x0100, 0x60cf, 0x0400, 0x6004, 0xc0ac, 0xa085,
+ 0x0200, 0x6006, 0x2001, 0x0074, 0x2004, 0xa005, 0x01f8, 0x2038,
+ 0x2001, 0x0076, 0x2024, 0x2001, 0x0077, 0x201c, 0x080c, 0x3c05,
+ 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+ 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+ 0x000d, 0x04a1, 0x1d90, 0x2d00, 0x681a, 0x0088, 0x080c, 0x3c05,
+ 0x6833, 0x000d, 0x2070, 0x6827, 0x0001, 0x2d00, 0x681a, 0x2001,
+ 0x0076, 0x2004, 0x2072, 0x2001, 0x0077, 0x2004, 0x7006, 0x2061,
+ 0x0020, 0x2079, 0x0100, 0x6013, 0x0400, 0x20e1, 0x9040, 0x2001,
+ 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x601a, 0x0006, 0x2001,
+ 0x0073, 0x2004, 0x700e, 0x601e, 0x78c6, 0x000e, 0x78ca, 0xa006,
+ 0x603a, 0x603e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00e6, 0x2071,
+ 0x0010, 0x20a0, 0x2099, 0x0014, 0x7003, 0x0026, 0x7432, 0x7336,
+ 0xa006, 0x703a, 0x703e, 0x810b, 0x810b, 0x21a8, 0x810b, 0x7122,
+ 0x7003, 0x0041, 0x7004, 0xd0fc, 0x0de8, 0x7003, 0x0002, 0x7003,
+ 0x0040, 0x53a5, 0x7430, 0x7334, 0x87ff, 0x0180, 0x00c6, 0x00d6,
+ 0x2d60, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x6018, 0x2070, 0x2d00,
+ 0x7006, 0x601a, 0x00de, 0x00ce, 0xa085, 0x0001, 0x00ee, 0x0005,
+ 0x00e6, 0x2001, 0x0075, 0x2004, 0xa005, 0x0508, 0x2038, 0x2001,
+ 0x0078, 0x2024, 0x2001, 0x0079, 0x201c, 0x080c, 0x3c05, 0x2d60,
+ 0x6833, 0x000d, 0x6f26, 0x2d00, 0x681a, 0xa78a, 0x0007, 0x0220,
+ 0x2138, 0x2009, 0x0007, 0x0010, 0x2708, 0xa03e, 0x6818, 0xa080,
+ 0x000d, 0x080c, 0x353e, 0x1d88, 0x2d00, 0x681a, 0x00e0, 0x080c,
+ 0x3c05, 0x2d60, 0x6033, 0x000d, 0x2070, 0x6027, 0x0001, 0x2c00,
+ 0x601a, 0x2001, 0x0078, 0x2004, 0x2072, 0x2001, 0x0079, 0x2004,
+ 0x7006, 0x2001, 0x0072, 0x2004, 0xa084, 0xfff8, 0x700a, 0x2001,
+ 0x0073, 0x2004, 0x700e, 0x2001, 0x0030, 0x2003, 0x0004, 0x7824,
+ 0xd0ac, 0x1178, 0x2001, 0x0101, 0x200c, 0xc1ed, 0x2102, 0x6027,
+ 0x0000, 0x2001, 0xaffd, 0x2003, 0x0003, 0x2001, 0x0030, 0x2003,
+ 0x0009, 0x00ee, 0x0005, 0x0804, 0x2dcc, 0x0126, 0x2091, 0x8000,
+ 0x20a9, 0x0011, 0x2001, 0xad40, 0x20a0, 0xa006, 0x40a4, 0x012e,
+ 0x0804, 0x2dcc, 0x7d38, 0x7c3c, 0x0804, 0x2e73, 0x080c, 0x3c05,
+ 0x0904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c, 0x491f, 0x2009,
+ 0x001c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b,
+ 0x35f2, 0x0005, 0xade8, 0x000d, 0x6800, 0xa005, 0x0904, 0x2df4,
+ 0x6804, 0xd0ac, 0x0118, 0xd0a4, 0x0904, 0x2df4, 0xd094, 0x00c6,
+ 0x2061, 0x0100, 0x6104, 0x0138, 0x6200, 0xa292, 0x0005, 0x0218,
+ 0xa18c, 0xffdf, 0x0010, 0xa18d, 0x0020, 0x6106, 0x00ce, 0xd08c,
+ 0x00c6, 0x2061, 0x0100, 0x6104, 0x0118, 0xa18d, 0x0010, 0x0010,
+ 0xa18c, 0xffef, 0x6106, 0x00ce, 0x2009, 0x0100, 0x210c, 0xa18a,
+ 0x0002, 0x0268, 0xd084, 0x0158, 0x6a28, 0xa28a, 0x007f, 0x1a04,
+ 0x2df4, 0xa288, 0x2be6, 0x210d, 0xa18c, 0x00ff, 0x6156, 0xd0dc,
+ 0x0130, 0x6828, 0xa08a, 0x007f, 0x1a04, 0x2df4, 0x604e, 0x6808,
+ 0xa08a, 0x0100, 0x0a04, 0x2df4, 0xa08a, 0x0841, 0x1a04, 0x2df4,
+ 0xa084, 0x0007, 0x1904, 0x2df4, 0x680c, 0xa005, 0x0904, 0x2df4,
+ 0x6810, 0xa005, 0x0904, 0x2df4, 0x6848, 0x6940, 0xa10a, 0x1a04,
+ 0x2df4, 0x8001, 0x0904, 0x2df4, 0x684c, 0x6944, 0xa10a, 0x1a04,
+ 0x2df4, 0x8001, 0x0904, 0x2df4, 0x6804, 0xd0fc, 0x0560, 0x080c,
+ 0x3c05, 0x0904, 0x2df1, 0x2009, 0x0014, 0x7a2c, 0x7b28, 0x7c3c,
+ 0x7d38, 0xa290, 0x0038, 0xa399, 0x0000, 0x080c, 0x3c46, 0x701b,
+ 0x3672, 0x0005, 0xade8, 0x000d, 0x20a9, 0x0014, 0x2d98, 0x2069,
+ 0xad6d, 0x2da0, 0x53a3, 0x7010, 0xa0e8, 0x000d, 0x2001, 0xad71,
+ 0x200c, 0xd1e4, 0x0140, 0x00c6, 0x2061, 0x0100, 0x6004, 0xa085,
+ 0x0b00, 0x6006, 0x00ce, 0x20a9, 0x001c, 0x2d98, 0x2069, 0xad51,
+ 0x2da0, 0x53a3, 0x6814, 0xa08c, 0x00ff, 0x613e, 0x8007, 0xa084,
+ 0x00ff, 0x6042, 0x080c, 0x5a1c, 0x080c, 0x5070, 0x080c, 0x50d9,
+ 0x6000, 0xa086, 0x0000, 0x1904, 0x3755, 0x6808, 0x602a, 0x080c,
+ 0x22f8, 0x0006, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x000e,
+ 0x0268, 0x2009, 0x0170, 0x200b, 0x0080, 0xe000, 0xe000, 0x200b,
+ 0x0000, 0x0036, 0x6b08, 0x080c, 0x26fb, 0x003e, 0x6818, 0x691c,
+ 0x6a20, 0x6b24, 0x8007, 0x810f, 0x8217, 0x831f, 0x6016, 0x611a,
+ 0x621e, 0x6322, 0x6c04, 0xd4f4, 0x0148, 0x6830, 0x6934, 0x6a38,
+ 0x6b3c, 0x8007, 0x810f, 0x8217, 0x831f, 0x0010, 0xa084, 0xf0ff,
+ 0x6006, 0x610a, 0x620e, 0x6312, 0x8007, 0x810f, 0x8217, 0x831f,
+ 0x20a9, 0x0004, 0x20a1, 0xafad, 0x40a1, 0x080c, 0x659c, 0x6904,
+ 0xd1fc, 0x0520, 0x00c6, 0x2009, 0x0000, 0x20a9, 0x0001, 0x6b70,
+ 0xd384, 0x01c8, 0x0020, 0x839d, 0x12b0, 0x3508, 0x8109, 0x080c,
+ 0x5fa9, 0x6878, 0x6016, 0x6874, 0x2008, 0xa084, 0xff00, 0x8007,
+ 0x600a, 0xa184, 0x00ff, 0x6006, 0x8108, 0x1118, 0x6003, 0x0003,
+ 0x0010, 0x6003, 0x0001, 0x1f04, 0x36f3, 0x00ce, 0x2069, 0xad51,
+ 0x2001, 0xaf9d, 0x6a80, 0xa294, 0x0030, 0xa28e, 0x0000, 0x0170,
+ 0xa28e, 0x0010, 0x0118, 0xa28e, 0x0020, 0x0140, 0x2003, 0xaaaa,
+ 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x0008, 0x2102, 0x00c6,
+ 0x2061, 0x0100, 0x602f, 0x0040, 0x602f, 0x0000, 0x00ce, 0x080c,
+ 0x574f, 0x0128, 0x080c, 0x3e5f, 0x0110, 0x080c, 0x26c0, 0x60c4,
+ 0xa005, 0x01b0, 0x6003, 0x0001, 0x2009, 0x373f, 0x00c0, 0x080c,
+ 0x574f, 0x1158, 0x2011, 0x566e, 0x080c, 0x650d, 0x2001, 0xaf9e,
+ 0x2003, 0x0000, 0x080c, 0x569a, 0x0040, 0x080c, 0x485e, 0x0028,
+ 0x6003, 0x0004, 0x2009, 0x3755, 0x0010, 0x0804, 0x2dcc, 0x2001,
+ 0x0100, 0x2004, 0xa082, 0x0005, 0x0258, 0x2001, 0x0170, 0x2004,
+ 0xa084, 0x00ff, 0xa086, 0x004c, 0x1118, 0x2091, 0x309d, 0x0817,
+ 0x2091, 0x301d, 0x0817, 0x6000, 0xa086, 0x0000, 0x0904, 0x2df1,
+ 0x2069, 0xad51, 0x7830, 0x6842, 0x7834, 0x6846, 0x6804, 0xd0fc,
+ 0x0118, 0x2009, 0x0030, 0x0010, 0x2009, 0x001c, 0x2d00, 0x7a2c,
+ 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0xa006, 0x080c, 0x26c0,
+ 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x1178, 0x2001, 0xaf9e,
+ 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085, 0x0001,
+ 0x080c, 0x5793, 0x080c, 0x569a, 0x0020, 0x080c, 0x491f, 0x080c,
+ 0x485e, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f,
+ 0x1110, 0x0804, 0x2df1, 0x6184, 0x81ff, 0x0198, 0x703f, 0x0000,
+ 0x2001, 0xb3c0, 0x2009, 0x0040, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x3c49, 0x701b, 0x2dca, 0x012e,
+ 0x0005, 0x703f, 0x0001, 0x00d6, 0x2069, 0xb3c0, 0x20a9, 0x0040,
+ 0x20a1, 0xb3c0, 0x2019, 0xffff, 0x43a4, 0x654c, 0xa588, 0x2be6,
+ 0x210d, 0xa18c, 0x00ff, 0x216a, 0xa00e, 0x2011, 0x0002, 0x2100,
+ 0xa506, 0x01a8, 0x080c, 0x4cdc, 0x1190, 0x6014, 0x821c, 0x0238,
+ 0xa398, 0xb3c0, 0xa085, 0xff00, 0x8007, 0x201a, 0x0038, 0xa398,
+ 0xb3c0, 0x2324, 0xa4a4, 0xff00, 0xa405, 0x201a, 0x8210, 0x8108,
+ 0xa182, 0x0080, 0x1208, 0x0c18, 0x8201, 0x8007, 0x2d0c, 0xa105,
+ 0x206a, 0x00de, 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb3c0,
+ 0x080c, 0x48be, 0x0804, 0x37b0, 0x080c, 0x3c2a, 0x0904, 0x2df4,
+ 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0b4, 0x01f0, 0x6000, 0xd08c,
+ 0x11d8, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x11a8, 0x6837,
+ 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x970b, 0x1120, 0x2009,
+ 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3830, 0x0005,
+ 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x20a9, 0x002b, 0x2c98, 0xade8,
+ 0x0002, 0x2da0, 0x53a3, 0x20a9, 0x0004, 0xac80, 0x0006, 0x2098,
+ 0xad80, 0x0006, 0x20a0, 0x080c, 0x48be, 0x20a9, 0x0004, 0xac80,
+ 0x000a, 0x2098, 0xad80, 0x000a, 0x20a0, 0x080c, 0x48be, 0x2d00,
+ 0x2009, 0x002b, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+ 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4, 0x080c,
+ 0x4eab, 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x7828, 0xa08a,
+ 0x1000, 0x1a04, 0x2df4, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x080c,
+ 0x4f0d, 0x0904, 0x2df1, 0x2019, 0x0004, 0x080c, 0x4ebd, 0x7924,
+ 0x810f, 0x7a28, 0x0011, 0x0804, 0x2dcc, 0xa186, 0x00ff, 0x0110,
+ 0x0071, 0x0060, 0x2029, 0x007e, 0x2061, 0xad00, 0x644c, 0x2400,
+ 0xa506, 0x0110, 0x2508, 0x0019, 0x8529, 0x1ec8, 0x0005, 0x080c,
+ 0x4cdc, 0x1138, 0x2200, 0x8003, 0x800b, 0x810b, 0xa108, 0x080c,
+ 0x6519, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904,
+ 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4eb4, 0x0804,
+ 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c1a, 0x0904, 0x2df4,
+ 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c, 0x4ea2, 0x0804, 0x2dcc,
+ 0x6100, 0x0804, 0x2dcc, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x2001,
+ 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x00d6, 0xace8,
+ 0x000a, 0x7924, 0xd184, 0x0110, 0xace8, 0x0006, 0x680c, 0x8007,
+ 0x783e, 0x6808, 0x8007, 0x783a, 0x6b04, 0x831f, 0x6a00, 0x8217,
+ 0x00de, 0x6100, 0xa18c, 0x0200, 0x0804, 0x2dcc, 0x7824, 0xa09c,
+ 0x00ff, 0xa39a, 0x0003, 0x1a04, 0x2df1, 0x624c, 0xa294, 0x00ff,
+ 0xa084, 0xff00, 0x8007, 0xa206, 0x1150, 0x2001, 0xad40, 0x2009,
+ 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x81ff,
+ 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+ 0x00ce, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a,
+ 0x080c, 0x96b7, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3919,
+ 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0xad80, 0x000e,
+ 0x2009, 0x000c, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49,
+ 0xa006, 0x080c, 0x26c0, 0x7824, 0xa084, 0x00ff, 0xa086, 0x00ff,
+ 0x0118, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x574f, 0x0110, 0x080c,
+ 0x491f, 0x7828, 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x7924, 0xa18c,
+ 0xff00, 0x810f, 0xa186, 0x00ff, 0x0138, 0xa182, 0x007f, 0x1a04,
+ 0x2df4, 0x2100, 0x080c, 0x268a, 0x0026, 0x00c6, 0x0126, 0x2091,
+ 0x8000, 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x080c,
+ 0x574f, 0x1178, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00,
+ 0x2003, 0x0001, 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a,
+ 0x00a0, 0x2061, 0x0100, 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff,
+ 0x810f, 0xa105, 0x604a, 0x6043, 0x0090, 0x6043, 0x0010, 0x2009,
+ 0x002d, 0x2011, 0x4883, 0x080c, 0x6593, 0x7924, 0xa18c, 0xff00,
+ 0x810f, 0x080c, 0x574f, 0x1110, 0x2009, 0x00ff, 0x7a28, 0x080c,
+ 0x387d, 0x012e, 0x00ce, 0x002e, 0x0804, 0x2dcc, 0x7924, 0xa18c,
+ 0xff00, 0x810f, 0x00c6, 0x080c, 0x4c80, 0x2c08, 0x00ce, 0x1904,
+ 0x2df4, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+ 0x2df1, 0x60d0, 0xd0ac, 0x1130, 0xd09c, 0x1120, 0x2009, 0x0005,
+ 0x0804, 0x2df1, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x2df1, 0x7924, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46,
+ 0x701b, 0x39bb, 0x0005, 0x2009, 0x0080, 0x080c, 0x4cdc, 0x1130,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0120, 0x2021, 0x400a,
+ 0x0804, 0x2dce, 0x00d6, 0xade8, 0x000d, 0x6900, 0x6a08, 0x6b0c,
+ 0x6c10, 0x6d14, 0x6e18, 0x6820, 0xa0be, 0x0100, 0x0904, 0x3a32,
+ 0xa0be, 0x0112, 0x0904, 0x3a32, 0xa0be, 0x0113, 0x0904, 0x3a32,
+ 0xa0be, 0x0114, 0x0904, 0x3a32, 0xa0be, 0x0117, 0x0904, 0x3a32,
+ 0xa0be, 0x011a, 0x0904, 0x3a32, 0xa0be, 0x011c, 0x0904, 0x3a32,
+ 0xa0be, 0x0121, 0x05b0, 0xa0be, 0x0131, 0x0598, 0xa0be, 0x0171,
+ 0x05c8, 0xa0be, 0x0173, 0x05b0, 0xa0be, 0x01a1, 0x1120, 0x6830,
+ 0x8007, 0x6832, 0x04a8, 0xa0be, 0x0212, 0x0540, 0xa0be, 0x0213,
+ 0x0528, 0xa0be, 0x0214, 0x01b0, 0xa0be, 0x0217, 0x0168, 0xa0be,
+ 0x021a, 0x1120, 0x6838, 0x8007, 0x683a, 0x00e0, 0xa0be, 0x0300,
+ 0x01c8, 0x00de, 0x0804, 0x2df4, 0xad80, 0x0010, 0x20a9, 0x0007,
+ 0x080c, 0x3a78, 0xad80, 0x000e, 0x20a9, 0x0001, 0x080c, 0x3a78,
+ 0x0048, 0xad80, 0x000c, 0x080c, 0x3a86, 0x0050, 0xad80, 0x000e,
+ 0x080c, 0x3a86, 0xad80, 0x000c, 0x20a9, 0x0001, 0x080c, 0x3a78,
+ 0x00c6, 0x080c, 0x3c05, 0x0568, 0x6838, 0xc0fd, 0x683a, 0x6837,
+ 0x0119, 0x6853, 0x0000, 0x684f, 0x0020, 0x685b, 0x0001, 0x810b,
+ 0x697e, 0x6883, 0x0000, 0x6a86, 0x6b8a, 0x6c8e, 0x6d92, 0x6996,
+ 0x689b, 0x0000, 0x00ce, 0x00de, 0x6837, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c, 0x96d3, 0x1120,
+ 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3a6f,
+ 0x0005, 0x00ce, 0x00de, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6820,
+ 0xa086, 0x8001, 0x1904, 0x2dcc, 0x2009, 0x0004, 0x0804, 0x2df1,
+ 0x0016, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x290a, 0x8108,
+ 0x280a, 0x8108, 0x1f04, 0x3a7a, 0x001e, 0x0005, 0x0016, 0x00a6,
+ 0x00b6, 0x2008, 0x2044, 0x8000, 0x204c, 0x8000, 0x2054, 0x8000,
+ 0x205c, 0x2b0a, 0x8108, 0x2a0a, 0x8108, 0x290a, 0x8108, 0x280a,
+ 0x00be, 0x00ae, 0x001e, 0x0005, 0x81ff, 0x0120, 0x2009, 0x0001,
+ 0x0804, 0x2df1, 0x7924, 0x2140, 0xa18c, 0xff00, 0x810f, 0x60d0,
+ 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182, 0x00ff,
+ 0x1a04, 0x2df4, 0x7a2c, 0x7b28, 0x606c, 0xa306, 0x1140, 0x6070,
+ 0xa24e, 0x0904, 0x2df4, 0xa9cc, 0xff00, 0x0904, 0x2df4, 0x00c6,
+ 0x080c, 0x3b58, 0x2c68, 0x00ce, 0x0538, 0xa0c6, 0x4000, 0x1180,
+ 0x00c6, 0x0006, 0x2d60, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108,
+ 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x000e, 0x00ce, 0x0088,
+ 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008, 0x1118,
+ 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010, 0x2001,
+ 0x4006, 0x2020, 0x0804, 0x2dce, 0x2d00, 0x7022, 0x0016, 0x00b6,
+ 0x00c6, 0x00e6, 0x2c70, 0x080c, 0x8022, 0x05d8, 0x2d00, 0x601a,
+ 0x080c, 0x9956, 0x2e58, 0x00ee, 0x00e6, 0x00c6, 0x080c, 0x3c05,
+ 0x00ce, 0x2b70, 0x1150, 0x080c, 0x8078, 0x00ee, 0x00ce, 0x00be,
+ 0x001e, 0x2009, 0x0002, 0x0804, 0x2df1, 0x6837, 0x0000, 0x683b,
+ 0x0000, 0x2d00, 0x6012, 0x6833, 0x0000, 0x6838, 0xc0fd, 0xd88c,
+ 0x0108, 0xc0f5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9,
+ 0x012e, 0x601f, 0x0001, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001,
+ 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002, 0x080c, 0x80a7, 0xa085,
+ 0x0001, 0x00ee, 0x00ce, 0x00be, 0x001e, 0x1120, 0x2009, 0x0003,
+ 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3b3f, 0x0005, 0x6830,
+ 0xa086, 0x0100, 0x7020, 0x2060, 0x1138, 0x2009, 0x0004, 0x6204,
+ 0xa294, 0x00ff, 0x0804, 0x2df1, 0x2009, 0x0000, 0x080c, 0x4f6e,
+ 0x1108, 0xc185, 0x6000, 0xd0bc, 0x0108, 0xc18d, 0x0804, 0x2dcc,
+ 0x00e6, 0x00d6, 0x2029, 0x0000, 0x2001, 0xad34, 0x2004, 0xd0ac,
+ 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34, 0x0030,
+ 0x2021, 0x0080, 0x20a9, 0x007f, 0x2071, 0xaeb4, 0x2e04, 0xa005,
+ 0x1130, 0x2100, 0xa406, 0x1548, 0x2428, 0xc5fd, 0x0430, 0x2068,
+ 0x6f10, 0x2700, 0xa306, 0x11b0, 0x6e14, 0x2600, 0xa206, 0x1190,
+ 0x2400, 0xa106, 0x1160, 0x2d60, 0xd884, 0x0540, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x1510, 0x2001, 0x4000, 0x0400, 0x2001,
+ 0x4007, 0x00e8, 0x2400, 0xa106, 0x1140, 0x6e14, 0x87ff, 0x1110,
+ 0x86ff, 0x09d0, 0x2001, 0x4008, 0x0090, 0x8420, 0x8e70, 0x1f04,
+ 0x3b6e, 0x85ff, 0x1130, 0x2001, 0x4009, 0x0048, 0x2001, 0x0001,
+ 0x0030, 0x080c, 0x4c80, 0x1dd0, 0x6312, 0x6216, 0xa006, 0xa005,
+ 0x00de, 0x00ee, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x080c, 0x3c05,
+ 0x0904, 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7824,
+ 0xa005, 0x0904, 0x2df4, 0xa096, 0x00ff, 0x0120, 0xa092, 0x0004,
+ 0x1a04, 0x2df4, 0x2010, 0x2d18, 0x080c, 0x2a8c, 0x0904, 0x2df1,
+ 0x7007, 0x0003, 0x701b, 0x3bd5, 0x0005, 0x6830, 0xa086, 0x0100,
+ 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x7924, 0xa18c, 0xff00, 0x810f,
+ 0x60d0, 0xd0ac, 0x1120, 0xa182, 0x0080, 0x0a04, 0x2df4, 0xa182,
+ 0x00ff, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x080c, 0x95c6,
+ 0x1188, 0xa190, 0xae34, 0x2204, 0xa065, 0x0160, 0x080c, 0x493a,
+ 0x2001, 0xad34, 0x2004, 0xd0ac, 0x0110, 0x6017, 0x0000, 0x012e,
+ 0x0804, 0x2dcc, 0x012e, 0x0804, 0x2df1, 0x080c, 0x15d9, 0x0188,
+ 0xa006, 0x6802, 0x7010, 0xa005, 0x1120, 0x2d00, 0x7012, 0x7016,
+ 0x0030, 0x7014, 0x6802, 0x2060, 0x2d00, 0x6006, 0x7016, 0xad80,
+ 0x000d, 0x0005, 0x7924, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+ 0x1130, 0x7e28, 0xa684, 0x3fff, 0xa082, 0x4000, 0x0208, 0xa066,
+ 0x8cff, 0x0005, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0x080c, 0x4cdc,
+ 0x1128, 0xa6b4, 0x00ff, 0xa682, 0x4000, 0x0208, 0xa066, 0x8cff,
+ 0x0005, 0x0016, 0x7110, 0x81ff, 0x0128, 0x2168, 0x6904, 0x080c,
+ 0x15f0, 0x0cc8, 0x7112, 0x7116, 0x001e, 0x0005, 0x2031, 0x0001,
+ 0x0010, 0x2031, 0x0000, 0x2061, 0xadd1, 0x6606, 0x6112, 0x600e,
+ 0x6226, 0x632a, 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007,
+ 0x0002, 0x701b, 0x2dcc, 0x0005, 0x00f6, 0x0126, 0x2091, 0x8000,
+ 0x2079, 0x0000, 0x2001, 0xad8f, 0x2004, 0xa005, 0x1168, 0x0e04,
+ 0x3c74, 0x7818, 0xd084, 0x1140, 0x7a22, 0x7b26, 0x7c2a, 0x781b,
+ 0x0001, 0x2091, 0x4080, 0x0408, 0x0016, 0x00c6, 0x00e6, 0x2071,
+ 0xad81, 0x7138, 0xa182, 0x0010, 0x0218, 0x7030, 0x2060, 0x0078,
+ 0x7030, 0xa0e0, 0x0004, 0xac82, 0xadd1, 0x0210, 0x2061, 0xad91,
+ 0x2c00, 0x7032, 0x81ff, 0x1108, 0x7036, 0x8108, 0x713a, 0x2262,
+ 0x6306, 0x640a, 0x00ee, 0x00ce, 0x001e, 0x012e, 0x00fe, 0x0005,
+ 0x00e6, 0x2071, 0xad81, 0x7038, 0xa005, 0x0570, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x3ccb, 0x00f6, 0x2079, 0x0000, 0x7818, 0xd084,
+ 0x1508, 0x00c6, 0x7034, 0x2060, 0x2c04, 0x7822, 0x6004, 0x7826,
+ 0x6008, 0x782a, 0x781b, 0x0001, 0x2091, 0x4080, 0x7038, 0x8001,
+ 0x703a, 0xa005, 0x1130, 0x7033, 0xad91, 0x7037, 0xad91, 0x00ce,
+ 0x0048, 0xac80, 0x0004, 0xa0fa, 0xadd1, 0x0210, 0x2001, 0xad91,
+ 0x7036, 0x00ce, 0x00fe, 0x012e, 0x00ee, 0x0005, 0x0026, 0x2001,
+ 0xad52, 0x2004, 0xd0c4, 0x0120, 0x2011, 0x8014, 0x080c, 0x3c5c,
+ 0x002e, 0x0005, 0x81ff, 0x1904, 0x2df1, 0x0126, 0x2091, 0x8000,
+ 0x6030, 0xc08d, 0xc085, 0xc0ac, 0x6032, 0x080c, 0x574f, 0x1178,
+ 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001,
+ 0xa085, 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x0010, 0x080c,
+ 0x485e, 0x012e, 0x0804, 0x2dcc, 0x7824, 0x2008, 0xa18c, 0xfffd,
+ 0x1128, 0x61dc, 0xa10d, 0x61de, 0x0804, 0x2dcc, 0x0804, 0x2df4,
+ 0x81ff, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x1904, 0x2df1,
+ 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1904, 0x2df1, 0x080c, 0x3c2a,
+ 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1120,
+ 0x7828, 0xa005, 0x0904, 0x2dcc, 0x00c6, 0x080c, 0x3c05, 0x00ce,
+ 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd,
+ 0x683a, 0x080c, 0x979c, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+ 0x3d3a, 0x0005, 0x6830, 0xa086, 0x0100, 0x0904, 0x2df1, 0x0804,
+ 0x2dcc, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1,
+ 0x7f24, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c05, 0x0904,
+ 0x2df1, 0x2009, 0x0000, 0x2031, 0x0000, 0x7023, 0x0000, 0x702f,
+ 0x0000, 0xad80, 0x0005, 0x7026, 0x20a0, 0x080c, 0x4cdc, 0x1904,
+ 0x3db4, 0x6004, 0xa0c4, 0x00ff, 0xa8c6, 0x0006, 0x0130, 0xa0c4,
+ 0xff00, 0xa8c6, 0x0600, 0x1904, 0x3db4, 0x2001, 0xad52, 0x2004,
+ 0xd0ac, 0x1128, 0x080c, 0x4f6e, 0x1110, 0xd79c, 0x05e8, 0xd794,
+ 0x1110, 0xd784, 0x0158, 0xac80, 0x0006, 0x2098, 0x3400, 0x20a9,
+ 0x0004, 0x53a3, 0x080c, 0x3a86, 0xd794, 0x0148, 0xac80, 0x000a,
+ 0x2098, 0x3400, 0x20a9, 0x0004, 0x53a3, 0x080c, 0x3a86, 0x21a2,
+ 0xd794, 0x01d8, 0xac80, 0x0000, 0x2098, 0x94a0, 0x20a9, 0x0002,
+ 0x53a3, 0xac80, 0x0003, 0x20a6, 0x94a0, 0xac80, 0x0004, 0x2098,
+ 0x3400, 0x20a9, 0x0002, 0x53a3, 0x080c, 0x3a78, 0xac80, 0x0026,
+ 0x2098, 0x20a9, 0x0002, 0x53a3, 0x0008, 0x94a0, 0xd794, 0x0110,
+ 0xa6b0, 0x000b, 0xa6b0, 0x0005, 0x8108, 0x2001, 0xad34, 0x2004,
+ 0xd0ac, 0x0118, 0xa186, 0x0100, 0x0040, 0xd78c, 0x0120, 0xa186,
+ 0x0100, 0x0170, 0x0018, 0xa186, 0x007e, 0x0150, 0xd794, 0x0118,
+ 0xa686, 0x0020, 0x0010, 0xa686, 0x0028, 0x0150, 0x0804, 0x3d5d,
+ 0x86ff, 0x1120, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x702f, 0x0001,
+ 0x711e, 0x7020, 0xa600, 0x7022, 0x772a, 0x2061, 0xadd1, 0x6007,
+ 0x0000, 0x6612, 0x7024, 0x600e, 0x6226, 0x632a, 0x642e, 0x6532,
+ 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b, 0x3df0, 0x0005,
+ 0x702c, 0xa005, 0x1170, 0x711c, 0x7024, 0x20a0, 0x7728, 0x2031,
+ 0x0000, 0x2061, 0xadd1, 0x6224, 0x6328, 0x642c, 0x6530, 0x0804,
+ 0x3d5d, 0x7120, 0x810b, 0x0804, 0x2dcc, 0x2029, 0x007e, 0x7924,
+ 0x7a28, 0x7b2c, 0x7c38, 0xa184, 0xff00, 0x8007, 0xa0e2, 0x0020,
+ 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa184, 0x00ff, 0xa0e2,
+ 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa284, 0xff00,
+ 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4,
+ 0xa284, 0x00ff, 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04,
+ 0x2df4, 0xa384, 0xff00, 0x8007, 0xa0e2, 0x0020, 0x0a04, 0x2df4,
+ 0xa502, 0x0a04, 0x2df4, 0xa384, 0x00ff, 0xa0e2, 0x0020, 0x0a04,
+ 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0xff00, 0x8007, 0xa0e2,
+ 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0xa484, 0x00ff,
+ 0xa0e2, 0x0020, 0x0a04, 0x2df4, 0xa502, 0x0a04, 0x2df4, 0x2061,
+ 0xafa6, 0x6102, 0x6206, 0x630a, 0x640e, 0x0804, 0x2dcc, 0x0006,
+ 0x2001, 0xad52, 0x2004, 0xd0cc, 0x000e, 0x0005, 0x0006, 0x2001,
+ 0xad71, 0x2004, 0xd0bc, 0x000e, 0x0005, 0x6164, 0x7a24, 0x6300,
+ 0x82ff, 0x1118, 0x7926, 0x0804, 0x2dcc, 0x83ff, 0x1904, 0x2df4,
+ 0x2001, 0xfff0, 0xa200, 0x1a04, 0x2df4, 0x2019, 0xffff, 0x6068,
+ 0xa302, 0xa200, 0x0a04, 0x2df4, 0x7926, 0x6266, 0x0804, 0x2dcc,
+ 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1904, 0x2df1, 0x7c28,
+ 0x7d24, 0x7e38, 0x7f2c, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x2009,
+ 0x0000, 0x2019, 0x0000, 0x7023, 0x0000, 0x702f, 0x0000, 0xad80,
+ 0x0003, 0x7026, 0x20a0, 0xa1e0, 0xae34, 0x2c64, 0x8cff, 0x01b8,
+ 0x6004, 0xa084, 0x00ff, 0xa086, 0x0006, 0x0130, 0x6004, 0xa084,
+ 0xff00, 0xa086, 0x0600, 0x1158, 0x6014, 0x20a2, 0x94a0, 0x6010,
+ 0x8007, 0xa105, 0x8007, 0x20a2, 0x94a0, 0xa398, 0x0002, 0x8108,
+ 0xa182, 0x00ff, 0x0120, 0xa386, 0x002a, 0x0148, 0x08e0, 0x83ff,
+ 0x1120, 0x7120, 0x810c, 0x0804, 0x2dcc, 0x702f, 0x0001, 0x711e,
+ 0x7020, 0xa300, 0x7022, 0x2061, 0xadd1, 0x6007, 0x0000, 0x6312,
+ 0x7024, 0x600e, 0x6426, 0x652a, 0x662e, 0x6732, 0x2c10, 0x080c,
+ 0x1624, 0x7007, 0x0002, 0x701b, 0x3ee6, 0x0005, 0x702c, 0xa005,
+ 0x1168, 0x711c, 0x7024, 0x20a0, 0x2019, 0x0000, 0x2061, 0xadd1,
+ 0x6424, 0x6528, 0x662c, 0x6730, 0x0804, 0x3ea3, 0x7120, 0x810c,
+ 0x0804, 0x2dcc, 0x81ff, 0x1904, 0x2df1, 0x60d0, 0xd0ac, 0x1118,
+ 0xd09c, 0x0904, 0x2df1, 0x080c, 0x3c05, 0x0904, 0x2df1, 0x7924,
+ 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x080c, 0x3c46, 0x701b, 0x3f11,
+ 0x0005, 0x00d6, 0xade8, 0x000d, 0x6828, 0xa0be, 0x7000, 0x0148,
+ 0xa0be, 0x7100, 0x0130, 0xa0be, 0x7200, 0x0118, 0x00de, 0x0804,
+ 0x2df4, 0x6820, 0x6924, 0x080c, 0x2676, 0x1510, 0x080c, 0x4c80,
+ 0x11f8, 0x7122, 0x6612, 0x6516, 0x6e18, 0x00c6, 0x080c, 0x3c05,
+ 0x01b8, 0x080c, 0x3c05, 0x01a0, 0x00ce, 0x00de, 0x6837, 0x0000,
+ 0x6838, 0xc0fd, 0x683a, 0x6823, 0x0000, 0x6804, 0x2068, 0x080c,
+ 0x96ef, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b, 0x3f4b, 0x0005,
+ 0x00de, 0x0804, 0x2df1, 0x7120, 0x080c, 0x2bc9, 0x6820, 0xa086,
+ 0x8001, 0x0904, 0x2df1, 0x2d00, 0x701e, 0x6804, 0xa080, 0x0002,
+ 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c, 0x48be, 0x000e,
+ 0xade8, 0x000d, 0x6a08, 0x6b0c, 0x6c10, 0x6d14, 0x2061, 0xadd1,
+ 0x6007, 0x0000, 0x6e00, 0x6f28, 0xa7c6, 0x7000, 0x1108, 0x0018,
+ 0xa7c6, 0x7100, 0x1140, 0xa6c2, 0x0004, 0x0a04, 0x2df4, 0x2009,
+ 0x0004, 0x0804, 0x3c49, 0xa7c6, 0x7200, 0x1904, 0x2df4, 0xa6c2,
+ 0x0054, 0x0a04, 0x2df4, 0x600e, 0x6013, 0x002a, 0x6226, 0x632a,
+ 0x642e, 0x6532, 0x2c10, 0x080c, 0x1624, 0x7007, 0x0002, 0x701b,
+ 0x3f92, 0x0005, 0x701c, 0x2068, 0x6804, 0xa080, 0x0001, 0x2004,
+ 0xa080, 0x0002, 0x0006, 0x20a9, 0x002a, 0x2098, 0x20a0, 0x080c,
+ 0x48be, 0x000e, 0x2009, 0x002a, 0x2061, 0xadd1, 0x6224, 0x6328,
+ 0x642c, 0x6530, 0x0804, 0x3c49, 0x81ff, 0x1904, 0x2df1, 0x080c,
+ 0x3c1a, 0x0904, 0x2df4, 0x080c, 0x4d96, 0x0904, 0x2df1, 0x080c,
+ 0x4ec6, 0x0804, 0x2dcc, 0x7824, 0xd084, 0x0904, 0x3804, 0x080c,
+ 0x3c2a, 0x0904, 0x2df4, 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120,
+ 0x2009, 0x0002, 0x0804, 0x2df1, 0x6004, 0xa084, 0x00ff, 0xa086,
+ 0x0006, 0x0128, 0xa08e, 0x0004, 0x0110, 0xa08e, 0x0005, 0x1508,
+ 0x2001, 0xad52, 0x2004, 0xd0b4, 0x0904, 0x3834, 0x6000, 0xd08c,
+ 0x1904, 0x3834, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c,
+ 0x970b, 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003,
+ 0x701b, 0x3ff3, 0x0005, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x0804,
+ 0x3834, 0x2009, 0xad30, 0x210c, 0x81ff, 0x0120, 0x2009, 0x0001,
+ 0x0804, 0x2df1, 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x0120,
+ 0x2009, 0x0007, 0x0804, 0x2df1, 0x2001, 0xad52, 0x2004, 0xd0ac,
+ 0x0120, 0x2009, 0x0008, 0x0804, 0x2df1, 0x609c, 0xd0a4, 0x1118,
+ 0xd0ac, 0x1904, 0x3834, 0x6837, 0x0000, 0x6833, 0x0000, 0x6838,
+ 0xc0fd, 0x683a, 0x080c, 0x979c, 0x1120, 0x2009, 0x0003, 0x0804,
+ 0x2df1, 0x7007, 0x0003, 0x701b, 0x402e, 0x0005, 0x6830, 0xa086,
+ 0x0100, 0x1120, 0x2009, 0x0004, 0x0804, 0x2df1, 0x080c, 0x3c2a,
+ 0x0904, 0x2df4, 0x0804, 0x3fd8, 0x81ff, 0x2009, 0x0001, 0x1904,
+ 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009, 0x0007, 0x1904, 0x2df1,
+ 0x2001, 0xad52, 0x2004, 0xd0ac, 0x2009, 0x0008, 0x1904, 0x2df1,
+ 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004, 0xa084, 0x00ff, 0xa086,
+ 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1, 0x00c6, 0x080c, 0x3c05,
+ 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1, 0x6837, 0x0000, 0x6833,
+ 0x0000, 0x6838, 0xc0fd, 0x683a, 0x7928, 0xa194, 0xff00, 0xa18c,
+ 0x00ff, 0xa006, 0x82ff, 0x1128, 0xc0ed, 0x6952, 0x792c, 0x6956,
+ 0x0048, 0xa28e, 0x0100, 0x1904, 0x2df4, 0xc0e5, 0x6853, 0x0000,
+ 0x6857, 0x0000, 0x683e, 0x080c, 0x9957, 0x2009, 0x0003, 0x0904,
+ 0x2df1, 0x7007, 0x0003, 0x701b, 0x408e, 0x0005, 0x6830, 0xa086,
+ 0x0100, 0x2009, 0x0004, 0x0904, 0x2df1, 0x0804, 0x2dcc, 0x81ff,
+ 0x2009, 0x0001, 0x1904, 0x2df1, 0x6000, 0xa086, 0x0003, 0x2009,
+ 0x0007, 0x1904, 0x2df1, 0x080c, 0x3c2a, 0x0904, 0x2df4, 0x6004,
+ 0xa084, 0x00ff, 0xa086, 0x0006, 0x2009, 0x0009, 0x1904, 0x2df1,
+ 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x2009, 0x0002, 0x0904, 0x2df1,
+ 0xad80, 0x000f, 0x2009, 0x0008, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x080c, 0x3c46, 0x701b, 0x40c5, 0x0005, 0x00d6, 0xade8, 0x000f,
+ 0x6800, 0xa086, 0x0500, 0x1140, 0x6804, 0xa005, 0x1128, 0x6808,
+ 0xa084, 0xff00, 0x1108, 0x0018, 0x00de, 0x1904, 0x2df4, 0x00de,
+ 0x6837, 0x0000, 0x6833, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x00c6,
+ 0x080c, 0x3c2a, 0x1118, 0x00ce, 0x0804, 0x2df4, 0x080c, 0x99a6,
+ 0x2009, 0x0003, 0x00ce, 0x0904, 0x2df1, 0x7007, 0x0003, 0x701b,
+ 0x40f2, 0x0005, 0x6830, 0xa086, 0x0100, 0x2009, 0x0004, 0x0904,
+ 0x2df1, 0x0804, 0x2dcc, 0x81ff, 0x0120, 0x2009, 0x0001, 0x0804,
+ 0x2df1, 0x6000, 0xa086, 0x0003, 0x0120, 0x2009, 0x0007, 0x0804,
+ 0x2df1, 0x7e24, 0x860f, 0xa18c, 0x00ff, 0xa6b4, 0x00ff, 0x080c,
+ 0x4cdc, 0x1904, 0x2df4, 0xa186, 0x007f, 0x0150, 0x6004, 0xa084,
+ 0x00ff, 0xa086, 0x0006, 0x0120, 0x2009, 0x0009, 0x0804, 0x2df1,
+ 0x00c6, 0x080c, 0x3c05, 0x00ce, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x2df1, 0x6837, 0x0000, 0x6838, 0xc0fd, 0x683a, 0x080c, 0x9726,
+ 0x1120, 0x2009, 0x0003, 0x0804, 0x2df1, 0x7007, 0x0003, 0x701b,
+ 0x413a, 0x0005, 0x6808, 0x8007, 0xa086, 0x0100, 0x1120, 0x2009,
+ 0x0004, 0x0804, 0x2df1, 0x68b0, 0x6836, 0x6810, 0x8007, 0xa084,
+ 0x00ff, 0x808e, 0x6814, 0x8007, 0xa084, 0x00ff, 0x8086, 0xa080,
+ 0x0002, 0xa108, 0xad80, 0x0004, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38,
+ 0x0804, 0x3c49, 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804,
+ 0x2df1, 0x7924, 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff,
+ 0x0110, 0x0804, 0x2df4, 0x2009, 0x001a, 0x7a2c, 0x7b28, 0x7c3c,
+ 0x7d38, 0x080c, 0x3c46, 0x701b, 0x4176, 0x0005, 0xad80, 0x000d,
+ 0x2098, 0x20a9, 0x001a, 0x20a1, 0xafad, 0x53a3, 0x0804, 0x2dcc,
+ 0x080c, 0x3c05, 0x1120, 0x2009, 0x0002, 0x0804, 0x2df1, 0x7924,
+ 0xa194, 0xff00, 0xa18c, 0x00ff, 0x8217, 0x82ff, 0x0110, 0x0804,
+ 0x2df4, 0x2099, 0xafad, 0x20a0, 0x20a9, 0x001a, 0x53a3, 0x2009,
+ 0x001a, 0x7a2c, 0x7b28, 0x7c3c, 0x7d38, 0x0804, 0x3c49, 0x7824,
+ 0xa08a, 0x1000, 0x1a04, 0x2df4, 0x0126, 0x2091, 0x8000, 0x8003,
+ 0x800b, 0x810b, 0xa108, 0x00c6, 0x2061, 0xafda, 0x6142, 0x00ce,
+ 0x012e, 0x0804, 0x2dcc, 0x00c6, 0x080c, 0x574f, 0x1188, 0x2001,
+ 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0xa085,
+ 0x0001, 0x080c, 0x5793, 0x080c, 0x569a, 0x080c, 0x14f6, 0x0038,
+ 0x2061, 0xad00, 0x6030, 0xc09d, 0x6032, 0x080c, 0x485e, 0x00ce,
+ 0x0005, 0x0126, 0x00c6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+ 0x6044, 0xd0a4, 0x11b0, 0xd084, 0x0118, 0x080c, 0x4348, 0x0068,
+ 0xd08c, 0x0118, 0x080c, 0x4269, 0x0040, 0xd094, 0x0118, 0x080c,
+ 0x423a, 0x0018, 0xd09c, 0x0108, 0x0061, 0x00ee, 0x00ce, 0x012e,
+ 0x0005, 0x0016, 0x6128, 0xd19c, 0x1110, 0xc19d, 0x612a, 0x001e,
+ 0x0ca0, 0x624c, 0xa286, 0xf0f0, 0x1150, 0x6048, 0xa086, 0xf0f0,
+ 0x0130, 0x624a, 0x6043, 0x0090, 0x6043, 0x0010, 0x0490, 0xa294,
+ 0xff00, 0xa296, 0xf700, 0x0178, 0x7134, 0xd1a4, 0x1160, 0x6240,
+ 0xa295, 0x0100, 0x6242, 0xa294, 0x0010, 0x0128, 0x2009, 0x00f7,
+ 0x080c, 0x48de, 0x00f0, 0x6040, 0xa084, 0x0010, 0xa085, 0x0040,
+ 0x6042, 0x6043, 0x0000, 0x7077, 0x0000, 0x7093, 0x0001, 0x70b7,
+ 0x0000, 0x70d3, 0x0000, 0x2009, 0xb3c0, 0x200b, 0x0000, 0x7087,
+ 0x0000, 0x707b, 0x000a, 0x2009, 0x000a, 0x2011, 0x4814, 0x080c,
+ 0x6593, 0x0005, 0x0156, 0x2001, 0xad73, 0x2004, 0xd08c, 0x0110,
+ 0x704f, 0xffff, 0x7078, 0xa005, 0x1510, 0x2011, 0x4814, 0x080c,
+ 0x650d, 0x6040, 0xa094, 0x0010, 0xa285, 0x0020, 0x6042, 0x20a9,
+ 0x00c8, 0x6044, 0xd08c, 0x1168, 0x1f04, 0x4251, 0x6242, 0x708b,
+ 0x0000, 0x6040, 0xa094, 0x0010, 0xa285, 0x0080, 0x6042, 0x6242,
+ 0x0030, 0x6242, 0x708b, 0x0000, 0x707f, 0x0000, 0x0000, 0x015e,
+ 0x0005, 0x707c, 0xa08a, 0x0003, 0x1210, 0x0023, 0x0010, 0x080c,
+ 0x14f6, 0x0005, 0x4275, 0x42c5, 0x4347, 0x00f6, 0x707f, 0x0001,
+ 0x20e1, 0xa000, 0xe000, 0x20e1, 0x8700, 0x080c, 0x22f8, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x2079, 0xb200, 0x207b, 0x2200, 0x7807,
+ 0x00ef, 0x780b, 0x0000, 0x780f, 0x00ef, 0x7813, 0x0138, 0x7817,
+ 0x0000, 0x781b, 0x0000, 0x781f, 0x0000, 0x7823, 0xffff, 0x7827,
+ 0xffff, 0x782b, 0x0000, 0x782f, 0x0000, 0x2079, 0xb20c, 0x207b,
+ 0x1101, 0x7807, 0x0000, 0x2099, 0xad05, 0x20a1, 0xb20e, 0x20a9,
+ 0x0004, 0x53a3, 0x2079, 0xb212, 0x207b, 0x0000, 0x7807, 0x0000,
+ 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6, 0x60c3,
+ 0x000c, 0x600f, 0x0000, 0x080c, 0x4845, 0x00fe, 0x7083, 0x0000,
+ 0x6043, 0x0008, 0x6043, 0x0000, 0x0005, 0x00d6, 0x7080, 0x7083,
+ 0x0000, 0xa025, 0x0904, 0x432f, 0x6020, 0xd0b4, 0x1904, 0x432d,
+ 0x7190, 0x81ff, 0x0904, 0x431d, 0xa486, 0x000c, 0x1904, 0x4328,
+ 0xa480, 0x0018, 0x8004, 0x20a8, 0x2011, 0xb280, 0x2019, 0xb200,
+ 0x220c, 0x2304, 0xa106, 0x11b8, 0x8210, 0x8318, 0x1f04, 0x42e0,
+ 0x6043, 0x0004, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043, 0x0006,
+ 0x707f, 0x0002, 0x708b, 0x0002, 0x2009, 0x07d0, 0x2011, 0x481b,
+ 0x080c, 0x6593, 0x0490, 0x2069, 0xb280, 0x6930, 0xa18e, 0x1101,
+ 0x1538, 0x6834, 0xa005, 0x1520, 0x6900, 0xa18c, 0x00ff, 0x1118,
+ 0x6804, 0xa005, 0x0190, 0x2011, 0xb28e, 0x2019, 0xad05, 0x20a9,
+ 0x0004, 0x220c, 0x2304, 0xa102, 0x0230, 0x1190, 0x8210, 0x8318,
+ 0x1f04, 0x4311, 0x0068, 0x7093, 0x0000, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9, 0x0014, 0x53a6,
+ 0x6043, 0x0008, 0x6043, 0x0000, 0x0010, 0x00de, 0x0005, 0x6040,
+ 0xa085, 0x0100, 0x6042, 0x6020, 0xd0b4, 0x1db8, 0x60c3, 0x000c,
+ 0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x20e1, 0x9080,
+ 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x0c30, 0x0005,
+ 0x7088, 0xa08a, 0x001d, 0x1210, 0x0023, 0x0010, 0x080c, 0x14f6,
+ 0x0005, 0x437b, 0x438a, 0x43b2, 0x43cb, 0x43ef, 0x4417, 0x443b,
+ 0x446c, 0x4490, 0x44b8, 0x44ef, 0x4517, 0x4533, 0x4549, 0x4569,
+ 0x457c, 0x4584, 0x45b1, 0x45d5, 0x45fd, 0x4621, 0x4652, 0x468f,
+ 0x46be, 0x46da, 0x4719, 0x4739, 0x4752, 0x4753, 0x00c6, 0x2061,
+ 0xad00, 0x6003, 0x0007, 0x2061, 0x0100, 0x6004, 0xa084, 0xfff9,
+ 0x6006, 0x00ce, 0x0005, 0x608b, 0xbc94, 0x608f, 0xf0f0, 0x6043,
+ 0x0002, 0x708b, 0x0001, 0x2009, 0x07d0, 0x2011, 0x481b, 0x080c,
+ 0x6593, 0x0005, 0x00f6, 0x7080, 0xa086, 0x0014, 0x1508, 0x6043,
+ 0x0000, 0x6020, 0xd0b4, 0x11e0, 0x2079, 0xb280, 0x7a30, 0xa296,
+ 0x1102, 0x11a0, 0x7834, 0xa005, 0x1188, 0x7a38, 0xd2fc, 0x0128,
+ 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x2011, 0x481b, 0x080c,
+ 0x650d, 0x708b, 0x0010, 0x080c, 0x4584, 0x0010, 0x080c, 0x485e,
+ 0x00fe, 0x0005, 0x708b, 0x0003, 0x6043, 0x0004, 0x2011, 0x481b,
+ 0x080c, 0x650d, 0x080c, 0x48c6, 0x20a3, 0x1102, 0x20a3, 0x0000,
+ 0x20a9, 0x000a, 0x20a3, 0x0000, 0x1f04, 0x43c2, 0x60c3, 0x0014,
+ 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011,
+ 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280,
+ 0x7a30, 0xa296, 0x1102, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38,
+ 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b,
+ 0x0004, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+ 0x0005, 0x080c, 0x48c6, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430,
+ 0x2011, 0xb28e, 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148,
+ 0x714c, 0xa186, 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c,
+ 0x48f5, 0x20a9, 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6,
+ 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+ 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1103, 0x1178,
+ 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+ 0x1110, 0x70b7, 0x0001, 0x708b, 0x0006, 0x0029, 0x0010, 0x080c,
+ 0x485e, 0x00fe, 0x0005, 0x708b, 0x0007, 0x080c, 0x48c6, 0x20a3,
+ 0x1104, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917,
+ 0x11a8, 0x7074, 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170,
+ 0xa180, 0x2be6, 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df,
+ 0x0128, 0x080c, 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008,
+ 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0,
+ 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079,
+ 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005, 0x1160,
+ 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+ 0x708b, 0x0008, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005,
+ 0x708b, 0x0009, 0x080c, 0x48c6, 0x20a3, 0x1105, 0x20a3, 0x0100,
+ 0x3430, 0x080c, 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c,
+ 0x4754, 0x1170, 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008,
+ 0x2099, 0xb28e, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0014, 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005,
+ 0x00f6, 0x7080, 0xa005, 0x0588, 0x2011, 0x481b, 0x080c, 0x650d,
+ 0xa086, 0x0014, 0x1540, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1105,
+ 0x1510, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1160, 0x7a38, 0xd2fc,
+ 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x000a,
+ 0x00b1, 0x0098, 0xa005, 0x1178, 0x7a38, 0xd2fc, 0x0128, 0x70b4,
+ 0xa005, 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x708b, 0x000e,
+ 0x080c, 0x4569, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b,
+ 0x000b, 0x2011, 0xb20e, 0x22a0, 0x20a9, 0x0040, 0x2019, 0xffff,
+ 0x43a4, 0x20a9, 0x0002, 0x2009, 0x0000, 0x41a4, 0x080c, 0x48c6,
+ 0x20a3, 0x1106, 0x20a3, 0x0000, 0x080c, 0x4917, 0x0118, 0x2013,
+ 0x0000, 0x0020, 0x7050, 0xa085, 0x0100, 0x2012, 0x2298, 0x20a9,
+ 0x0042, 0x53a6, 0x60c3, 0x0084, 0x080c, 0x4845, 0x0005, 0x00f6,
+ 0x7080, 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086,
+ 0x0084, 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138,
+ 0x7834, 0xa005, 0x1120, 0x708b, 0x000c, 0x0029, 0x0010, 0x080c,
+ 0x485e, 0x00fe, 0x0005, 0x708b, 0x000d, 0x080c, 0x48c6, 0x20a3,
+ 0x1107, 0x20a3, 0x0000, 0x2099, 0xb28e, 0x20a9, 0x0040, 0x53a6,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+ 0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+ 0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+ 0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+ 0x48b8, 0x708b, 0x000e, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+ 0x0005, 0x708b, 0x000f, 0x7083, 0x0000, 0x608b, 0xbc85, 0x608f,
+ 0xb5b5, 0x6043, 0x0005, 0x6043, 0x0004, 0x2009, 0x07d0, 0x2011,
+ 0x481b, 0x080c, 0x6501, 0x0005, 0x7080, 0xa005, 0x0120, 0x2011,
+ 0x481b, 0x080c, 0x650d, 0x0005, 0x708b, 0x0011, 0x080c, 0x4917,
+ 0x1188, 0x716c, 0x81ff, 0x0170, 0x2009, 0x0000, 0x7070, 0xa084,
+ 0x00ff, 0x080c, 0x2676, 0xa186, 0x0080, 0x0120, 0x2011, 0xb28e,
+ 0x080c, 0x47df, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+ 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007, 0xa084,
+ 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0014, 0x080c, 0x4845,
+ 0x0005, 0x00f6, 0x7080, 0xa005, 0x01f0, 0x2011, 0x481b, 0x080c,
+ 0x650d, 0xa086, 0x0014, 0x11a8, 0x2079, 0xb280, 0x7a30, 0xa296,
+ 0x1103, 0x1178, 0x7834, 0xa005, 0x1160, 0x7a38, 0xd2fc, 0x0128,
+ 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001, 0x708b, 0x0012, 0x0029,
+ 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x708b, 0x0013, 0x080c,
+ 0x48d2, 0x20a3, 0x1103, 0x20a3, 0x0000, 0x3430, 0x2011, 0xb28e,
+ 0x080c, 0x4917, 0x1160, 0x7074, 0xa005, 0x1148, 0x714c, 0xa186,
+ 0xffff, 0x0128, 0x080c, 0x47df, 0x0110, 0x080c, 0x48f5, 0x20a9,
+ 0x0008, 0x2298, 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x60c3, 0x0014, 0x080c, 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005,
+ 0x01f0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0014, 0x11a8,
+ 0x2079, 0xb280, 0x7a30, 0xa296, 0x1104, 0x1178, 0x7834, 0xa005,
+ 0x1160, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7,
+ 0x0001, 0x708b, 0x0014, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+ 0x0005, 0x708b, 0x0015, 0x080c, 0x48d2, 0x20a3, 0x1104, 0x20a3,
+ 0x0000, 0x3430, 0x2011, 0xb28e, 0x080c, 0x4917, 0x11a8, 0x7074,
+ 0xa005, 0x1190, 0x7154, 0xa186, 0xffff, 0x0170, 0xa180, 0x2be6,
+ 0x200d, 0xa18c, 0xff00, 0x810f, 0x080c, 0x47df, 0x0128, 0x080c,
+ 0x3e66, 0x0110, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2298, 0x26a0,
+ 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c,
+ 0x4845, 0x0005, 0x00f6, 0x7080, 0xa005, 0x05b8, 0x2011, 0x481b,
+ 0x080c, 0x650d, 0xa086, 0x0014, 0x1570, 0x2079, 0xb280, 0x7a30,
+ 0xa296, 0x1105, 0x1540, 0x7834, 0x2011, 0x0100, 0xa21e, 0x1148,
+ 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005, 0x1110, 0x70b7, 0x0001,
+ 0x0060, 0xa005, 0x11c0, 0x7a38, 0xd2fc, 0x0128, 0x70b4, 0xa005,
+ 0x1110, 0x70b7, 0x0001, 0x7087, 0x0000, 0x7a38, 0xd2f4, 0x0138,
+ 0x2001, 0xad73, 0x2004, 0xd0a4, 0x1110, 0x70d3, 0x0008, 0x708b,
+ 0x0016, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe, 0x0005, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280, 0x20a1, 0x020b, 0x20a9,
+ 0x000e, 0x53a6, 0x3430, 0x2011, 0xb28e, 0x708b, 0x0017, 0x080c,
+ 0x4917, 0x1150, 0x7074, 0xa005, 0x1138, 0x080c, 0x4754, 0x1170,
+ 0xa085, 0x0001, 0x080c, 0x26c0, 0x20a9, 0x0008, 0x2099, 0xb28e,
+ 0x26a0, 0x53a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014,
+ 0x080c, 0x4845, 0x0010, 0x080c, 0x436e, 0x0005, 0x00f6, 0x7080,
+ 0xa005, 0x01b0, 0x2011, 0x481b, 0x080c, 0x650d, 0xa086, 0x0084,
+ 0x1168, 0x2079, 0xb280, 0x7a30, 0xa296, 0x1106, 0x1138, 0x7834,
+ 0xa005, 0x1120, 0x708b, 0x0018, 0x0029, 0x0010, 0x080c, 0x485e,
+ 0x00fe, 0x0005, 0x708b, 0x0019, 0x080c, 0x48d2, 0x20a3, 0x1106,
+ 0x20a3, 0x0000, 0x3430, 0x2099, 0xb28e, 0x2039, 0xb20e, 0x27a0,
+ 0x20a9, 0x0040, 0x53a3, 0x080c, 0x4917, 0x11e8, 0x2728, 0x2514,
+ 0x8207, 0xa084, 0x00ff, 0x8000, 0x2018, 0xa294, 0x00ff, 0x8007,
+ 0xa205, 0x202a, 0x7050, 0x2310, 0x8214, 0xa2a0, 0xb20e, 0x2414,
+ 0xa38c, 0x0001, 0x0118, 0xa294, 0xff00, 0x0018, 0xa294, 0x00ff,
+ 0x8007, 0xa215, 0x2222, 0x2798, 0x26a0, 0x20a9, 0x0040, 0x53a6,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0084, 0x080c, 0x4845,
+ 0x0005, 0x00f6, 0x7080, 0xa005, 0x01d0, 0x2011, 0x481b, 0x080c,
+ 0x650d, 0xa086, 0x0084, 0x1188, 0x2079, 0xb280, 0x7a30, 0xa296,
+ 0x1107, 0x1158, 0x7834, 0xa005, 0x1140, 0x7087, 0x0001, 0x080c,
+ 0x48b8, 0x708b, 0x001a, 0x0029, 0x0010, 0x080c, 0x485e, 0x00fe,
+ 0x0005, 0x708b, 0x001b, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099,
+ 0xb280, 0x20a1, 0x020b, 0x7480, 0xa480, 0x0018, 0xa080, 0x0007,
+ 0xa084, 0x03f8, 0x8004, 0x20a8, 0x53a6, 0x60c3, 0x0084, 0x080c,
+ 0x4845, 0x0005, 0x0005, 0x0005, 0x0086, 0x0096, 0x2029, 0xad52,
+ 0x252c, 0x20a9, 0x0008, 0x2041, 0xb20e, 0x28a0, 0x2099, 0xb28e,
+ 0x53a3, 0x20a9, 0x0008, 0x2011, 0x0007, 0xd5d4, 0x0110, 0x2011,
+ 0x0000, 0x2800, 0xa200, 0x200c, 0xa1a6, 0xffff, 0x1148, 0xd5d4,
+ 0x0110, 0x8210, 0x0008, 0x8211, 0x1f04, 0x4769, 0x0804, 0x47d7,
+ 0x82ff, 0x1160, 0xd5d4, 0x0120, 0xa1a6, 0x3fff, 0x0d90, 0x0020,
+ 0xa1a6, 0x3fff, 0x0904, 0x47d7, 0xa18d, 0xc000, 0x20a9, 0x0010,
+ 0x2019, 0x0001, 0xd5d4, 0x0110, 0x2019, 0x0010, 0x2120, 0xd5d4,
+ 0x0110, 0x8423, 0x0008, 0x8424, 0x1240, 0xd5d4, 0x0110, 0x8319,
+ 0x0008, 0x8318, 0x1f04, 0x478f, 0x04d0, 0x23a8, 0x2021, 0x0001,
+ 0x8426, 0x8425, 0x1f04, 0x47a1, 0x2328, 0x8529, 0xa2be, 0x0007,
+ 0x0158, 0x0006, 0x2039, 0x0007, 0x2200, 0xa73a, 0x000e, 0x27a8,
+ 0xa5a8, 0x0010, 0x1f04, 0x47b0, 0x754e, 0xa5c8, 0x2be6, 0x292d,
+ 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016, 0x2508, 0x080c,
+ 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x2018, 0x2304, 0xa405,
+ 0x201a, 0x7077, 0x0001, 0x26a0, 0x2898, 0x20a9, 0x0008, 0x53a6,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0xa085, 0x0001, 0x0028, 0xa006,
+ 0x0018, 0xa006, 0x080c, 0x14f6, 0x009e, 0x008e, 0x0005, 0x2118,
+ 0x2021, 0x0000, 0x2001, 0x0007, 0xa39a, 0x0010, 0x0218, 0x8420,
+ 0x8001, 0x0cd0, 0x2118, 0x84ff, 0x0120, 0xa39a, 0x0010, 0x8421,
+ 0x1de0, 0x2021, 0x0001, 0x83ff, 0x0118, 0x8423, 0x8319, 0x1de8,
+ 0xa238, 0x2704, 0xa42c, 0x11b8, 0xa405, 0x203a, 0x714e, 0xa1a0,
+ 0x2be6, 0x242d, 0xa5ac, 0x00ff, 0x7572, 0x6532, 0x6536, 0x0016,
+ 0x2508, 0x080c, 0x26a0, 0x001e, 0x60e7, 0x0000, 0x65ea, 0x7077,
+ 0x0001, 0xa084, 0x0000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x707b,
+ 0x0000, 0x00ee, 0x0005, 0x00e6, 0x00f6, 0x2079, 0x0100, 0x2071,
+ 0x0140, 0x080c, 0x7834, 0x7004, 0xa084, 0x4000, 0x0120, 0x7003,
+ 0x1000, 0x7003, 0x0000, 0x0126, 0x2091, 0x8000, 0x2071, 0xad22,
+ 0x2073, 0x0000, 0x7840, 0x0026, 0x0016, 0x2009, 0x00f7, 0x080c,
+ 0x48de, 0x001e, 0xa094, 0x0010, 0xa285, 0x0080, 0x7842, 0x7a42,
+ 0x002e, 0x012e, 0x00fe, 0x00ee, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x2011, 0xafd1, 0x2013, 0x0000, 0x7083, 0x0000, 0x012e, 0x20e1,
+ 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x080c, 0x782b, 0x2009,
+ 0x07d0, 0x2011, 0x481b, 0x080c, 0x6593, 0x0005, 0x0016, 0x0026,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x2009, 0x00f7, 0x080c, 0x48de,
+ 0x2061, 0xafda, 0x601b, 0x0000, 0x601f, 0x0000, 0x2061, 0xad00,
+ 0x6003, 0x0001, 0x2061, 0x0100, 0x6043, 0x0090, 0x6043, 0x0010,
+ 0x2009, 0x002d, 0x2011, 0x4883, 0x080c, 0x6501, 0x012e, 0x00ce,
+ 0x002e, 0x001e, 0x0005, 0x00e6, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2071, 0x0100, 0x080c, 0x7834, 0x2071, 0x0140, 0x7004, 0xa084,
+ 0x4000, 0x0120, 0x7003, 0x1000, 0x7003, 0x0000, 0x080c, 0x5757,
+ 0x01a8, 0x080c, 0x5775, 0x1190, 0x2001, 0xaf9d, 0x2003, 0xaaaa,
+ 0x0016, 0x080c, 0x2744, 0x2001, 0xaf8e, 0x2102, 0x001e, 0x2001,
+ 0xaf9e, 0x2003, 0x0000, 0x080c, 0x569a, 0x0030, 0x2001, 0x0001,
+ 0x080c, 0x261e, 0x080c, 0x485e, 0x012e, 0x000e, 0x00ee, 0x0005,
+ 0x20a9, 0x0040, 0x20a1, 0xb3c0, 0x2099, 0xb28e, 0x3304, 0x8007,
+ 0x20a2, 0x9398, 0x94a0, 0x1f04, 0x48be, 0x0005, 0x20e1, 0x9080,
+ 0x20e1, 0x4000, 0x2099, 0xb200, 0x20a1, 0x020b, 0x20a9, 0x000c,
+ 0x53a6, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x2099, 0xb280,
+ 0x20a1, 0x020b, 0x20a9, 0x000c, 0x53a6, 0x0005, 0x00c6, 0x0006,
+ 0x2061, 0x0100, 0x810f, 0x2001, 0xad30, 0x2004, 0xa005, 0x1138,
+ 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0xa105, 0x0010, 0xa185,
+ 0x00f7, 0x604a, 0x000e, 0x00ce, 0x0005, 0x0016, 0x0046, 0x2001,
+ 0xad52, 0x2004, 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a,
+ 0x080c, 0xa96c, 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019,
+ 0x002a, 0x2009, 0x0000, 0x080c, 0x2aac, 0x004e, 0x001e, 0x0005,
+ 0x080c, 0x485e, 0x708b, 0x0000, 0x7083, 0x0000, 0x0005, 0x0006,
+ 0x2001, 0xad0c, 0x2004, 0xd09c, 0x0100, 0x000e, 0x0005, 0x0006,
+ 0x0016, 0x0126, 0x2091, 0x8000, 0x2001, 0x0101, 0x200c, 0xa18d,
+ 0x0006, 0x2102, 0x012e, 0x001e, 0x000e, 0x0005, 0x0156, 0x20a9,
+ 0x00ff, 0x2009, 0xae34, 0xa006, 0x200a, 0x8108, 0x1f04, 0x4934,
+ 0x015e, 0x0005, 0x00d6, 0x0036, 0x0156, 0x0136, 0x0146, 0x2069,
+ 0xad51, 0xa006, 0x6002, 0x6007, 0x0707, 0x600a, 0x600e, 0x6012,
+ 0xa198, 0x2be6, 0x231d, 0xa39c, 0x00ff, 0x6316, 0x20a9, 0x0004,
+ 0xac98, 0x0006, 0x23a0, 0x40a4, 0x20a9, 0x0004, 0xac98, 0x000a,
+ 0x23a0, 0x40a4, 0x603e, 0x6042, 0x604e, 0x6052, 0x6056, 0x605a,
+ 0x605e, 0x6062, 0x6066, 0x606a, 0x606e, 0x6072, 0x6076, 0x607a,
+ 0x607e, 0x6082, 0x6086, 0x608a, 0x608e, 0x6092, 0x6096, 0x609a,
+ 0x609e, 0x60ae, 0x61a2, 0x00d6, 0x60a4, 0xa06d, 0x0110, 0x080c,
+ 0x15f0, 0x60a7, 0x0000, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0,
+ 0x60ab, 0x0000, 0x00de, 0xa006, 0x604a, 0x6810, 0x603a, 0x680c,
+ 0x6046, 0x6814, 0xa084, 0x00ff, 0x6042, 0x014e, 0x013e, 0x015e,
+ 0x003e, 0x00de, 0x0005, 0x0126, 0x2091, 0x8000, 0x6944, 0x6e48,
+ 0xa684, 0x3fff, 0xa082, 0x4000, 0x1a04, 0x4a49, 0xa18c, 0xff00,
+ 0x810f, 0xa182, 0x00ff, 0x1a04, 0x4a4e, 0x2001, 0xad0c, 0x2004,
+ 0xa084, 0x0003, 0x01c0, 0x2001, 0xad0c, 0x2004, 0xd084, 0x1904,
+ 0x4a31, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904, 0x4a31, 0x6004,
+ 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a31, 0x6000, 0xd0c4,
+ 0x0904, 0x4a31, 0x0068, 0xa188, 0xae34, 0x2104, 0xa065, 0x0904,
+ 0x4a15, 0x6004, 0xa084, 0x00ff, 0xa08e, 0x0006, 0x1904, 0x4a1a,
+ 0x60a4, 0xa00d, 0x0118, 0x080c, 0x4ef9, 0x05d0, 0x60a8, 0xa00d,
+ 0x0188, 0x080c, 0x4f43, 0x1170, 0x694c, 0xd1fc, 0x1118, 0x080c,
+ 0x4c11, 0x0448, 0x080c, 0x4bd3, 0x694c, 0xd1ec, 0x1520, 0x080c,
+ 0x4ded, 0x0408, 0x694c, 0xa184, 0xa000, 0x0178, 0xd1ec, 0x0140,
+ 0xd1fc, 0x0118, 0x080c, 0x4dfc, 0x0028, 0x080c, 0x4dfc, 0x0028,
+ 0xd1fc, 0x0118, 0x080c, 0x4bd3, 0x0070, 0x6050, 0xa00d, 0x0130,
+ 0x2d00, 0x200a, 0x6803, 0x0000, 0x6052, 0x0028, 0x2d00, 0x6052,
+ 0x604e, 0x6803, 0x0000, 0x080c, 0x67c5, 0xa006, 0x012e, 0x0005,
+ 0x2001, 0x0005, 0x2009, 0x0000, 0x04e8, 0x2001, 0x0028, 0x2009,
+ 0x0000, 0x04c0, 0xa082, 0x0006, 0x12a0, 0x2001, 0xad34, 0x2004,
+ 0xd0ac, 0x1160, 0x60a0, 0xd0bc, 0x1148, 0x6100, 0xd1fc, 0x0904,
+ 0x49d0, 0x2001, 0x0029, 0x2009, 0x1000, 0x0420, 0x2001, 0x0028,
+ 0x00a8, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004,
+ 0x0068, 0xd184, 0x0118, 0x2001, 0x0004, 0x0040, 0x2001, 0x0029,
+ 0x6100, 0xd1fc, 0x0118, 0x2009, 0x1000, 0x0060, 0x2009, 0x0000,
+ 0x0048, 0x2001, 0x0029, 0x2009, 0x0000, 0x0020, 0x2001, 0x0029,
+ 0x2009, 0x0000, 0xa005, 0x012e, 0x0005, 0x00e6, 0x0126, 0x2091,
+ 0x8000, 0x6844, 0x8007, 0xa084, 0x00ff, 0x2008, 0xa182, 0x00ff,
+ 0x1a04, 0x4aa8, 0xa188, 0xae34, 0x2104, 0xa065, 0x01c0, 0x6004,
+ 0xa084, 0x00ff, 0xa08e, 0x0006, 0x11a8, 0x2c70, 0x080c, 0x8022,
+ 0x05e8, 0x2e00, 0x601a, 0x2d00, 0x6012, 0x600b, 0xffff, 0x601f,
+ 0x000a, 0x2009, 0x0003, 0x080c, 0x80a7, 0xa006, 0x0460, 0x2001,
+ 0x0028, 0x0440, 0xa082, 0x0006, 0x1298, 0x2001, 0xad34, 0x2004,
+ 0xd0ac, 0x1158, 0x60a0, 0xd0bc, 0x1140, 0x6100, 0xd1fc, 0x09e8,
+ 0x2001, 0x0029, 0x2009, 0x1000, 0x00a8, 0x2001, 0x0028, 0x0090,
+ 0x2009, 0xad0c, 0x210c, 0xd18c, 0x0118, 0x2001, 0x0004, 0x0050,
+ 0xd184, 0x0118, 0x2001, 0x0004, 0x0028, 0x2001, 0x0029, 0x0010,
+ 0x2001, 0x0029, 0xa005, 0x012e, 0x00ee, 0x0005, 0x2001, 0x002c,
+ 0x0cc8, 0x00f6, 0x00e6, 0x0126, 0x2091, 0x8000, 0x2011, 0x0000,
+ 0x2079, 0xad00, 0x6944, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+ 0x1a04, 0x4b77, 0x2001, 0xad0c, 0x2004, 0xa084, 0x0003, 0x1904,
+ 0x4b65, 0x080c, 0x4cdc, 0x1180, 0x6004, 0xa084, 0x00ff, 0xa082,
+ 0x0006, 0x1250, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1904, 0x4b60,
+ 0x60a0, 0xd0bc, 0x1904, 0x4b60, 0x6864, 0xa0c6, 0x006f, 0x0118,
+ 0x2008, 0x0804, 0x4b28, 0x6968, 0x2140, 0xa18c, 0xff00, 0x810f,
+ 0x78d0, 0xd0ac, 0x1118, 0xa182, 0x0080, 0x06d0, 0xa182, 0x00ff,
+ 0x16b8, 0x6a70, 0x6b6c, 0x786c, 0xa306, 0x1160, 0x7870, 0xa24e,
+ 0x1118, 0x2208, 0x2310, 0x0460, 0xa9cc, 0xff00, 0x1118, 0x2208,
+ 0x2310, 0x0430, 0x080c, 0x3b58, 0x2c70, 0x0550, 0x2009, 0x0000,
+ 0x2011, 0x0000, 0xa0c6, 0x4000, 0x1160, 0x0006, 0x2e60, 0x080c,
+ 0x4f6e, 0x1108, 0xc185, 0x7000, 0xd0bc, 0x0108, 0xc18d, 0x000e,
+ 0x0088, 0xa0c6, 0x4007, 0x1110, 0x2408, 0x0060, 0xa0c6, 0x4008,
+ 0x1118, 0x2708, 0x2610, 0x0030, 0xa0c6, 0x4009, 0x1108, 0x0010,
+ 0x2001, 0x4006, 0x6866, 0x696a, 0x6a6e, 0x2001, 0x0030, 0x0458,
+ 0x080c, 0x8022, 0x1138, 0x2001, 0x4005, 0x2009, 0x0003, 0x2011,
+ 0x0000, 0x0c80, 0x2e00, 0x601a, 0x080c, 0x9956, 0x2d00, 0x6012,
+ 0x601f, 0x0001, 0xa006, 0xd88c, 0x0110, 0x2001, 0x4000, 0x683a,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x2ad9, 0x012e, 0x2001, 0x0000,
+ 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x2009, 0x0002,
+ 0x080c, 0x80a7, 0xa006, 0xa005, 0x012e, 0x00ee, 0x00fe, 0x0005,
+ 0x2001, 0x0028, 0x2009, 0x0000, 0x0cb0, 0x2009, 0xad0c, 0x210c,
+ 0xd18c, 0x0118, 0x2001, 0x0004, 0x0038, 0xd184, 0x0118, 0x2001,
+ 0x0004, 0x0010, 0x2001, 0x0029, 0x2009, 0x0000, 0x0c20, 0x2001,
+ 0x0029, 0x2009, 0x0000, 0x08f8, 0x6944, 0x6e48, 0xa684, 0x3fff,
+ 0xa082, 0x4000, 0x16b8, 0xa18c, 0xff00, 0x810f, 0xa182, 0x00ff,
+ 0x12e0, 0xa188, 0xae34, 0x2104, 0xa065, 0x01b8, 0x6004, 0xa084,
+ 0x00ff, 0xa08e, 0x0006, 0x11b0, 0x684c, 0xd0ec, 0x0120, 0x080c,
+ 0x4dfc, 0x04c9, 0x0030, 0x04b9, 0x684c, 0xd0fc, 0x0110, 0x080c,
+ 0x4ded, 0x080c, 0x4e3a, 0xa006, 0x00c8, 0x2001, 0x0028, 0x2009,
+ 0x0000, 0x00a0, 0xa082, 0x0006, 0x1240, 0x6100, 0xd1fc, 0x0d20,
+ 0x2001, 0x0029, 0x2009, 0x1000, 0x0048, 0x2001, 0x0029, 0x2009,
+ 0x0000, 0x0020, 0x2001, 0x0029, 0x2009, 0x0000, 0xa005, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x6050, 0xa00d, 0x0138, 0x2d00, 0x200a,
+ 0x6803, 0x0000, 0x6052, 0x012e, 0x0005, 0x2d00, 0x6052, 0x604e,
+ 0x6803, 0x0000, 0x0cc0, 0x0126, 0x2091, 0x8000, 0x604c, 0xa005,
+ 0x0170, 0x00e6, 0x2071, 0xafc7, 0x7004, 0xa086, 0x0002, 0x0168,
+ 0x00ee, 0x604c, 0x6802, 0x2d00, 0x604e, 0x012e, 0x0005, 0x2d00,
+ 0x6052, 0x604e, 0x6803, 0x0000, 0x0cc0, 0x701c, 0xac06, 0x1d80,
+ 0x604c, 0x2070, 0x7000, 0x6802, 0x2d00, 0x7002, 0x00ee, 0x012e,
+ 0x0005, 0x0126, 0x2091, 0x8000, 0x604c, 0xa06d, 0x0130, 0x6800,
+ 0xa005, 0x1108, 0x6052, 0x604e, 0xad05, 0x012e, 0x0005, 0x604c,
+ 0xa06d, 0x0130, 0x6800, 0xa005, 0x1108, 0x6052, 0x604e, 0xad05,
+ 0x0005, 0x6803, 0x0000, 0x6084, 0xa00d, 0x0120, 0x2d00, 0x200a,
+ 0x6086, 0x0005, 0x2d00, 0x6086, 0x6082, 0x0cd8, 0x0126, 0x00c6,
+ 0x0026, 0x2091, 0x8000, 0x6218, 0x2260, 0x6200, 0xa005, 0x0110,
+ 0xc285, 0x0008, 0xc284, 0x6202, 0x002e, 0x00ce, 0x012e, 0x0005,
+ 0x0126, 0x00c6, 0x2091, 0x8000, 0x6218, 0x2260, 0x6204, 0x0006,
+ 0xa086, 0x0006, 0x1180, 0x609c, 0xd0ac, 0x0168, 0x2001, 0xad52,
+ 0x2004, 0xd0a4, 0x0140, 0xa284, 0xff00, 0x8007, 0xa086, 0x0007,
+ 0x1110, 0x2011, 0x0600, 0x000e, 0xa294, 0xff00, 0xa215, 0x6206,
+ 0x0006, 0xa086, 0x0006, 0x1128, 0x6290, 0x82ff, 0x1110, 0x080c,
+ 0x14f6, 0x000e, 0x00ce, 0x012e, 0x0005, 0x0126, 0x00c6, 0x2091,
+ 0x8000, 0x6218, 0x2260, 0x6204, 0x0006, 0xa086, 0x0006, 0x1178,
+ 0x609c, 0xd0a4, 0x0160, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1138,
+ 0xa284, 0x00ff, 0xa086, 0x0007, 0x1110, 0x2011, 0x0006, 0x000e,
+ 0xa294, 0x00ff, 0x8007, 0xa215, 0x6206, 0x00ce, 0x012e, 0x0005,
+ 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001, 0x00b0, 0xa190,
+ 0xae34, 0x2204, 0xa065, 0x1180, 0x0016, 0x00d6, 0x080c, 0x15c0,
+ 0x2d60, 0x00de, 0x001e, 0x0d80, 0x2c00, 0x2012, 0x60a7, 0x0000,
+ 0x60ab, 0x0000, 0x080c, 0x493a, 0xa006, 0x002e, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0x0026, 0xa182, 0x00ff, 0x0218, 0xa085, 0x0001,
+ 0x0480, 0x00d6, 0xa190, 0xae34, 0x2204, 0xa06d, 0x0540, 0x2013,
+ 0x0000, 0x00d6, 0x00c6, 0x2d60, 0x60a4, 0xa06d, 0x0110, 0x080c,
+ 0x15f0, 0x60a8, 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00ce, 0x00de,
+ 0x00d6, 0x00c6, 0x68ac, 0x2060, 0x8cff, 0x0168, 0x600c, 0x0006,
+ 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x1600, 0x080c,
+ 0x8078, 0x00ce, 0x0c88, 0x00ce, 0x00de, 0x080c, 0x15f0, 0x00de,
+ 0xa006, 0x002e, 0x012e, 0x0005, 0x0016, 0xa182, 0x00ff, 0x0218,
+ 0xa085, 0x0001, 0x0030, 0xa188, 0xae34, 0x2104, 0xa065, 0x0dc0,
+ 0xa006, 0x001e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x600b,
+ 0x0000, 0x600f, 0x0000, 0x6000, 0xc08c, 0x6002, 0x080c, 0x574f,
+ 0x1538, 0x60a0, 0xa086, 0x007e, 0x2069, 0xb290, 0x0130, 0x2001,
+ 0xad34, 0x2004, 0xd0ac, 0x11e0, 0x0098, 0x2d04, 0xd0e4, 0x01c0,
+ 0x00d6, 0x2069, 0xb28e, 0x00c6, 0x2061, 0xaf9f, 0x6810, 0x2062,
+ 0x6814, 0x6006, 0x6818, 0x600a, 0x681c, 0x600e, 0x00ce, 0x00de,
+ 0x8d69, 0x2d04, 0x2069, 0x0140, 0x6886, 0x2069, 0xad00, 0x68a2,
+ 0x2069, 0xb28e, 0x6808, 0x605e, 0x6810, 0x6062, 0x6138, 0xa10a,
+ 0x0208, 0x603a, 0x6814, 0x6066, 0x2099, 0xb296, 0xac88, 0x000a,
+ 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2099, 0xb29a, 0xac88, 0x0006,
+ 0x21a0, 0x20a9, 0x0004, 0x53a3, 0x2069, 0xb2ae, 0x6808, 0x606a,
+ 0x690c, 0x616e, 0x6810, 0x6072, 0x6818, 0x6076, 0xa182, 0x0211,
+ 0x1218, 0x2009, 0x0008, 0x0400, 0xa182, 0x0259, 0x1218, 0x2009,
+ 0x0007, 0x00d0, 0xa182, 0x02c1, 0x1218, 0x2009, 0x0006, 0x00a0,
+ 0xa182, 0x0349, 0x1218, 0x2009, 0x0005, 0x0070, 0xa182, 0x0421,
+ 0x1218, 0x2009, 0x0004, 0x0040, 0xa182, 0x0581, 0x1218, 0x2009,
+ 0x0003, 0x0010, 0x2009, 0x0002, 0x6192, 0x014e, 0x013e, 0x015e,
+ 0x00de, 0x0005, 0x0016, 0x0026, 0x00e6, 0x2071, 0xb28d, 0x2e04,
+ 0x6896, 0x2071, 0xb28e, 0x7004, 0x689a, 0x701c, 0x689e, 0x6a00,
+ 0x2009, 0xad71, 0x210c, 0xd0bc, 0x0120, 0xd1ec, 0x0110, 0xc2ad,
+ 0x0008, 0xc2ac, 0xd0c4, 0x0120, 0xd1e4, 0x0110, 0xc2bd, 0x0008,
+ 0xc2bc, 0x6a02, 0x00ee, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0126,
+ 0x2091, 0x8000, 0x60a4, 0xa06d, 0x01c0, 0x6900, 0x81ff, 0x1540,
+ 0x6a04, 0xa282, 0x0010, 0x1648, 0xad88, 0x0004, 0x20a9, 0x0010,
+ 0x2104, 0xa086, 0xffff, 0x0128, 0x8108, 0x1f04, 0x4da8, 0x080c,
+ 0x14f6, 0x260a, 0x8210, 0x6a06, 0x0098, 0x080c, 0x15d9, 0x01a8,
+ 0x2d00, 0x60a6, 0x6803, 0x0000, 0xad88, 0x0004, 0x20a9, 0x0010,
+ 0x200b, 0xffff, 0x8108, 0x1f04, 0x4dc0, 0x6807, 0x0001, 0x6e12,
+ 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x0126,
+ 0x2091, 0x8000, 0x00d6, 0x60a4, 0xa00d, 0x01a0, 0x2168, 0x6800,
+ 0xa005, 0x1160, 0x080c, 0x4ef9, 0x1168, 0x200b, 0xffff, 0x6804,
+ 0xa08a, 0x0002, 0x0218, 0x8001, 0x6806, 0x0020, 0x080c, 0x15f0,
+ 0x60a7, 0x0000, 0x00de, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x4f56, 0x0010, 0x080c, 0x4bc0, 0x080c, 0x4e71, 0x1dd8,
+ 0x080c, 0x4e3a, 0x012e, 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000,
+ 0x60a8, 0xa06d, 0x01c0, 0x6950, 0x81ff, 0x1540, 0x6a54, 0xa282,
+ 0x0010, 0x1670, 0xad88, 0x0018, 0x20a9, 0x0010, 0x2104, 0xa086,
+ 0xffff, 0x0128, 0x8108, 0x1f04, 0x4e0e, 0x080c, 0x14f6, 0x260a,
+ 0x8210, 0x6a56, 0x0098, 0x080c, 0x15d9, 0x01d0, 0x2d00, 0x60aa,
+ 0x6853, 0x0000, 0xad88, 0x0018, 0x20a9, 0x0010, 0x200b, 0xffff,
+ 0x8108, 0x1f04, 0x4e26, 0x6857, 0x0001, 0x6e62, 0x0010, 0x080c,
+ 0x4c11, 0x0089, 0x1de0, 0xa085, 0x0001, 0x012e, 0x00de, 0x0005,
+ 0xa006, 0x0cd8, 0x0126, 0x2091, 0x8000, 0x080c, 0x67c5, 0x012e,
+ 0x0005, 0xa01e, 0x0010, 0x2019, 0x0001, 0xa00e, 0x0126, 0x2091,
+ 0x8000, 0x604c, 0x2068, 0x6000, 0xd0dc, 0x1170, 0x8dff, 0x01e8,
+ 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406,
+ 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70,
+ 0x6a00, 0x604c, 0xad06, 0x1110, 0x624e, 0x0018, 0xa180, 0x0000,
+ 0x2202, 0x82ff, 0x1110, 0x6152, 0x8dff, 0x012e, 0x0005, 0xa01e,
+ 0x0010, 0x2019, 0x0001, 0xa00e, 0x6080, 0x2068, 0x8dff, 0x01e8,
+ 0x83ff, 0x0120, 0x6848, 0xa606, 0x0158, 0x0030, 0x683c, 0xa406,
+ 0x1118, 0x6840, 0xa506, 0x0120, 0x2d08, 0x6800, 0x2068, 0x0c70,
+ 0x6a00, 0x6080, 0xad06, 0x1110, 0x6282, 0x0018, 0xa180, 0x0000,
+ 0x2202, 0x82ff, 0x1110, 0x6186, 0x8dff, 0x0005, 0xa016, 0x080c,
+ 0x4ef3, 0x1110, 0x2011, 0x0001, 0x080c, 0x4f3d, 0x1110, 0xa295,
+ 0x0002, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x964b, 0x0010,
+ 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c, 0x95e4,
+ 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118, 0x080c,
+ 0x962e, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e, 0x0118,
+ 0x080c, 0x9600, 0x0010, 0xa085, 0x0001, 0x0005, 0x080c, 0x4f6e,
+ 0x0118, 0x080c, 0x9667, 0x0010, 0xa085, 0x0001, 0x0005, 0x0126,
+ 0x0006, 0x00d6, 0x2091, 0x8000, 0x6080, 0xa06d, 0x01a0, 0x6800,
+ 0x0006, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd,
+ 0x0006, 0x6000, 0xd0fc, 0x0110, 0x080c, 0xac03, 0x000e, 0x080c,
+ 0x510c, 0x000e, 0x0c50, 0x6083, 0x0000, 0x6087, 0x0000, 0x00de,
+ 0x000e, 0x012e, 0x0005, 0x60a4, 0xa00d, 0x1118, 0xa085, 0x0001,
+ 0x0005, 0x00e6, 0x2170, 0x7000, 0xa005, 0x1160, 0x20a9, 0x0010,
+ 0xae88, 0x0004, 0x2104, 0xa606, 0x0128, 0x8108, 0x1f04, 0x4f02,
+ 0xa085, 0x0001, 0xa006, 0x00ee, 0x0005, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x60a4, 0xa06d, 0x1128, 0x080c, 0x15d9, 0x01a0, 0x2d00,
+ 0x60a6, 0x6803, 0x0001, 0x6807, 0x0000, 0xad88, 0x0004, 0x20a9,
+ 0x0010, 0x200b, 0xffff, 0x8108, 0x1f04, 0x4f21, 0xa085, 0x0001,
+ 0x012e, 0x00de, 0x0005, 0xa006, 0x0cd8, 0x00d6, 0x0126, 0x2091,
+ 0x8000, 0x60a4, 0xa06d, 0x0130, 0x60a7, 0x0000, 0x080c, 0x15f0,
+ 0xa085, 0x0001, 0x012e, 0x00de, 0x0005, 0x60a8, 0xa00d, 0x1118,
+ 0xa085, 0x0001, 0x0005, 0x00e6, 0x2170, 0x7050, 0xa005, 0x1160,
+ 0x20a9, 0x0010, 0xae88, 0x0018, 0x2104, 0xa606, 0x0128, 0x8108,
+ 0x1f04, 0x4f4c, 0xa085, 0x0001, 0x00ee, 0x0005, 0x0126, 0x2091,
+ 0x8000, 0x0c19, 0x1188, 0x200b, 0xffff, 0x00d6, 0x60a8, 0x2068,
+ 0x6854, 0xa08a, 0x0002, 0x0218, 0x8001, 0x6856, 0x0020, 0x080c,
+ 0x15f0, 0x60ab, 0x0000, 0x00de, 0x012e, 0x0005, 0x609c, 0xd0a4,
+ 0x0005, 0x00f6, 0x080c, 0x574f, 0x01b0, 0x71b4, 0x81ff, 0x1198,
+ 0x71d0, 0xd19c, 0x0180, 0x2001, 0x007e, 0xa080, 0xae34, 0x2004,
+ 0xa07d, 0x0148, 0x7804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x1118,
+ 0x7800, 0xc0ed, 0x7802, 0x2079, 0xad51, 0x7804, 0xd0a4, 0x01e8,
+ 0x0156, 0x00c6, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c,
+ 0x4cdc, 0x1168, 0x6004, 0xa084, 0xff00, 0x8007, 0xa096, 0x0004,
+ 0x0118, 0xa086, 0x0006, 0x1118, 0x6000, 0xc0ed, 0x6002, 0x001e,
+ 0x8108, 0x1f04, 0x4f96, 0x00ce, 0x015e, 0x080c, 0x502d, 0x0120,
+ 0x2001, 0xafa2, 0x200c, 0x0038, 0x2079, 0xad51, 0x7804, 0xd0a4,
+ 0x0130, 0x2009, 0x07d0, 0x2011, 0x4fc1, 0x080c, 0x6593, 0x00fe,
+ 0x0005, 0x2011, 0x4fc1, 0x080c, 0x650d, 0x080c, 0x502d, 0x01f0,
+ 0x2001, 0xaeb2, 0x2004, 0xa080, 0x0000, 0x200c, 0xc1ec, 0x2102,
+ 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0130, 0x2009, 0x07d0, 0x2011,
+ 0x4fc1, 0x080c, 0x6593, 0x00e6, 0x2071, 0xad00, 0x706f, 0x0000,
+ 0x7073, 0x0000, 0x080c, 0x28fa, 0x00ee, 0x04b0, 0x0156, 0x00c6,
+ 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x080c, 0x4cdc, 0x1530,
+ 0x6000, 0xd0ec, 0x0518, 0x0046, 0x62a0, 0xa294, 0x00ff, 0x8227,
+ 0xa006, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6000, 0xc0e5, 0xc0ec,
+ 0x6002, 0x6004, 0xa084, 0x00ff, 0xa085, 0x0700, 0x6006, 0x2019,
+ 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d,
+ 0x2009, 0x0000, 0x080c, 0xa712, 0x007e, 0x004e, 0x001e, 0x8108,
+ 0x1f04, 0x4fec, 0x00ce, 0x015e, 0x0005, 0x00c6, 0x6018, 0x2060,
+ 0x6000, 0xc0ec, 0x6002, 0x00ce, 0x0005, 0x7818, 0x2004, 0xd0ac,
+ 0x0005, 0x7818, 0x2004, 0xd0bc, 0x0005, 0x00f6, 0x2001, 0xaeb2,
+ 0x2004, 0xa07d, 0x0110, 0x7800, 0xd0ec, 0x00fe, 0x0005, 0x0126,
+ 0x0026, 0x2091, 0x8000, 0x6200, 0xa005, 0x0110, 0xc2fd, 0x0008,
+ 0xc2fc, 0x6202, 0x002e, 0x012e, 0x0005, 0x2071, 0xae13, 0x7003,
+ 0x0001, 0x7007, 0x0000, 0x7013, 0x0000, 0x7017, 0x0000, 0x701b,
+ 0x0000, 0x701f, 0x0000, 0x700b, 0x0000, 0x704b, 0x0001, 0x704f,
+ 0x0000, 0x705b, 0x0020, 0x705f, 0x0040, 0x707f, 0x0000, 0x2071,
+ 0xaf7c, 0x7003, 0xae13, 0x7007, 0x0000, 0x700b, 0x0000, 0x700f,
+ 0xaf5c, 0x7013, 0x0020, 0x7017, 0x0040, 0x7037, 0x0000, 0x0005,
+ 0x0016, 0x00e6, 0x2071, 0xaf34, 0xa00e, 0x7186, 0x718a, 0x7097,
+ 0x0001, 0x2001, 0xad52, 0x2004, 0xd0fc, 0x1150, 0x2001, 0xad52,
+ 0x2004, 0xa00e, 0xd09c, 0x0108, 0x8108, 0x7102, 0x0804, 0x50d6,
+ 0x2001, 0xad71, 0x200c, 0xa184, 0x000f, 0x2009, 0xad72, 0x210c,
+ 0x0002, 0x507e, 0x50b1, 0x50b8, 0x50c2, 0x50c7, 0x507e, 0x507e,
+ 0x507e, 0x50a1, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e, 0x507e,
+ 0x507e, 0x7003, 0x0004, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+ 0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+ 0x0428, 0x708f, 0x0005, 0x7007, 0x0122, 0x2001, 0x0002, 0x0030,
+ 0x708f, 0x0002, 0x7007, 0x0121, 0x2001, 0x0003, 0x7002, 0x7097,
+ 0x0001, 0x0088, 0x7007, 0x0122, 0x2001, 0x0002, 0x0020, 0x7007,
+ 0x0121, 0x2001, 0x0003, 0x7002, 0xa006, 0x7096, 0x708e, 0xa184,
+ 0xff00, 0x8007, 0x709a, 0xa184, 0x00ff, 0x7092, 0x00ee, 0x001e,
+ 0x0005, 0x00e6, 0x2071, 0xae13, 0x684c, 0xa005, 0x1130, 0x7028,
+ 0xc085, 0x702a, 0xa085, 0x0001, 0x0428, 0x6a60, 0x7236, 0x6b64,
+ 0x733a, 0x6868, 0x703e, 0x7076, 0x686c, 0x7042, 0x707a, 0x684c,
+ 0x702e, 0x6844, 0x7032, 0x2009, 0x000d, 0x200a, 0x700b, 0x0000,
+ 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0, 0xa210,
+ 0x2100, 0xa319, 0x726e, 0x7372, 0x7028, 0xc084, 0x702a, 0x7007,
+ 0x0001, 0xa006, 0x00ee, 0x0005, 0x0156, 0x00e6, 0x0026, 0x6838,
+ 0xd0fc, 0x1904, 0x5165, 0x6804, 0xa00d, 0x0188, 0x00d6, 0x2071,
+ 0xad00, 0xa016, 0x702c, 0x2168, 0x6904, 0x206a, 0x8210, 0x2d00,
+ 0x81ff, 0x1dc8, 0x702e, 0x70b0, 0xa200, 0x70b2, 0x00de, 0x2071,
+ 0xae13, 0x701c, 0xa005, 0x1904, 0x5175, 0x20a9, 0x0032, 0x0f04,
+ 0x5173, 0x0e04, 0x512f, 0x2071, 0xaf34, 0x7200, 0x82ff, 0x05d8,
+ 0x6934, 0xa186, 0x0103, 0x1904, 0x5183, 0x6948, 0x6844, 0xa105,
+ 0x1540, 0x2009, 0x8020, 0x2200, 0x0002, 0x5173, 0x514a, 0x519b,
+ 0x51a7, 0x5173, 0x2071, 0x0000, 0x20a9, 0x0032, 0x0f04, 0x5173,
+ 0x7018, 0xd084, 0x1dd8, 0x7122, 0x683c, 0x7026, 0x6840, 0x702a,
+ 0x701b, 0x0001, 0x2091, 0x4080, 0x2071, 0xad00, 0x702c, 0x206a,
+ 0x2d00, 0x702e, 0x70b0, 0x8000, 0x70b2, 0x002e, 0x00ee, 0x015e,
+ 0x0005, 0x6844, 0xa086, 0x0100, 0x1130, 0x6868, 0xa005, 0x1118,
+ 0x2009, 0x8020, 0x0880, 0x2071, 0xae13, 0x2d08, 0x206b, 0x0000,
+ 0x7010, 0x8000, 0x7012, 0x7018, 0xa06d, 0x711a, 0x0110, 0x6902,
+ 0x0008, 0x711e, 0x0c10, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130,
+ 0xa186, 0x001e, 0x0118, 0xa18e, 0x001f, 0x1d28, 0x684c, 0xd0cc,
+ 0x0d10, 0x6850, 0xa084, 0x00ff, 0xa086, 0x0001, 0x19e0, 0x2009,
+ 0x8021, 0x0804, 0x5143, 0x7084, 0x8008, 0xa092, 0x001e, 0x1a98,
+ 0x7186, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x0078, 0x7084,
+ 0x8008, 0xa092, 0x000f, 0x1a38, 0x7186, 0xae90, 0x0003, 0x8003,
+ 0xa210, 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7088, 0xa10a,
+ 0x0a04, 0x515c, 0x718c, 0x7084, 0xa10a, 0x0a04, 0x515c, 0x2071,
+ 0x0000, 0x7018, 0xd084, 0x1904, 0x515c, 0x2071, 0xaf34, 0x7000,
+ 0xa086, 0x0002, 0x1150, 0x080c, 0x5426, 0x2071, 0x0000, 0x701b,
+ 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x080c, 0x5450, 0x2071,
+ 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0804, 0x515c, 0x0006,
+ 0x684c, 0x0006, 0x6837, 0x0103, 0x20a9, 0x001c, 0xad80, 0x0011,
+ 0x20a0, 0x2001, 0x0000, 0x40a4, 0x000e, 0xa084, 0x00ff, 0x684e,
+ 0x000e, 0x684a, 0x6952, 0x0005, 0x2071, 0xae13, 0x7004, 0x0002,
+ 0x5202, 0x5213, 0x5411, 0x5412, 0x541f, 0x5425, 0x5203, 0x5402,
+ 0x5398, 0x53ee, 0x0005, 0x0126, 0x2091, 0x8000, 0x0e04, 0x5212,
+ 0x2009, 0x000d, 0x7030, 0x200a, 0x2091, 0x4080, 0x7007, 0x0001,
+ 0x700b, 0x0000, 0x012e, 0x2069, 0xafda, 0x683c, 0xa005, 0x03f8,
+ 0x11f0, 0x0126, 0x2091, 0x8000, 0x2069, 0x0000, 0x6934, 0x2001,
+ 0xae1f, 0x2004, 0xa10a, 0x0170, 0x0e04, 0x5236, 0x2069, 0x0000,
+ 0x6818, 0xd084, 0x1158, 0x2009, 0x8040, 0x6922, 0x681b, 0x0001,
+ 0x2091, 0x4080, 0x2069, 0xafda, 0x683f, 0xffff, 0x012e, 0x2069,
+ 0xad00, 0x6844, 0x6964, 0xa102, 0x2069, 0xaf34, 0x688a, 0x6984,
+ 0x701c, 0xa06d, 0x0120, 0x81ff, 0x0904, 0x528c, 0x00a0, 0x81ff,
+ 0x0904, 0x5352, 0x2071, 0xaf34, 0x7184, 0x7088, 0xa10a, 0x1258,
+ 0x7190, 0x2071, 0xafda, 0x7038, 0xa005, 0x0128, 0x1b04, 0x5352,
+ 0x713a, 0x0804, 0x5352, 0x2071, 0xaf34, 0x718c, 0x0126, 0x2091,
+ 0x8000, 0x7084, 0xa10a, 0x0a04, 0x536d, 0x0e04, 0x530e, 0x2071,
+ 0x0000, 0x7018, 0xd084, 0x1904, 0x530e, 0x2001, 0xffff, 0x2071,
+ 0xafda, 0x703a, 0x2071, 0xaf34, 0x7000, 0xa086, 0x0002, 0x1150,
+ 0x080c, 0x5426, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+ 0x0804, 0x530e, 0x080c, 0x5450, 0x2071, 0x0000, 0x701b, 0x0001,
+ 0x2091, 0x4080, 0x0804, 0x530e, 0x2071, 0xaf34, 0x7000, 0xa005,
+ 0x0904, 0x5334, 0x6934, 0xa186, 0x0103, 0x1904, 0x5311, 0x684c,
+ 0xd0bc, 0x1904, 0x5334, 0x6948, 0x6844, 0xa105, 0x1904, 0x5329,
+ 0x2009, 0x8020, 0x2071, 0xaf34, 0x7000, 0x0002, 0x5334, 0x52f4,
+ 0x52cc, 0x52de, 0x52ab, 0x0136, 0x0146, 0x0156, 0x2099, 0xad75,
+ 0x20a1, 0xaf85, 0x20a9, 0x0004, 0x53a3, 0x015e, 0x014e, 0x013e,
+ 0x2071, 0xaf7c, 0xad80, 0x000f, 0x700e, 0x7013, 0x0002, 0x7007,
+ 0x0002, 0x700b, 0x0000, 0x2e10, 0x080c, 0x1624, 0x2071, 0xae13,
+ 0x7007, 0x0009, 0x0804, 0x5352, 0x7084, 0x8008, 0xa092, 0x001e,
+ 0x1a04, 0x5352, 0xae90, 0x0003, 0xa210, 0x683c, 0x2012, 0x7186,
+ 0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x7084, 0x8008,
+ 0xa092, 0x000f, 0x1a04, 0x5352, 0xae90, 0x0003, 0x8003, 0xa210,
+ 0x683c, 0x2012, 0x8210, 0x6840, 0x2012, 0x7186, 0x2071, 0xae13,
+ 0x080c, 0x54a7, 0x0804, 0x5352, 0x0126, 0x2091, 0x8000, 0x0e04,
+ 0x530e, 0x2071, 0x0000, 0x7018, 0xd084, 0x1180, 0x7122, 0x683c,
+ 0x7026, 0x6840, 0x702a, 0x701b, 0x0001, 0x2091, 0x4080, 0x012e,
+ 0x2071, 0xae13, 0x080c, 0x54a7, 0x0804, 0x5352, 0x012e, 0x0804,
+ 0x5352, 0xa18c, 0x00ff, 0xa186, 0x0017, 0x0130, 0xa186, 0x001e,
+ 0x0118, 0xa18e, 0x001f, 0x11c0, 0x684c, 0xd0cc, 0x01a8, 0x6850,
+ 0xa084, 0x00ff, 0xa086, 0x0001, 0x1178, 0x2009, 0x8021, 0x0804,
+ 0x52a2, 0x6844, 0xa086, 0x0100, 0x1138, 0x6868, 0xa005, 0x1120,
+ 0x2009, 0x8020, 0x0804, 0x52a2, 0x2071, 0xae13, 0x080c, 0x54b9,
+ 0x01c8, 0x2071, 0xae13, 0x700f, 0x0001, 0x6934, 0xa184, 0x00ff,
+ 0xa086, 0x0003, 0x1130, 0x810f, 0xa18c, 0x00ff, 0x8101, 0x0108,
+ 0x710e, 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100,
+ 0x0904, 0x5412, 0x0126, 0x2091, 0x8000, 0x2071, 0xae13, 0x7008,
+ 0xa086, 0x0001, 0x1180, 0x0e04, 0x536b, 0x2009, 0x000d, 0x7030,
+ 0x200a, 0x2091, 0x4080, 0x700b, 0x0000, 0x7004, 0xa086, 0x0006,
+ 0x1110, 0x7007, 0x0001, 0x012e, 0x0005, 0x2071, 0xae13, 0x080c,
+ 0x54b9, 0x0518, 0x2071, 0xaf34, 0x7084, 0x700a, 0x20a9, 0x0020,
+ 0x2099, 0xaf35, 0x20a1, 0xaf5c, 0x53a3, 0x7087, 0x0000, 0x2071,
+ 0xae13, 0x2069, 0xaf7c, 0x706c, 0x6826, 0x7070, 0x682a, 0x7074,
+ 0x682e, 0x7078, 0x6832, 0x2d10, 0x080c, 0x1624, 0x7007, 0x0008,
+ 0x2001, 0xffff, 0x2071, 0xafda, 0x703a, 0x012e, 0x0804, 0x5352,
+ 0x2069, 0xaf7c, 0x6808, 0xa08e, 0x0000, 0x0904, 0x53ed, 0xa08e,
+ 0x0200, 0x0904, 0x53eb, 0xa08e, 0x0100, 0x1904, 0x53ed, 0x0126,
+ 0x2091, 0x8000, 0x0e04, 0x53e9, 0x2069, 0x0000, 0x6818, 0xd084,
+ 0x15c0, 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034,
+ 0x706e, 0x7038, 0x7072, 0x0048, 0x706c, 0xa080, 0x0040, 0x706e,
+ 0x1220, 0x7070, 0xa081, 0x0000, 0x7072, 0x7132, 0x6936, 0x700b,
+ 0x0000, 0x2001, 0xaf59, 0x2004, 0xa005, 0x1190, 0x6934, 0x2069,
+ 0xaf34, 0x689c, 0x699e, 0x2069, 0xafda, 0xa102, 0x1118, 0x683c,
+ 0xa005, 0x1368, 0x2001, 0xaf5a, 0x200c, 0x810d, 0x693e, 0x0038,
+ 0x2009, 0x8040, 0x6922, 0x681b, 0x0001, 0x2091, 0x4080, 0x7007,
+ 0x0001, 0x012e, 0x0010, 0x7007, 0x0005, 0x0005, 0x2001, 0xaf7e,
+ 0x2004, 0xa08e, 0x0100, 0x1128, 0x7007, 0x0001, 0x080c, 0x54a7,
+ 0x0005, 0xa08e, 0x0000, 0x0de0, 0xa08e, 0x0200, 0x1dc8, 0x7007,
+ 0x0005, 0x0005, 0x701c, 0xa06d, 0x0158, 0x080c, 0x54b9, 0x0140,
+ 0x7007, 0x0003, 0x080c, 0x54d2, 0x7050, 0xa086, 0x0100, 0x0110,
+ 0x0005, 0x0005, 0x7050, 0xa09e, 0x0100, 0x1118, 0x7007, 0x0004,
+ 0x0030, 0xa086, 0x0200, 0x1110, 0x7007, 0x0005, 0x0005, 0x080c,
+ 0x5475, 0x7006, 0x080c, 0x54a7, 0x0005, 0x0005, 0x00e6, 0x0156,
+ 0x2071, 0xaf34, 0x7184, 0x81ff, 0x0500, 0xa006, 0x7086, 0xae80,
+ 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226, 0x8000, 0x0f04,
+ 0x544a, 0x2014, 0x722a, 0x8000, 0x0f04, 0x544a, 0x2014, 0x722e,
+ 0x8000, 0x0f04, 0x544a, 0x2014, 0x723a, 0x8000, 0x0f04, 0x544a,
+ 0x2014, 0x723e, 0xa180, 0x8030, 0x7022, 0x015e, 0x00ee, 0x0005,
+ 0x00e6, 0x0156, 0x2071, 0xaf34, 0x7184, 0x81ff, 0x01d8, 0xa006,
+ 0x7086, 0xae80, 0x0003, 0x2071, 0x0000, 0x21a8, 0x2014, 0x7226,
+ 0x8000, 0x2014, 0x722a, 0x8000, 0x0f04, 0x546c, 0x2014, 0x723a,
+ 0x8000, 0x2014, 0x723e, 0x0018, 0x2001, 0x8020, 0x0010, 0x2001,
+ 0x8042, 0x7022, 0x015e, 0x00ee, 0x0005, 0x702c, 0x7130, 0x8108,
+ 0xa102, 0x0230, 0xa00e, 0x7034, 0x706e, 0x7038, 0x7072, 0x0048,
+ 0x706c, 0xa080, 0x0040, 0x706e, 0x1220, 0x7070, 0xa081, 0x0000,
+ 0x7072, 0x7132, 0x700c, 0x8001, 0x700e, 0x1180, 0x0126, 0x2091,
+ 0x8000, 0x0e04, 0x54a1, 0x2001, 0x000d, 0x2102, 0x2091, 0x4080,
+ 0x2001, 0x0001, 0x700b, 0x0000, 0x012e, 0x0005, 0x2001, 0x0007,
+ 0x0005, 0x2001, 0x0006, 0x700b, 0x0001, 0x012e, 0x0005, 0x701c,
+ 0xa06d, 0x0170, 0x0126, 0x2091, 0x8000, 0x7010, 0x8001, 0x7012,
+ 0x2d04, 0x701e, 0xa005, 0x1108, 0x701a, 0x012e, 0x080c, 0x15f0,
+ 0x0005, 0x2019, 0x000d, 0x2304, 0x230c, 0xa10e, 0x0130, 0x2304,
+ 0x230c, 0xa10e, 0x0110, 0xa006, 0x0060, 0x732c, 0x8319, 0x7130,
+ 0xa102, 0x1118, 0x2300, 0xa005, 0x0020, 0x0210, 0xa302, 0x0008,
+ 0x8002, 0x0005, 0x2d00, 0x7026, 0xa080, 0x000d, 0x7056, 0x7053,
+ 0x0000, 0x0126, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc08d,
+ 0x200a, 0x012e, 0x080c, 0x163c, 0x0005, 0x7088, 0xa08a, 0x0029,
+ 0x1220, 0xa082, 0x001d, 0x0033, 0x0010, 0x080c, 0x14f6, 0x6027,
+ 0x1e00, 0x0005, 0x55c1, 0x555b, 0x5571, 0x5595, 0x55b4, 0x55e6,
+ 0x55f8, 0x5571, 0x55d2, 0x54ff, 0x552d, 0x54fe, 0x0005, 0x00d6,
+ 0x2069, 0x0200, 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518,
+ 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x584d,
+ 0x6028, 0xa085, 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069,
+ 0xafac, 0x2d04, 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6,
+ 0x0036, 0x0046, 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e,
+ 0x004e, 0x003e, 0x00ee, 0x00de, 0x0005, 0x00d6, 0x2069, 0x0200,
+ 0x6804, 0xa005, 0x1180, 0x6808, 0xa005, 0x1518, 0x708b, 0x0028,
+ 0x2069, 0xafac, 0x2d04, 0x7002, 0x080c, 0x58da, 0x6028, 0xa085,
+ 0x0600, 0x602a, 0x00b0, 0x708b, 0x0028, 0x2069, 0xafac, 0x2d04,
+ 0x7002, 0x6028, 0xa085, 0x0600, 0x602a, 0x00e6, 0x0036, 0x0046,
+ 0x0056, 0x2071, 0xaffd, 0x080c, 0x1d22, 0x005e, 0x004e, 0x003e,
+ 0x00ee, 0x00de, 0x0005, 0x6803, 0x0090, 0x6124, 0xd1e4, 0x1180,
+ 0x080c, 0x5663, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1cc, 0x0140,
+ 0x708b, 0x0020, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f,
+ 0x0005, 0x6803, 0x0088, 0x6124, 0xd1cc, 0x11c8, 0xd1dc, 0x11a0,
+ 0xd1e4, 0x1178, 0xa184, 0x1e00, 0x11b8, 0x60e3, 0x0001, 0x600c,
+ 0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x708b, 0x0028,
+ 0x0058, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d, 0x0028, 0x708b,
+ 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x60e3, 0x0001, 0x600c,
+ 0xc0b4, 0x600e, 0x080c, 0x577f, 0x6803, 0x0080, 0x6124, 0xd1d4,
+ 0x1180, 0xd1dc, 0x1158, 0xd1e4, 0x1130, 0xa184, 0x1e00, 0x1158,
+ 0x708b, 0x0028, 0x0040, 0x708b, 0x001e, 0x0028, 0x708b, 0x001d,
+ 0x0010, 0x708b, 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1dc,
+ 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b, 0x001d,
+ 0x0005, 0x080c, 0x568d, 0x6124, 0xd1dc, 0x1158, 0x080c, 0x5663,
+ 0xd1d4, 0x1128, 0xd1e4, 0x0128, 0x708b, 0x001e, 0x0010, 0x708b,
+ 0x001f, 0x0005, 0x6803, 0x00a0, 0x6124, 0xd1d4, 0x1160, 0xd1cc,
+ 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b, 0x001e, 0x0028,
+ 0x708b, 0x001d, 0x0010, 0x708b, 0x0021, 0x0005, 0x080c, 0x568d,
+ 0x6124, 0xd1d4, 0x1150, 0xd1dc, 0x1128, 0xd1e4, 0x0140, 0x708b,
+ 0x001e, 0x0028, 0x708b, 0x001d, 0x0010, 0x708b, 0x001f, 0x0005,
+ 0x6803, 0x0090, 0x6124, 0xd1d4, 0x1178, 0xd1cc, 0x1150, 0xd1dc,
+ 0x1128, 0xd1e4, 0x0158, 0x708b, 0x001e, 0x0040, 0x708b, 0x001d,
+ 0x0028, 0x708b, 0x0020, 0x0010, 0x708b, 0x001f, 0x0005, 0x0016,
+ 0x00c6, 0x00d6, 0x00e6, 0x0126, 0x2061, 0x0100, 0x2069, 0x0140,
+ 0x2071, 0xad00, 0x2091, 0x8000, 0x080c, 0x574f, 0x11e8, 0x2001,
+ 0xad0c, 0x200c, 0xd1b4, 0x01c0, 0xc1b4, 0x2102, 0x6027, 0x0200,
+ 0xe000, 0xe000, 0x6024, 0xd0cc, 0x0158, 0x6803, 0x00a0, 0x2001,
+ 0xaf9e, 0x2003, 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0428,
+ 0x6028, 0xc0cd, 0x602a, 0x0408, 0x080c, 0x576b, 0x0150, 0x080c,
+ 0x5761, 0x1138, 0x2001, 0x0001, 0x080c, 0x261e, 0x080c, 0x5726,
+ 0x00a0, 0x080c, 0x568a, 0x0178, 0x2001, 0x0001, 0x080c, 0x261e,
+ 0x7088, 0xa086, 0x001e, 0x0120, 0x7088, 0xa086, 0x0022, 0x1118,
+ 0x708b, 0x0025, 0x0010, 0x708b, 0x0021, 0x012e, 0x00ee, 0x00de,
+ 0x00ce, 0x001e, 0x0005, 0x0016, 0x0026, 0x2009, 0x0064, 0x2011,
+ 0x566e, 0x080c, 0x6501, 0x002e, 0x001e, 0x0005, 0x00e6, 0x00f6,
+ 0x0016, 0x080c, 0x7834, 0x2071, 0xad00, 0x080c, 0x560f, 0x001e,
+ 0x00fe, 0x00ee, 0x0005, 0x2001, 0xad00, 0x2004, 0xa086, 0x0004,
+ 0x0140, 0x2001, 0xaf9d, 0x2003, 0xaaaa, 0x2001, 0xaf9e, 0x2003,
+ 0x0000, 0x0005, 0x6020, 0xd09c, 0x0005, 0x6803, 0x00c0, 0x0156,
+ 0x20a9, 0x002d, 0x1d04, 0x5692, 0x2091, 0x6000, 0x1f04, 0x5692,
+ 0x015e, 0x0005, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x2071, 0xad00, 0x2001, 0xaf9e, 0x200c, 0xa186, 0x0000,
+ 0x0158, 0xa186, 0x0001, 0x0158, 0xa186, 0x0002, 0x0158, 0xa186,
+ 0x0003, 0x0158, 0x0804, 0x5714, 0x708b, 0x0022, 0x0040, 0x708b,
+ 0x0021, 0x0028, 0x708b, 0x0023, 0x0020, 0x708b, 0x0024, 0x6043,
+ 0x0000, 0x60e3, 0x0000, 0x6887, 0x0001, 0x2001, 0x0001, 0x080c,
+ 0x26cb, 0x0026, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002,
+ 0x080c, 0x7ae9, 0x002e, 0x7000, 0xa08e, 0x0004, 0x0118, 0x602b,
+ 0x0028, 0x0010, 0x602b, 0x0020, 0x0156, 0x0126, 0x2091, 0x8000,
+ 0x20a9, 0x0005, 0x6024, 0xd0ac, 0x0118, 0x012e, 0x015e, 0x04d0,
+ 0x6800, 0xa084, 0x00a0, 0xc0bd, 0x6802, 0x6904, 0xd1d4, 0x1130,
+ 0x6803, 0x0100, 0x1f04, 0x56e2, 0x080c, 0x57a0, 0x012e, 0x015e,
+ 0x080c, 0x5761, 0x01a8, 0x6044, 0xa005, 0x0168, 0x6050, 0x0006,
+ 0xa085, 0x0020, 0x6052, 0x080c, 0x57a0, 0xa006, 0x8001, 0x1df0,
+ 0x000e, 0x6052, 0x0028, 0x6804, 0xd0d4, 0x1110, 0x080c, 0x57a0,
+ 0x2001, 0xaf9e, 0x2003, 0x0004, 0x080c, 0x54e5, 0x080c, 0x5761,
+ 0x0148, 0x6804, 0xd0d4, 0x1130, 0xd0dc, 0x1100, 0x2001, 0xaf9e,
+ 0x2003, 0x0000, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+ 0x00e6, 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x2001,
+ 0xaf9d, 0x2003, 0x0000, 0x2001, 0xaf8e, 0x2003, 0x0000, 0x708b,
+ 0x0000, 0x60e3, 0x0000, 0x6887, 0x0000, 0x2001, 0x0000, 0x080c,
+ 0x26cb, 0x6803, 0x0000, 0x6043, 0x0090, 0x6043, 0x0010, 0x6027,
+ 0xffff, 0x602b, 0x182f, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0006,
+ 0x2001, 0xaf9d, 0x2004, 0xa086, 0xaaaa, 0x000e, 0x0005, 0x0006,
+ 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086, 0x0000, 0x000e,
+ 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084, 0x0030, 0xa086,
+ 0x0030, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71, 0x2004, 0xa084,
+ 0x0030, 0xa086, 0x0010, 0x000e, 0x0005, 0x0006, 0x2001, 0xad71,
+ 0x2004, 0xa084, 0x0030, 0xa086, 0x0020, 0x000e, 0x0005, 0x2001,
+ 0xad0c, 0x2004, 0xd0a4, 0x0170, 0x080c, 0x26eb, 0x0036, 0x0016,
+ 0x2009, 0x0000, 0x2019, 0x0028, 0x080c, 0x2aac, 0x001e, 0x003e,
+ 0xa006, 0x0009, 0x0005, 0x00e6, 0x2071, 0xad0c, 0x2e04, 0x0118,
+ 0xa085, 0x0010, 0x0010, 0xa084, 0xffef, 0x2072, 0x00ee, 0x0005,
+ 0x6050, 0x0006, 0x60f0, 0x0006, 0x60ec, 0x0006, 0x600c, 0x0006,
+ 0x6004, 0x0006, 0x6028, 0x0006, 0x602f, 0x0100, 0x602f, 0x0000,
+ 0x602f, 0x0040, 0x602f, 0x0000, 0x000e, 0x602a, 0x000e, 0x6006,
+ 0x000e, 0x600e, 0x000e, 0x60ee, 0x000e, 0x60f2, 0x60e3, 0x0000,
+ 0x6887, 0x0001, 0x2001, 0x0001, 0x080c, 0x26cb, 0x6800, 0xa084,
+ 0x00a0, 0xc0bd, 0x6802, 0x6803, 0x00a0, 0x000e, 0x6052, 0x6050,
+ 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6, 0x00e6,
+ 0x2061, 0x0100, 0x2069, 0x0140, 0x2071, 0xad00, 0x6020, 0xa084,
+ 0x0080, 0x0138, 0x2001, 0xad0c, 0x200c, 0xc1bd, 0x2102, 0x0804,
+ 0x5845, 0x2001, 0xad0c, 0x200c, 0xc1bc, 0x2102, 0x6028, 0xa084,
+ 0xe1ff, 0x602a, 0x6027, 0x0200, 0x6803, 0x0090, 0x20a9, 0x0384,
+ 0x6024, 0xd0cc, 0x1518, 0x1d04, 0x57f8, 0x2091, 0x6000, 0x1f04,
+ 0x57f8, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+ 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+ 0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+ 0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x0438, 0x60e3, 0x0000,
+ 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x6803, 0x0080,
+ 0x20a9, 0x0384, 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024,
+ 0xa10c, 0x0138, 0x1d04, 0x582a, 0x2091, 0x6000, 0x1f04, 0x582a,
+ 0x0840, 0x6028, 0xa085, 0x1e00, 0x602a, 0x70a0, 0xa005, 0x1118,
+ 0x6887, 0x0001, 0x0008, 0x6886, 0xa006, 0x00ee, 0x00de, 0x00ce,
+ 0x003e, 0x002e, 0x001e, 0x015e, 0x0005, 0x0156, 0x0016, 0x0026,
+ 0x0036, 0x00c6, 0x00d6, 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00,
+ 0x2069, 0x0140, 0x6020, 0xa084, 0x00c0, 0x0120, 0x6884, 0xa005,
+ 0x1904, 0x58a1, 0x6803, 0x0088, 0x60e3, 0x0000, 0x6887, 0x0000,
+ 0x2001, 0x0000, 0x080c, 0x26cb, 0x2069, 0x0200, 0x6804, 0xa005,
+ 0x1118, 0x6808, 0xa005, 0x01c0, 0x6028, 0xa084, 0xfbff, 0x602a,
+ 0x6027, 0x0400, 0x2069, 0xafac, 0x7000, 0x206a, 0x708b, 0x0026,
+ 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x5884, 0x2091, 0x6000,
+ 0x1f04, 0x5884, 0x0804, 0x58d2, 0x2069, 0x0140, 0x20a9, 0x0384,
+ 0x6027, 0x1e00, 0x2009, 0x1e00, 0xe000, 0x6024, 0xa10c, 0x0530,
+ 0xa084, 0x1a00, 0x1518, 0x1d04, 0x5890, 0x2091, 0x6000, 0x1f04,
+ 0x5890, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+ 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+ 0x7a64, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003, 0x0001, 0x2001,
+ 0xad00, 0x2003, 0x0001, 0xa085, 0x0001, 0x00a0, 0x6803, 0x0080,
+ 0x2069, 0x0140, 0x60e3, 0x0000, 0x70a0, 0xa005, 0x1118, 0x6887,
+ 0x0001, 0x0008, 0x6886, 0x2001, 0xaf8e, 0x2004, 0x080c, 0x26cb,
+ 0x60e2, 0xa006, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+ 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x00c6, 0x00d6,
+ 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x6020, 0xa084, 0x00c0,
+ 0x01f0, 0x2011, 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c,
+ 0x7ae9, 0x080c, 0x79e1, 0x080c, 0x6581, 0x2019, 0x0000, 0x080c,
+ 0x7a64, 0x2069, 0x0140, 0x6803, 0x00a0, 0x2001, 0xaf9e, 0x2003,
+ 0x0001, 0x2001, 0xad00, 0x2003, 0x0001, 0x0804, 0x5972, 0x2001,
+ 0xad0c, 0x200c, 0xd1b4, 0x1150, 0xc1b5, 0x2102, 0x080c, 0x5663,
+ 0x2069, 0x0140, 0x6803, 0x0080, 0x60e3, 0x0000, 0x2069, 0x0200,
+ 0x6804, 0xa005, 0x1118, 0x6808, 0xa005, 0x01b8, 0x6028, 0xa084,
+ 0xfdff, 0x602a, 0x6027, 0x0200, 0x2069, 0xafac, 0x7000, 0x206a,
+ 0x708b, 0x0027, 0x7003, 0x0001, 0x20a9, 0x0002, 0x1d04, 0x592e,
+ 0x2091, 0x6000, 0x1f04, 0x592e, 0x04e8, 0x6027, 0x1e00, 0x2009,
+ 0x1e00, 0xe000, 0x6024, 0xa10c, 0x01c8, 0xa084, 0x1c00, 0x11b0,
+ 0x1d04, 0x5935, 0x0006, 0x0016, 0x00c6, 0x00d6, 0x00e6, 0x080c,
+ 0x64a2, 0x00ee, 0x00de, 0x00ce, 0x001e, 0x000e, 0x00e6, 0x2071,
+ 0xafda, 0x7018, 0x00ee, 0xa005, 0x1d00, 0x01e0, 0x0026, 0x2011,
+ 0x566e, 0x080c, 0x650d, 0x002e, 0x2069, 0x0140, 0x60e3, 0x0000,
+ 0x70a0, 0xa005, 0x1118, 0x6887, 0x0001, 0x0008, 0x6886, 0x2001,
+ 0xaf8e, 0x2004, 0x080c, 0x26cb, 0x60e2, 0x2001, 0xad0c, 0x200c,
+ 0xc1b4, 0x2102, 0x00ee, 0x00de, 0x00ce, 0x003e, 0x002e, 0x001e,
+ 0x015e, 0x0005, 0x0156, 0x0016, 0x0026, 0x0036, 0x0046, 0x00c6,
+ 0x00e6, 0x2061, 0x0100, 0x2071, 0xad00, 0x7130, 0xd184, 0x1180,
+ 0x2011, 0xad52, 0x2214, 0xd2ec, 0x0138, 0xc18d, 0x7132, 0x2011,
+ 0xad52, 0x2214, 0xd2ac, 0x1120, 0x7030, 0xd08c, 0x0904, 0x59df,
+ 0x7130, 0xc185, 0x7132, 0x2011, 0xad52, 0x220c, 0xd1a4, 0x0530,
+ 0x0016, 0x2009, 0x0001, 0x2011, 0x0100, 0x080c, 0x663f, 0x2019,
+ 0x000e, 0x080c, 0xa8eb, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000,
+ 0xa186, 0x007e, 0x0170, 0xa186, 0x0080, 0x0158, 0x080c, 0x4cdc,
+ 0x1140, 0x8127, 0xa006, 0x0016, 0x2009, 0x000e, 0x080c, 0xa96c,
+ 0x001e, 0x8108, 0x1f04, 0x59b0, 0x015e, 0x001e, 0xd1ac, 0x1148,
+ 0x0016, 0x2009, 0x0000, 0x2019, 0x0004, 0x080c, 0x2aac, 0x001e,
+ 0x0070, 0x0156, 0x20a9, 0x007f, 0x2009, 0x0000, 0x080c, 0x4cdc,
+ 0x1110, 0x080c, 0x493a, 0x8108, 0x1f04, 0x59d6, 0x015e, 0x2011,
+ 0x0003, 0x080c, 0x7adf, 0x2011, 0x0002, 0x080c, 0x7ae9, 0x080c,
+ 0x79e1, 0x080c, 0x6581, 0x0036, 0x2019, 0x0000, 0x080c, 0x7a64,
+ 0x003e, 0x60e3, 0x0000, 0x2001, 0xad00, 0x2003, 0x0001, 0x080c,
+ 0x569a, 0x00ee, 0x00ce, 0x004e, 0x003e, 0x002e, 0x001e, 0x015e,
+ 0x0005, 0x2071, 0xade1, 0x7003, 0x0000, 0x7007, 0x0000, 0x700f,
+ 0x0000, 0x702b, 0x0001, 0x704f, 0x0000, 0x7053, 0x0001, 0x705f,
+ 0x0020, 0x7063, 0x0040, 0x7083, 0x0000, 0x708b, 0x0000, 0x708f,
+ 0x0001, 0x70bf, 0x0000, 0x0005, 0x00e6, 0x2071, 0xade1, 0x6848,
+ 0xa005, 0x1130, 0x7028, 0xc085, 0x702a, 0xa085, 0x0001, 0x0428,
+ 0x6a50, 0x7236, 0x6b54, 0x733a, 0x6858, 0x703e, 0x707a, 0x685c,
+ 0x7042, 0x707e, 0x6848, 0x702e, 0x6840, 0x7032, 0x2009, 0x000c,
+ 0x200a, 0x8007, 0x8006, 0x8006, 0xa08c, 0x003f, 0xa084, 0xffc0,
+ 0xa210, 0x2100, 0xa319, 0x7272, 0x7376, 0x7028, 0xc084, 0x702a,
+ 0x7007, 0x0001, 0x700f, 0x0000, 0xa006, 0x00ee, 0x0005, 0x2b78,
+ 0x2071, 0xade1, 0x7004, 0x0043, 0x700c, 0x0002, 0x5a5b, 0x5a52,
+ 0x5a52, 0x5a52, 0x5a52, 0x0005, 0x5ab1, 0x5ab2, 0x5ae4, 0x5ae5,
+ 0x5aaf, 0x5b33, 0x5b38, 0x5b69, 0x5b6a, 0x5b85, 0x5b86, 0x5b87,
+ 0x5b88, 0x5b89, 0x5b8a, 0x5c40, 0x5c67, 0x700c, 0x0002, 0x5a74,
+ 0x5aaf, 0x5aaf, 0x5ab0, 0x5ab0, 0x7830, 0x7930, 0xa106, 0x0120,
+ 0x7830, 0x7930, 0xa106, 0x1510, 0x7030, 0xa10a, 0x01f8, 0x1210,
+ 0x712c, 0xa10a, 0xa18a, 0x0002, 0x12d0, 0x080c, 0x15c0, 0x01b0,
+ 0x2d00, 0x705a, 0x7063, 0x0040, 0x2001, 0x0003, 0x7057, 0x0000,
+ 0x0126, 0x0006, 0x2091, 0x8000, 0x2009, 0xafec, 0x2104, 0xc085,
+ 0x200a, 0x000e, 0x700e, 0x012e, 0x080c, 0x163c, 0x0005, 0x080c,
+ 0x15c0, 0x0de0, 0x2d00, 0x705a, 0x080c, 0x15c0, 0x1108, 0x0c10,
+ 0x2d00, 0x7086, 0x7063, 0x0080, 0x2001, 0x0004, 0x08f8, 0x0005,
+ 0x0005, 0x0005, 0x700c, 0x0002, 0x5ab9, 0x5abc, 0x5aca, 0x5ae3,
+ 0x5ae3, 0x080c, 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058,
+ 0x0006, 0x080c, 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d,
+ 0x00de, 0x0048, 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058,
+ 0x2068, 0x7084, 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834,
+ 0xa084, 0x00ff, 0xa08a, 0x003a, 0x1218, 0x00db, 0x012e, 0x0005,
+ 0x012e, 0x080c, 0x5b8b, 0x0005, 0x0005, 0x0005, 0x00e6, 0x2071,
+ 0xade1, 0x700c, 0x0002, 0x5af0, 0x5af0, 0x5af0, 0x5af2, 0x5af5,
+ 0x00ee, 0x0005, 0x700f, 0x0001, 0x0010, 0x700f, 0x0002, 0x00ee,
+ 0x0005, 0x5b8b, 0x5b8b, 0x5ba7, 0x5b8b, 0x5d22, 0x5b8b, 0x5b8b,
+ 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x5d64, 0x5da7, 0x5df0, 0x5e04,
+ 0x5b8b, 0x5b8b, 0x5bc3, 0x5ba7, 0x5b8b, 0x5b8b, 0x5c1d, 0x5ead,
+ 0x5ec8, 0x5b8b, 0x5bc3, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5c13,
+ 0x5ec8, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+ 0x5b8b, 0x5b8b, 0x5bd7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+ 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b, 0x5b8b,
+ 0x5b8b, 0x5b8b, 0x5bec, 0x7020, 0x2068, 0x080c, 0x15f0, 0x0005,
+ 0x700c, 0x0002, 0x5b3f, 0x5b42, 0x5b50, 0x5b68, 0x5b68, 0x080c,
+ 0x5a6d, 0x0005, 0x0126, 0x8001, 0x700e, 0x7058, 0x0006, 0x080c,
+ 0x5f90, 0x0120, 0x2091, 0x8000, 0x080c, 0x5a6d, 0x00de, 0x0048,
+ 0x0126, 0x8001, 0x700e, 0x080c, 0x5f90, 0x7058, 0x2068, 0x7084,
+ 0x705a, 0x6803, 0x0000, 0x6807, 0x0000, 0x6834, 0xa084, 0x00ff,
+ 0xa08a, 0x001a, 0x1218, 0x003b, 0x012e, 0x0005, 0x012e, 0x0419,
+ 0x0005, 0x0005, 0x0005, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5ba7,
+ 0x5b8b, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5ba7, 0x5ba7,
+ 0x5ba7, 0x5ba7, 0x5ba7, 0x5b8b, 0x5ba7, 0x5d0e, 0x5b8b, 0x5b8b,
+ 0x5ba7, 0x5b8b, 0x5b8b, 0x5b8b, 0x5ba7, 0x0005, 0x0005, 0x0005,
+ 0x0005, 0x0005, 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff,
+ 0xc0d5, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e,
+ 0x0005, 0x7007, 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0e5, 0x683a,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007,
+ 0x0001, 0x6838, 0xa084, 0x00ff, 0xc0ed, 0x683a, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x7007, 0x0001, 0x6838,
+ 0xa084, 0x00ff, 0xc0dd, 0x683a, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x510c, 0x012e, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff, 0x0988,
+ 0x8001, 0x1120, 0x7007, 0x0001, 0x0804, 0x5cd0, 0x7007, 0x0006,
+ 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5cd0, 0x0005, 0x6834,
+ 0x8007, 0xa084, 0x00ff, 0x0904, 0x5b99, 0x8001, 0x1120, 0x7007,
+ 0x0001, 0x0804, 0x5ced, 0x7007, 0x0006, 0x7012, 0x2d00, 0x7016,
+ 0x701a, 0x704b, 0x5ced, 0x0005, 0x6834, 0x8007, 0xa084, 0x00ff,
+ 0xa086, 0x0001, 0x1904, 0x5b99, 0x7007, 0x0001, 0x2009, 0xad30,
+ 0x210c, 0x81ff, 0x11a8, 0x6838, 0xa084, 0x00ff, 0x683a, 0x6853,
+ 0x0000, 0x080c, 0x4ab1, 0x1108, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x6837, 0x0139, 0x684a, 0x6952, 0x080c, 0x510c, 0x012e, 0x0ca0,
+ 0x2001, 0x0028, 0x0c90, 0x684c, 0xa084, 0x00c0, 0xa086, 0x00c0,
+ 0x1120, 0x7007, 0x0001, 0x0804, 0x5ee0, 0x2d00, 0x7016, 0x701a,
+ 0x20a9, 0x0004, 0xa080, 0x0024, 0x2098, 0x20a1, 0xae0c, 0x53a3,
+ 0x6858, 0x7012, 0xa082, 0x0401, 0x1a04, 0x5bb5, 0x6a84, 0xa28a,
+ 0x0002, 0x1a04, 0x5bb5, 0x82ff, 0x1138, 0x6888, 0x698c, 0xa105,
+ 0x0118, 0x2001, 0x5ca3, 0x0018, 0xa280, 0x5c99, 0x2005, 0x70c6,
+ 0x7010, 0xa015, 0x0904, 0x5c85, 0x080c, 0x15c0, 0x1118, 0x7007,
+ 0x000f, 0x0005, 0x2d00, 0x7022, 0x70c4, 0x2060, 0x2c05, 0x6836,
+ 0xe004, 0xad00, 0x7096, 0xe008, 0xa20a, 0x1210, 0xa00e, 0x2200,
+ 0x7112, 0xe20c, 0x8003, 0x800b, 0xa296, 0x0004, 0x0108, 0xa108,
+ 0x719a, 0x810b, 0x719e, 0xae90, 0x0022, 0x080c, 0x1624, 0x7090,
+ 0xa08e, 0x0100, 0x0170, 0xa086, 0x0200, 0x0118, 0x7007, 0x0010,
+ 0x0005, 0x7020, 0x2068, 0x080c, 0x15f0, 0x7014, 0x2068, 0x0804,
+ 0x5bb5, 0x7020, 0x2068, 0x7018, 0x6802, 0x6807, 0x0000, 0x2d08,
+ 0x2068, 0x6906, 0x711a, 0x0804, 0x5c40, 0x7014, 0x2068, 0x7007,
+ 0x0001, 0x6884, 0xa005, 0x1128, 0x6888, 0x698c, 0xa105, 0x0108,
+ 0x00b1, 0x6834, 0xa084, 0x00ff, 0xa086, 0x001e, 0x0904, 0x5ee0,
+ 0x04b8, 0x5c9b, 0x5c9f, 0x0002, 0x0011, 0x0007, 0x0004, 0x000a,
+ 0x000f, 0x0005, 0x0006, 0x000a, 0x0011, 0x0005, 0x0004, 0x00f6,
+ 0x00e6, 0x00c6, 0x0076, 0x0066, 0x6f88, 0x6e8c, 0x6804, 0x2060,
+ 0xacf0, 0x0021, 0xacf8, 0x0027, 0x2009, 0x0005, 0x700c, 0x7816,
+ 0x7008, 0x7812, 0x7004, 0x7806, 0x7000, 0x7802, 0x7e0e, 0x7f0a,
+ 0x8109, 0x0128, 0xaef2, 0x0004, 0xaffa, 0x0006, 0x0c78, 0x6004,
+ 0xa065, 0x1d30, 0x006e, 0x007e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+ 0x2009, 0xad30, 0x210c, 0x81ff, 0x1198, 0x6838, 0xa084, 0x00ff,
+ 0x683a, 0x080c, 0x4993, 0x1108, 0x0005, 0x080c, 0x51df, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x012e, 0x0ca0,
+ 0x2001, 0x0028, 0x2009, 0x0000, 0x0c80, 0x2009, 0xad30, 0x210c,
+ 0x81ff, 0x11b0, 0x6858, 0xa005, 0x01b0, 0x6838, 0xa084, 0x00ff,
+ 0x683a, 0x6853, 0x0000, 0x080c, 0x4a55, 0x1108, 0x0005, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x51df, 0x080c, 0x510c, 0x012e, 0x0cb0,
+ 0x2001, 0x0028, 0x0ca0, 0x2001, 0x0000, 0x0c88, 0x7018, 0x6802,
+ 0x2d08, 0x2068, 0x6906, 0x711a, 0x7010, 0x8001, 0x7012, 0x0118,
+ 0x7007, 0x0006, 0x0030, 0x7014, 0x2068, 0x7007, 0x0001, 0x7048,
+ 0x080f, 0x0005, 0x7007, 0x0001, 0x6944, 0x810f, 0xa18c, 0x00ff,
+ 0x6848, 0xa084, 0x00ff, 0x20a9, 0x0001, 0xa096, 0x0001, 0x01b0,
+ 0x2009, 0x0000, 0x20a9, 0x00ff, 0xa096, 0x0002, 0x0178, 0xa005,
+ 0x11f0, 0x6944, 0x810f, 0xa18c, 0x00ff, 0x080c, 0x4cdc, 0x11b8,
+ 0x0066, 0x6e50, 0x080c, 0x4dcf, 0x006e, 0x0088, 0x0046, 0x2011,
+ 0xad0c, 0x2224, 0xc484, 0x2412, 0x004e, 0x00c6, 0x080c, 0x4cdc,
+ 0x1110, 0x080c, 0x4f2d, 0x8108, 0x1f04, 0x5d4e, 0x00ce, 0x684c,
+ 0xd084, 0x1118, 0x080c, 0x15f0, 0x0005, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x510c, 0x012e, 0x0005, 0x0126, 0x2091, 0x8000, 0x7007,
+ 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0580, 0x2061, 0xb048,
+ 0x6100, 0xd184, 0x0178, 0x6858, 0xa084, 0x00ff, 0x1550, 0x6000,
+ 0xd084, 0x0520, 0x6004, 0xa005, 0x1538, 0x6003, 0x0000, 0x600b,
+ 0x0000, 0x00c8, 0x2011, 0x0001, 0x6860, 0xa005, 0x1110, 0x2001,
+ 0x001e, 0x8000, 0x6016, 0x6858, 0xa084, 0x00ff, 0x0178, 0x6006,
+ 0x6858, 0x8007, 0xa084, 0x00ff, 0x0148, 0x600a, 0x6858, 0x8000,
+ 0x1108, 0xc28d, 0x6202, 0x012e, 0x0804, 0x5f7f, 0x012e, 0x0804,
+ 0x5f79, 0x012e, 0x0804, 0x5f73, 0x012e, 0x0804, 0x5f76, 0x0126,
+ 0x2091, 0x8000, 0x7007, 0x0001, 0x2001, 0xad52, 0x2004, 0xd0a4,
+ 0x05e0, 0x2061, 0xb048, 0x6000, 0xd084, 0x05b8, 0x6204, 0x6308,
+ 0xd08c, 0x1530, 0x6c48, 0xa484, 0x0003, 0x0170, 0x6958, 0xa18c,
+ 0x00ff, 0x8001, 0x1120, 0x2100, 0xa210, 0x0620, 0x0028, 0x8001,
+ 0x1508, 0x2100, 0xa212, 0x02f0, 0xa484, 0x000c, 0x0188, 0x6958,
+ 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x1120, 0x2100, 0xa318,
+ 0x0288, 0x0030, 0xa082, 0x0004, 0x1168, 0x2100, 0xa31a, 0x0250,
+ 0x6860, 0xa005, 0x0110, 0x8000, 0x6016, 0x6206, 0x630a, 0x012e,
+ 0x0804, 0x5f7f, 0x012e, 0x0804, 0x5f7c, 0x012e, 0x0804, 0x5f79,
+ 0x0126, 0x2091, 0x8000, 0x7007, 0x0001, 0x2061, 0xb048, 0x6300,
+ 0xd38c, 0x1120, 0x6308, 0x8318, 0x0220, 0x630a, 0x012e, 0x0804,
+ 0x5f8d, 0x012e, 0x0804, 0x5f7c, 0x0126, 0x00c6, 0x2091, 0x8000,
+ 0x7007, 0x0001, 0x684c, 0xd0ac, 0x0148, 0x00c6, 0x2061, 0xb048,
+ 0x6000, 0xa084, 0xfcff, 0x6002, 0x00ce, 0x0448, 0x6858, 0xa005,
+ 0x05d0, 0x685c, 0xa065, 0x0598, 0x2001, 0xad30, 0x2004, 0xa005,
+ 0x0118, 0x080c, 0x974e, 0x0068, 0x6013, 0x0400, 0x6057, 0x0000,
+ 0x694c, 0xd1a4, 0x0110, 0x6950, 0x6156, 0x2009, 0x0041, 0x080c,
+ 0x80a7, 0x6958, 0xa18c, 0xff00, 0xa186, 0x2000, 0x1140, 0x0026,
+ 0x2009, 0x0000, 0x2011, 0xfdff, 0x080c, 0x663f, 0x002e, 0x684c,
+ 0xd0c4, 0x0148, 0x2061, 0xb048, 0x6000, 0xd08c, 0x1120, 0x6008,
+ 0x8000, 0x0208, 0x600a, 0x00ce, 0x012e, 0x0804, 0x5f7f, 0x00ce,
+ 0x012e, 0x0804, 0x5f79, 0x6954, 0xa186, 0x002e, 0x0d40, 0xa186,
+ 0x002d, 0x0d28, 0xa186, 0x0045, 0x0510, 0xa186, 0x002a, 0x1130,
+ 0x2001, 0xad0c, 0x200c, 0xc194, 0x2102, 0x08c8, 0xa186, 0x0020,
+ 0x0170, 0xa186, 0x0029, 0x1d18, 0x6944, 0xa18c, 0xff00, 0x810f,
+ 0x080c, 0x4cdc, 0x1960, 0x6000, 0xc0e4, 0x6002, 0x0840, 0x685c,
+ 0xa065, 0x09a8, 0x2001, 0xafa3, 0x2004, 0x6016, 0x0800, 0x685c,
+ 0xa065, 0x0968, 0x00e6, 0x6860, 0xa075, 0x2001, 0xad30, 0x2004,
+ 0xa005, 0x0150, 0x080c, 0x974e, 0x8eff, 0x0118, 0x2e60, 0x080c,
+ 0x974e, 0x00ee, 0x0804, 0x5e3f, 0x6020, 0xc0dc, 0xc0d5, 0x6022,
+ 0x2e60, 0x6007, 0x003a, 0x6870, 0xa005, 0x0130, 0x6007, 0x003b,
+ 0x6874, 0x602a, 0x6878, 0x6012, 0x6003, 0x0001, 0x080c, 0x67a8,
+ 0x080c, 0x6c50, 0x00ee, 0x0804, 0x5e3f, 0x2061, 0xb048, 0x6000,
+ 0xd084, 0x0190, 0xd08c, 0x1904, 0x5f8d, 0x0126, 0x2091, 0x8000,
+ 0x6204, 0x8210, 0x0220, 0x6206, 0x012e, 0x0804, 0x5f8d, 0x012e,
+ 0x6853, 0x0016, 0x0804, 0x5f86, 0x6853, 0x0007, 0x0804, 0x5f86,
+ 0x6834, 0x8007, 0xa084, 0x00ff, 0x1118, 0x080c, 0x5b99, 0x0078,
+ 0x2030, 0x8001, 0x1120, 0x7007, 0x0001, 0x0051, 0x0040, 0x7007,
+ 0x0006, 0x7012, 0x2d00, 0x7016, 0x701a, 0x704b, 0x5ee0, 0x0005,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x2009, 0xad30, 0x210c, 0x81ff,
+ 0x1904, 0x5f5b, 0x2009, 0xad0c, 0x210c, 0xd194, 0x1904, 0x5f63,
+ 0x6848, 0x2070, 0xae82, 0xb400, 0x0a04, 0x5f4f, 0x2001, 0xad16,
+ 0x2004, 0xae02, 0x1a04, 0x5f4f, 0x2061, 0xb048, 0x6100, 0xa184,
+ 0x0301, 0xa086, 0x0001, 0x15a8, 0x711c, 0xa186, 0x0006, 0x15b0,
+ 0x7018, 0xa005, 0x0904, 0x5f5b, 0x2004, 0xd0e4, 0x1904, 0x5f5e,
+ 0x7020, 0xd0dc, 0x1904, 0x5f66, 0x6853, 0x0000, 0x6803, 0x0000,
+ 0x2d08, 0x7010, 0xa005, 0x1158, 0x7112, 0x684c, 0xd0f4, 0x1904,
+ 0x5f69, 0x2e60, 0x080c, 0x65aa, 0x012e, 0x00ee, 0x0005, 0x2068,
+ 0x6800, 0xa005, 0x1de0, 0x6902, 0x2168, 0x684c, 0xd0f4, 0x15c8,
+ 0x012e, 0x00ee, 0x0005, 0x012e, 0x00ee, 0x6853, 0x0006, 0x0804,
+ 0x5f86, 0xd184, 0x0dc0, 0xd1c4, 0x11a8, 0x00b8, 0x6944, 0xa18c,
+ 0xff00, 0x810f, 0x080c, 0x4cdc, 0x11c8, 0x6000, 0xd0e4, 0x11b0,
+ 0x711c, 0xa186, 0x0007, 0x1118, 0x6853, 0x0002, 0x0088, 0x6853,
+ 0x0008, 0x0070, 0x6853, 0x000e, 0x0058, 0x6853, 0x0017, 0x0040,
+ 0x6853, 0x0035, 0x0028, 0x6853, 0x0028, 0x0010, 0x6853, 0x0029,
+ 0x012e, 0x00ee, 0x0418, 0x6853, 0x002a, 0x0cd0, 0x6853, 0x0045,
+ 0x0cb8, 0x2e60, 0x2019, 0x0002, 0x6017, 0x0014, 0x080c, 0xa566,
+ 0x012e, 0x00ee, 0x0005, 0x2009, 0x003e, 0x0058, 0x2009, 0x0004,
+ 0x0040, 0x2009, 0x0006, 0x0028, 0x2009, 0x0016, 0x0010, 0x2009,
+ 0x0001, 0x6854, 0xa084, 0xff00, 0xa105, 0x6856, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x510c, 0x012e, 0x0005, 0x080c, 0x15f0, 0x0005,
+ 0x702c, 0x7130, 0x8108, 0xa102, 0x0230, 0xa00e, 0x7034, 0x7072,
+ 0x7038, 0x7076, 0x0058, 0x7070, 0xa080, 0x0040, 0x7072, 0x1230,
+ 0x7074, 0xa081, 0x0000, 0x7076, 0xa085, 0x0001, 0x7932, 0x7132,
+ 0x0005, 0x00d6, 0x080c, 0x65a1, 0x00de, 0x0005, 0x00d6, 0x2011,
+ 0x0004, 0x2204, 0xa085, 0x8002, 0x2012, 0x00de, 0x0005, 0x20e1,
+ 0x0002, 0x3d08, 0x20e1, 0x2000, 0x3d00, 0xa084, 0x7000, 0x0118,
+ 0xa086, 0x1000, 0x1540, 0x20e1, 0x0000, 0x3d00, 0xa094, 0xff00,
+ 0x8217, 0xa084, 0xf000, 0xa086, 0x3000, 0x1118, 0x080c, 0x61c6,
+ 0x00b0, 0x20e1, 0x0004, 0x3d60, 0xd1bc, 0x1108, 0x3e60, 0xac84,
+ 0x0007, 0x1188, 0xac82, 0xb400, 0x0270, 0x6858, 0xac02, 0x1258,
+ 0x6120, 0xd1f4, 0x1160, 0x2009, 0x0047, 0x080c, 0x80a7, 0x7a1c,
+ 0xd284, 0x1968, 0x0005, 0xa016, 0x080c, 0x1824, 0x0cc0, 0x0cd8,
+ 0x781c, 0xd08c, 0x0500, 0x0156, 0x0136, 0x0146, 0x20e1, 0x3000,
+ 0x3d20, 0x3e28, 0xa584, 0x0076, 0x1530, 0xa484, 0x7000, 0xa086,
+ 0x1000, 0x11a8, 0x080c, 0x604e, 0x01f0, 0x20e1, 0x3000, 0x7828,
+ 0x7828, 0x080c, 0x606a, 0x014e, 0x013e, 0x015e, 0x2009, 0xafcf,
+ 0x2104, 0xa005, 0x1108, 0x0005, 0x080c, 0x6c50, 0x0ce0, 0xa484,
+ 0x7000, 0x1518, 0x0499, 0x01b8, 0x7000, 0xa084, 0xff00, 0xa086,
+ 0x8100, 0x0d18, 0x0080, 0xd5a4, 0x0158, 0x080c, 0x1d86, 0x20e1,
+ 0x9010, 0x2001, 0x0160, 0x2502, 0x2001, 0x0138, 0x2202, 0x0048,
+ 0x00e9, 0x6883, 0x0000, 0x080c, 0xac59, 0x20e1, 0x3000, 0x7828,
+ 0x7828, 0x014e, 0x013e, 0x015e, 0x08b0, 0x0081, 0x1130, 0x7000,
+ 0xa084, 0xff00, 0xa086, 0x8100, 0x1d70, 0x080c, 0xac59, 0x20e1,
+ 0x3000, 0x7828, 0x7828, 0x080c, 0x642d, 0x0c58, 0xa484, 0x01ff,
+ 0x6882, 0xa005, 0x0160, 0xa080, 0x001f, 0xa084, 0x03f8, 0x80ac,
+ 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x0005, 0x20a9,
+ 0x000c, 0x20e1, 0x1000, 0x2ea0, 0x2099, 0x020a, 0x53a5, 0xa085,
+ 0x0001, 0x0ca0, 0x7000, 0xa084, 0xff00, 0xa08c, 0xf000, 0x8007,
+ 0xa196, 0x0000, 0x1118, 0x0804, 0x62cf, 0x0005, 0xa196, 0x2000,
+ 0x1148, 0x6900, 0xa18e, 0x0001, 0x1118, 0x080c, 0x41d1, 0x0ca8,
+ 0x0039, 0x0c98, 0xa196, 0x8000, 0x1d80, 0x080c, 0x6372, 0x0c68,
+ 0x00c6, 0x6a80, 0x82ff, 0x0904, 0x61c0, 0x7110, 0xa18c, 0xff00,
+ 0x810f, 0xa196, 0x0001, 0x0120, 0xa196, 0x0023, 0x1904, 0x61c0,
+ 0xa08e, 0x0023, 0x1570, 0x080c, 0x6408, 0x0904, 0x61c0, 0x7124,
+ 0x610a, 0x7030, 0xa08e, 0x0200, 0x1150, 0x7034, 0xa005, 0x1904,
+ 0x61c0, 0x2009, 0x0015, 0x080c, 0x80a7, 0x0804, 0x61c0, 0xa08e,
+ 0x0214, 0x0118, 0xa08e, 0x0210, 0x1130, 0x2009, 0x0015, 0x080c,
+ 0x80a7, 0x0804, 0x61c0, 0xa08e, 0x0100, 0x1904, 0x61c0, 0x7034,
+ 0xa005, 0x1904, 0x61c0, 0x2009, 0x0016, 0x080c, 0x80a7, 0x0804,
+ 0x61c0, 0xa08e, 0x0022, 0x1904, 0x61c0, 0x7030, 0xa08e, 0x0300,
+ 0x1580, 0x68d0, 0xd0a4, 0x0528, 0xc0b5, 0x68d2, 0x7100, 0xa18c,
+ 0x00ff, 0x696e, 0x7004, 0x6872, 0x00f6, 0x2079, 0x0100, 0x79e6,
+ 0x78ea, 0x0006, 0xa084, 0x00ff, 0x0016, 0x2008, 0x080c, 0x26a0,
+ 0x7932, 0x7936, 0x001e, 0x000e, 0x00fe, 0x080c, 0x2676, 0x694e,
+ 0x703c, 0x00e6, 0x2071, 0x0140, 0x7086, 0x2071, 0xad00, 0x70a2,
+ 0x00ee, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0017, 0x0804,
+ 0x6193, 0xa08e, 0x0400, 0x1158, 0x7034, 0xa005, 0x1904, 0x61c0,
+ 0x68d0, 0xc0a5, 0x68d2, 0x2009, 0x0030, 0x0804, 0x6193, 0xa08e,
+ 0x0500, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0018,
+ 0x0804, 0x6193, 0xa08e, 0x2010, 0x1120, 0x2009, 0x0019, 0x0804,
+ 0x6193, 0xa08e, 0x2110, 0x1120, 0x2009, 0x001a, 0x0804, 0x6193,
+ 0xa08e, 0x5200, 0x1140, 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009,
+ 0x001b, 0x0804, 0x6193, 0xa08e, 0x5000, 0x1140, 0x7034, 0xa005,
+ 0x1904, 0x61c0, 0x2009, 0x001c, 0x0804, 0x6193, 0xa08e, 0x1300,
+ 0x1120, 0x2009, 0x0034, 0x0804, 0x6193, 0xa08e, 0x1200, 0x1140,
+ 0x7034, 0xa005, 0x1904, 0x61c0, 0x2009, 0x0024, 0x0804, 0x6193,
+ 0xa08c, 0xff00, 0xa18e, 0x2400, 0x1118, 0x2009, 0x002d, 0x04d8,
+ 0xa08c, 0xff00, 0xa18e, 0x5300, 0x1118, 0x2009, 0x002a, 0x0498,
+ 0xa08e, 0x0f00, 0x1118, 0x2009, 0x0020, 0x0468, 0xa08e, 0x5300,
+ 0x1108, 0x00d8, 0xa08e, 0x6104, 0x11c0, 0x2011, 0xb28d, 0x8208,
+ 0x2204, 0xa082, 0x0004, 0x20a8, 0x95ac, 0x95ac, 0x2011, 0x8015,
+ 0x211c, 0x8108, 0x0046, 0x2124, 0x080c, 0x3c5c, 0x004e, 0x8108,
+ 0x1f04, 0x6176, 0x2009, 0x0023, 0x0070, 0xa08e, 0x6000, 0x1118,
+ 0x2009, 0x003f, 0x0040, 0xa08e, 0x7800, 0x1118, 0x2009, 0x0045,
+ 0x0010, 0x2009, 0x001d, 0x0016, 0x2011, 0xb283, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x2676, 0x1530, 0x080c, 0x4c80, 0x1518, 0x6612,
+ 0x6516, 0x86ff, 0x0180, 0x001e, 0x0016, 0xa186, 0x0017, 0x1158,
+ 0x686c, 0xa606, 0x1140, 0x6870, 0xa506, 0xa084, 0xff00, 0x1118,
+ 0x6000, 0xc0f5, 0x6002, 0x00c6, 0x080c, 0x8022, 0x0168, 0x001e,
+ 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c, 0x80a7,
+ 0x00ce, 0x0005, 0x001e, 0x0ce0, 0x00ce, 0x0ce0, 0x00c6, 0x0046,
+ 0x080c, 0x6221, 0x1904, 0x621e, 0xa184, 0xff00, 0x8007, 0xa086,
+ 0x0008, 0x1904, 0x621e, 0xa28e, 0x0033, 0x11e8, 0x080c, 0x6408,
+ 0x0904, 0x621e, 0x7124, 0x610a, 0x7030, 0xa08e, 0x0200, 0x1140,
+ 0x7034, 0xa005, 0x15d8, 0x2009, 0x0015, 0x080c, 0x80a7, 0x04b0,
+ 0xa08e, 0x0100, 0x1598, 0x7034, 0xa005, 0x1580, 0x2009, 0x0016,
+ 0x080c, 0x80a7, 0x0458, 0xa28e, 0x0032, 0x1540, 0x7030, 0xa08e,
+ 0x1400, 0x1520, 0x2009, 0x0038, 0x0016, 0x2011, 0xb283, 0x2204,
+ 0x8211, 0x220c, 0x080c, 0x2676, 0x11c0, 0x080c, 0x4c80, 0x11a8,
+ 0x6612, 0x6516, 0x00c6, 0x080c, 0x8022, 0x0170, 0x001e, 0x611a,
+ 0x080c, 0x9956, 0x601f, 0x0004, 0x7120, 0x610a, 0x001e, 0x080c,
+ 0x80a7, 0x080c, 0x6c50, 0x0010, 0x00ce, 0x001e, 0x004e, 0x00ce,
+ 0x0005, 0x00f6, 0x00d6, 0x0026, 0x0016, 0x0136, 0x0146, 0x0156,
+ 0x3c00, 0x0006, 0x2079, 0x0030, 0x2069, 0x0200, 0x080c, 0x1df2,
+ 0x1590, 0x080c, 0x1ce2, 0x05c8, 0x04d9, 0x1130, 0x7908, 0xa18c,
+ 0x1fff, 0xa182, 0x0011, 0x1688, 0x20a9, 0x000c, 0x20e1, 0x0000,
+ 0x2ea0, 0x2099, 0x020a, 0x53a5, 0x20e1, 0x2000, 0x2001, 0x020a,
+ 0x2004, 0x7a0c, 0x7808, 0xa080, 0x0007, 0xa084, 0x1ff8, 0x0401,
+ 0x1120, 0xa08a, 0x0140, 0x1a0c, 0x14f6, 0x80ac, 0x20e1, 0x6000,
+ 0x2099, 0x020a, 0x53a5, 0x20e1, 0x7000, 0x6828, 0x6828, 0x7803,
+ 0x0004, 0xa294, 0x0070, 0x000e, 0x20e0, 0x015e, 0x014e, 0x013e,
+ 0x001e, 0x002e, 0x00de, 0x00fe, 0x0005, 0xa085, 0x0001, 0x0c98,
+ 0x0006, 0x2001, 0x0111, 0x2004, 0xa084, 0x0003, 0x000e, 0x0005,
+ 0x0046, 0x00e6, 0x00d6, 0x2028, 0x2130, 0xa696, 0x00ff, 0x1198,
+ 0xa596, 0xfffd, 0x1120, 0x2009, 0x007f, 0x0804, 0x62ca, 0xa596,
+ 0xfffe, 0x1118, 0x2009, 0x007e, 0x04e8, 0xa596, 0xfffc, 0x1118,
+ 0x2009, 0x0080, 0x04b8, 0x2011, 0x0000, 0x2019, 0xad34, 0x231c,
+ 0xd3ac, 0x0138, 0x2021, 0x0000, 0x20a9, 0x00ff, 0x2071, 0xae34,
+ 0x0030, 0x2021, 0x0081, 0x20a9, 0x007e, 0x2071, 0xaeb5, 0x2e1c,
+ 0x83ff, 0x1128, 0x82ff, 0x1198, 0x2410, 0xc2fd, 0x0080, 0x2368,
+ 0x6f10, 0x0006, 0x2100, 0xa706, 0x000e, 0x6b14, 0x1120, 0xa346,
+ 0x1110, 0x2408, 0x0078, 0x87ff, 0x1110, 0x83ff, 0x0d58, 0x8420,
+ 0x8e70, 0x1f04, 0x62a7, 0x82ff, 0x1118, 0xa085, 0x0001, 0x0018,
+ 0xc2fc, 0x2208, 0xa006, 0x00de, 0x00ee, 0x004e, 0x0005, 0xa084,
+ 0x0007, 0x000a, 0x0005, 0x62db, 0x62db, 0x62db, 0x641a, 0x62db,
+ 0x62dc, 0x62f1, 0x635d, 0x0005, 0x7110, 0xd1bc, 0x0188, 0x7120,
+ 0x2160, 0xac8c, 0x0007, 0x1160, 0xac8a, 0xb400, 0x0248, 0x6858,
+ 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0046, 0x080c, 0x80a7,
+ 0x0005, 0x00c6, 0x7110, 0xd1bc, 0x1904, 0x6344, 0x2011, 0xb283,
+ 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1904, 0x6344, 0x080c,
+ 0x4c80, 0x1904, 0x6344, 0x6612, 0x6516, 0x6000, 0xd0ec, 0x15e0,
+ 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006, 0x0160, 0x080c,
+ 0x574f, 0x11d0, 0x6204, 0xa294, 0x00ff, 0xa286, 0x0006, 0x11a0,
+ 0xa295, 0x0600, 0x6206, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0530,
+ 0x611a, 0x601f, 0x0006, 0x7120, 0x610a, 0x7130, 0x6152, 0x2009,
+ 0x0044, 0x080c, 0x80a7, 0x00c0, 0x00c6, 0x080c, 0x8022, 0x001e,
+ 0x0198, 0x611a, 0x601f, 0x0004, 0x7120, 0x610a, 0xa286, 0x0004,
+ 0x1118, 0x6007, 0x0005, 0x0010, 0x6007, 0x0001, 0x6003, 0x0001,
+ 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00ce, 0x0005, 0x00c6, 0x080c,
+ 0x9807, 0x001e, 0x0dc8, 0x611a, 0x601f, 0x0006, 0x7120, 0x610a,
+ 0x7130, 0x6152, 0x6013, 0x0300, 0x6003, 0x0001, 0x6007, 0x0041,
+ 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c38, 0x7110, 0xd1bc, 0x0188,
+ 0x7020, 0x2060, 0xac84, 0x0007, 0x1160, 0xac82, 0xb400, 0x0248,
+ 0x6858, 0xac02, 0x1230, 0x7124, 0x610a, 0x2009, 0x0045, 0x080c,
+ 0x80a7, 0x0005, 0x7110, 0xa18c, 0xff00, 0x810f, 0xa18e, 0x0000,
+ 0x1130, 0xa084, 0x000f, 0xa08a, 0x0006, 0x1208, 0x000b, 0x0005,
+ 0x6386, 0x6387, 0x6386, 0x6386, 0x63f0, 0x63fc, 0x0005, 0x7110,
+ 0xd1bc, 0x0120, 0x702c, 0xd084, 0x0904, 0x63ef, 0x700c, 0x7108,
+ 0x080c, 0x2676, 0x1904, 0x63ef, 0x080c, 0x4c80, 0x1904, 0x63ef,
+ 0x6612, 0x6516, 0x6204, 0x7110, 0xd1bc, 0x01f8, 0xa28c, 0x00ff,
+ 0xa186, 0x0004, 0x0118, 0xa186, 0x0006, 0x15c8, 0x00c6, 0x080c,
+ 0x6408, 0x00ce, 0x0904, 0x63ef, 0x00c6, 0x080c, 0x8022, 0x001e,
+ 0x05f0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0002, 0x7120, 0x610a,
+ 0x2009, 0x0088, 0x080c, 0x80a7, 0x0490, 0xa28c, 0x00ff, 0xa186,
+ 0x0006, 0x0160, 0xa186, 0x0004, 0x0148, 0xa294, 0xff00, 0x8217,
+ 0xa286, 0x0004, 0x0118, 0xa286, 0x0006, 0x1188, 0x00c6, 0x080c,
+ 0x8022, 0x001e, 0x01e0, 0x611a, 0x080c, 0x9956, 0x601f, 0x0005,
+ 0x7120, 0x610a, 0x2009, 0x0088, 0x080c, 0x80a7, 0x0080, 0x00c6,
+ 0x080c, 0x8022, 0x001e, 0x0158, 0x611a, 0x080c, 0x9956, 0x601f,
+ 0x0004, 0x7120, 0x610a, 0x2009, 0x0001, 0x080c, 0x80a7, 0x0005,
+ 0x7110, 0xd1bc, 0x0140, 0x00a1, 0x0130, 0x7124, 0x610a, 0x2009,
+ 0x0089, 0x080c, 0x80a7, 0x0005, 0x7110, 0xd1bc, 0x0140, 0x0041,
+ 0x0130, 0x7124, 0x610a, 0x2009, 0x008a, 0x080c, 0x80a7, 0x0005,
+ 0x7020, 0x2060, 0xac84, 0x0007, 0x1158, 0xac82, 0xb400, 0x0240,
+ 0x2001, 0xad16, 0x2004, 0xac02, 0x1218, 0xa085, 0x0001, 0x0005,
+ 0xa006, 0x0ce8, 0x7110, 0xd1bc, 0x1178, 0x7024, 0x2060, 0xac84,
+ 0x0007, 0x1150, 0xac82, 0xb400, 0x0238, 0x6858, 0xac02, 0x1220,
+ 0x2009, 0x0051, 0x080c, 0x80a7, 0x0005, 0x2031, 0x0105, 0x0069,
+ 0x0005, 0x2031, 0x0206, 0x0049, 0x0005, 0x2031, 0x0207, 0x0029,
+ 0x0005, 0x2031, 0x0213, 0x0009, 0x0005, 0x00c6, 0x00d6, 0x00f6,
+ 0x7000, 0xa084, 0xf000, 0xa086, 0xc000, 0x05b0, 0x080c, 0x8022,
+ 0x0598, 0x0066, 0x00c6, 0x0046, 0x2011, 0xb283, 0x2204, 0x8211,
+ 0x220c, 0x080c, 0x2676, 0x1580, 0x080c, 0x4c80, 0x1568, 0x6612,
+ 0x6516, 0x2c00, 0x004e, 0x00ce, 0x601a, 0x080c, 0x9956, 0x080c,
+ 0x15d9, 0x01f0, 0x2d00, 0x6056, 0x6803, 0x0000, 0x6837, 0x0000,
+ 0x6c3a, 0xadf8, 0x000f, 0x20a9, 0x000e, 0x2fa0, 0x2e98, 0x53a3,
+ 0x006e, 0x6612, 0x6007, 0x003e, 0x601f, 0x0001, 0x6003, 0x0001,
+ 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00fe, 0x00de, 0x00ce, 0x0005,
+ 0x080c, 0x8078, 0x006e, 0x0cc0, 0x004e, 0x00ce, 0x0cc8, 0x2071,
+ 0xafda, 0x7003, 0x0003, 0x700f, 0x0361, 0xa006, 0x701a, 0x7012,
+ 0x7017, 0xb400, 0x7007, 0x0000, 0x7026, 0x702b, 0x7841, 0x7032,
+ 0x7037, 0x789d, 0x703b, 0xffff, 0x703f, 0xffff, 0x7042, 0x7047,
+ 0x41b3, 0x0005, 0x2071, 0xafda, 0x1d04, 0x64fc, 0x2091, 0x6000,
+ 0x700c, 0x8001, 0x700e, 0x1180, 0x700f, 0x0361, 0x7007, 0x0001,
+ 0x0126, 0x2091, 0x8000, 0x7040, 0xa00d, 0x0148, 0x8109, 0x7142,
+ 0x1130, 0x7044, 0x080f, 0x0018, 0x0126, 0x2091, 0x8000, 0x7024,
+ 0xa00d, 0x0188, 0x7020, 0x8001, 0x7022, 0x1168, 0x7023, 0x0009,
+ 0x8109, 0x7126, 0xa186, 0x03e8, 0x1110, 0x7028, 0x080f, 0x81ff,
+ 0x1110, 0x7028, 0x080f, 0x7030, 0xa00d, 0x0158, 0x702c, 0x8001,
+ 0x702e, 0x1138, 0x702f, 0x0009, 0x8109, 0x7132, 0x1110, 0x7034,
+ 0x080f, 0x7038, 0xa005, 0x0118, 0x0310, 0x8001, 0x703a, 0x703c,
+ 0xa005, 0x0118, 0x0310, 0x8001, 0x703e, 0x7018, 0xa00d, 0x0158,
+ 0x7008, 0x8001, 0x700a, 0x1138, 0x700b, 0x0009, 0x8109, 0x711a,
+ 0x1110, 0x701c, 0x080f, 0x012e, 0x7004, 0x0002, 0x6522, 0x6523,
+ 0x653b, 0x00e6, 0x2071, 0xafda, 0x7018, 0xa005, 0x1120, 0x711a,
+ 0x721e, 0x700b, 0x0009, 0x00ee, 0x0005, 0x00e6, 0x0006, 0x2071,
+ 0xafda, 0x701c, 0xa206, 0x1110, 0x701a, 0x701e, 0x000e, 0x00ee,
+ 0x0005, 0x00e6, 0x2071, 0xafda, 0x6088, 0xa102, 0x0208, 0x618a,
+ 0x00ee, 0x0005, 0x0005, 0x7110, 0x080c, 0x4cdc, 0x1158, 0x6088,
+ 0x8001, 0x0240, 0x608a, 0x1130, 0x0126, 0x2091, 0x8000, 0x080c,
+ 0x6c50, 0x012e, 0x8108, 0xa182, 0x00ff, 0x0218, 0xa00e, 0x7007,
+ 0x0002, 0x7112, 0x0005, 0x7014, 0x2060, 0x0126, 0x2091, 0x8000,
+ 0x603c, 0xa005, 0x0128, 0x8001, 0x603e, 0x1110, 0x080c, 0x9846,
+ 0x6014, 0xa005, 0x0500, 0x8001, 0x6016, 0x11e8, 0x611c, 0xa186,
+ 0x0003, 0x0118, 0xa186, 0x0006, 0x11a0, 0x6010, 0x2068, 0x6854,
+ 0xa08a, 0x199a, 0x0270, 0xa082, 0x1999, 0x6856, 0xa08a, 0x199a,
+ 0x0210, 0x2001, 0x1999, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+ 0x0010, 0x080c, 0x9350, 0x012e, 0xac88, 0x0018, 0x7116, 0x2001,
+ 0xe400, 0xa102, 0x0220, 0x7017, 0xb400, 0x7007, 0x0000, 0x0005,
+ 0x00e6, 0x2071, 0xafda, 0x7027, 0x07d0, 0x7023, 0x0009, 0x00ee,
+ 0x0005, 0x2001, 0xafe3, 0x2003, 0x0000, 0x0005, 0x00e6, 0x2071,
+ 0xafda, 0x7132, 0x702f, 0x0009, 0x00ee, 0x0005, 0x2011, 0xafe6,
+ 0x2013, 0x0000, 0x0005, 0x00e6, 0x2071, 0xafda, 0x711a, 0x721e,
+ 0x700b, 0x0009, 0x00ee, 0x0005, 0x00c6, 0x2061, 0xb048, 0x00ce,
+ 0x0005, 0xa184, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0xb048,
+ 0x2060, 0x0005, 0x6854, 0xa08a, 0x199a, 0x0210, 0x2001, 0x1999,
+ 0xa005, 0x1150, 0x00c6, 0x2061, 0xb048, 0x6014, 0x00ce, 0xa005,
+ 0x1138, 0x2001, 0x001e, 0x0020, 0xa08e, 0xffff, 0x1108, 0xa006,
+ 0x8003, 0x800b, 0x810b, 0xa108, 0x6116, 0x684c, 0xa08c, 0x00c0,
+ 0xa18e, 0x00c0, 0x05b0, 0xd0b4, 0x1138, 0xd0bc, 0x1528, 0x2009,
+ 0x0006, 0x080c, 0x661a, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+ 0x0118, 0xa086, 0x0003, 0x15c0, 0x6020, 0xd0d4, 0x0130, 0xc0d4,
+ 0x6022, 0x6860, 0x602a, 0x685c, 0x602e, 0x2009, 0xad73, 0x2104,
+ 0xd084, 0x0128, 0x2009, 0x0042, 0x080c, 0x80a7, 0x0005, 0x2009,
+ 0x0043, 0x080c, 0x80a7, 0x0005, 0xd0fc, 0x0130, 0xa084, 0x0003,
+ 0x0118, 0xa086, 0x0003, 0x11c0, 0x2009, 0x0042, 0x080c, 0x80a7,
+ 0x0005, 0xd0fc, 0x0150, 0xa084, 0x0003, 0xa08e, 0x0002, 0x0138,
+ 0x2009, 0x0041, 0x080c, 0x80a7, 0x0005, 0x0051, 0x0ce8, 0x2009,
+ 0x0043, 0x080c, 0x80a7, 0x0cc0, 0x2009, 0x0004, 0x0019, 0x0005,
+ 0x2009, 0x0001, 0x00d6, 0x6010, 0xa0ec, 0xf000, 0x01f0, 0x2068,
+ 0x6952, 0x6800, 0x6012, 0xa186, 0x0001, 0x1188, 0x694c, 0xa18c,
+ 0x8100, 0xa18e, 0x8100, 0x1158, 0x00c6, 0x2061, 0xb048, 0x6200,
+ 0xd28c, 0x1120, 0x6204, 0x8210, 0x0208, 0x6206, 0x00ce, 0x080c,
+ 0x510c, 0x6010, 0xa06d, 0x190c, 0x65aa, 0x00de, 0x0005, 0x0156,
+ 0x00c6, 0x2061, 0xb048, 0x6000, 0x81ff, 0x0110, 0xa205, 0x0008,
+ 0xa204, 0x6002, 0x00ce, 0x015e, 0x0005, 0x6800, 0xd08c, 0x1138,
+ 0x6808, 0xa005, 0x0120, 0x8001, 0x680a, 0xa085, 0x0001, 0x0005,
+ 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
+ 0x1f04, 0x665c, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
+ 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
+ 0x1220, 0x1f04, 0x666c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
+ 0x666c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
+ 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x0126, 0x2091,
+ 0x2800, 0x2079, 0xafc7, 0x012e, 0x00d6, 0x2069, 0xafc7, 0x6803,
+ 0x0005, 0x2069, 0x0004, 0x2d04, 0xa085, 0x8001, 0x206a, 0x00de,
+ 0x0005, 0x00c6, 0x6027, 0x0001, 0x7804, 0xa084, 0x0007, 0x0002,
+ 0x66aa, 0x66cb, 0x671e, 0x66b0, 0x66cb, 0x66aa, 0x66a8, 0x66a8,
+ 0x080c, 0x14f6, 0x080c, 0x6581, 0x080c, 0x6c50, 0x00ce, 0x0005,
+ 0x62c0, 0x82ff, 0x1110, 0x00ce, 0x0005, 0x2011, 0x481b, 0x080c,
+ 0x650d, 0x7828, 0xa092, 0x00c8, 0x1228, 0x8000, 0x782a, 0x080c,
+ 0x4855, 0x0c88, 0x080c, 0x481b, 0x7807, 0x0003, 0x7827, 0x0000,
+ 0x782b, 0x0000, 0x0c40, 0x080c, 0x6581, 0x3c00, 0x0006, 0x2011,
+ 0x0209, 0x20e1, 0x4000, 0x2214, 0x000e, 0x20e0, 0x82ff, 0x0178,
+ 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824, 0xa065, 0x090c,
+ 0x14f6, 0x2009, 0x0013, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x3900,
+ 0xa082, 0xb0e8, 0x1210, 0x080c, 0x7d8d, 0x00c6, 0x7824, 0xa065,
+ 0x090c, 0x14f6, 0x7804, 0xa086, 0x0004, 0x0904, 0x675e, 0x7828,
+ 0xa092, 0x2710, 0x1230, 0x8000, 0x782a, 0x00ce, 0x080c, 0x7827,
+ 0x0c20, 0x6104, 0xa186, 0x0003, 0x1188, 0x00e6, 0x2071, 0xad00,
+ 0x70dc, 0x00ee, 0xd08c, 0x0150, 0x00c6, 0x00e6, 0x2061, 0x0100,
+ 0x2071, 0xad00, 0x080c, 0x485e, 0x00ee, 0x00ce, 0x080c, 0xaca2,
+ 0x2009, 0x0014, 0x080c, 0x80a7, 0x00ce, 0x0838, 0x2001, 0xafe3,
+ 0x2003, 0x0000, 0x62c0, 0x82ff, 0x1160, 0x782b, 0x0000, 0x7824,
+ 0xa065, 0x090c, 0x14f6, 0x2009, 0x0013, 0x080c, 0x80fb, 0x00ce,
+ 0x0005, 0x00c6, 0x00d6, 0x3900, 0xa082, 0xb0e8, 0x1210, 0x080c,
+ 0x7d8d, 0x7824, 0xa005, 0x090c, 0x14f6, 0x781c, 0xa06d, 0x090c,
+ 0x14f6, 0x6800, 0xc0dc, 0x6802, 0x7924, 0x2160, 0x080c, 0x8078,
+ 0x693c, 0x81ff, 0x090c, 0x14f6, 0x8109, 0x693e, 0x6854, 0xa015,
+ 0x0110, 0x7a1e, 0x0010, 0x7918, 0x791e, 0x7807, 0x0000, 0x7827,
+ 0x0000, 0x00de, 0x00ce, 0x080c, 0x6c50, 0x0888, 0x6104, 0xa186,
+ 0x0002, 0x0128, 0xa186, 0x0004, 0x0110, 0x0804, 0x66f7, 0x7808,
+ 0xac06, 0x0904, 0x66f7, 0x080c, 0x6b73, 0x080c, 0x67ee, 0x00ce,
+ 0x080c, 0x6c50, 0x0804, 0x66e5, 0x00c6, 0x6027, 0x0002, 0x62c8,
+ 0x60c4, 0xa205, 0x1178, 0x793c, 0xa1e5, 0x0000, 0x0130, 0x2009,
+ 0x0049, 0x080c, 0x80a7, 0x00ce, 0x0005, 0x2011, 0xafe6, 0x2013,
+ 0x0000, 0x0cc8, 0x3908, 0xa192, 0xb0e8, 0x1210, 0x080c, 0x7d8d,
+ 0x793c, 0x81ff, 0x0d90, 0x793c, 0xa188, 0x0007, 0x210c, 0xa18e,
+ 0x0006, 0x1138, 0x6014, 0xa084, 0x0184, 0xa085, 0x0012, 0x6016,
+ 0x0c10, 0x6014, 0xa084, 0x0184, 0xa085, 0x0016, 0x6016, 0x08d8,
+ 0x0006, 0x0016, 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000,
+ 0x2c08, 0x2061, 0xafc7, 0x6020, 0x8000, 0x6022, 0x6010, 0xa005,
+ 0x0148, 0xa080, 0x0003, 0x2102, 0x6112, 0x012e, 0x00ce, 0x001e,
+ 0x000e, 0x0005, 0x6116, 0x6112, 0x0cc0, 0x00d6, 0x2069, 0xafc7,
+ 0x6000, 0xd0d4, 0x0168, 0x6820, 0x8000, 0x6822, 0xa086, 0x0001,
+ 0x1110, 0x2c00, 0x681e, 0x6804, 0xa084, 0x0007, 0x0804, 0x6c56,
+ 0xc0d5, 0x6002, 0x6818, 0xa005, 0x0158, 0x6056, 0x605b, 0x0000,
+ 0x0006, 0x2c00, 0x681a, 0x00de, 0x685a, 0x2069, 0xafc7, 0x0c18,
+ 0x6056, 0x605a, 0x2c00, 0x681a, 0x681e, 0x08e8, 0x0006, 0x0016,
+ 0x00c6, 0x0126, 0x2091, 0x8000, 0x600f, 0x0000, 0x2c08, 0x2061,
+ 0xafc7, 0x6020, 0x8000, 0x6022, 0x6008, 0xa005, 0x0148, 0xa080,
+ 0x0003, 0x2102, 0x610a, 0x012e, 0x00ce, 0x001e, 0x000e, 0x0005,
+ 0x610e, 0x610a, 0x0cc0, 0x00c6, 0x600f, 0x0000, 0x2c08, 0x2061,
+ 0xafc7, 0x6034, 0xa005, 0x0130, 0xa080, 0x0003, 0x2102, 0x6136,
+ 0x00ce, 0x0005, 0x613a, 0x6136, 0x0cd8, 0x00f6, 0x00e6, 0x00d6,
+ 0x00c6, 0x0076, 0x0066, 0x0026, 0x0016, 0x0006, 0x0126, 0x2071,
+ 0xafc7, 0x7638, 0x2660, 0x2678, 0x2091, 0x8000, 0x8cff, 0x0904,
+ 0x6889, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904, 0x6884,
+ 0x87ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6884, 0x703c, 0xac06,
+ 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x7033, 0x0000,
+ 0x703f, 0x0000, 0x7043, 0x0000, 0x7047, 0x0000, 0x003e, 0x7038,
+ 0xac36, 0x1110, 0x660c, 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00,
+ 0xaf36, 0x0118, 0x2f00, 0x7036, 0x0010, 0x7037, 0x0000, 0x660c,
+ 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f,
+ 0x0000, 0x080c, 0x9596, 0x0198, 0x6010, 0x2068, 0x601c, 0xa086,
+ 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+ 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c, 0x9742, 0x080c,
+ 0x974e, 0x00ce, 0x0804, 0x682e, 0x2c78, 0x600c, 0x2060, 0x0804,
+ 0x682e, 0x012e, 0x000e, 0x001e, 0x002e, 0x006e, 0x007e, 0x00ce,
+ 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086, 0x0006, 0x19d0,
+ 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x0006, 0x0066, 0x00c6,
+ 0x00d6, 0x00f6, 0x2031, 0x0000, 0x0126, 0x2091, 0x8000, 0x2079,
+ 0xafc7, 0x7838, 0xa065, 0x0558, 0x600c, 0x0006, 0x600f, 0x0000,
+ 0x783c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64,
+ 0x7833, 0x0000, 0x783f, 0x0000, 0x7843, 0x0000, 0x7847, 0x0000,
+ 0x003e, 0x080c, 0x9596, 0x0178, 0x6010, 0x2068, 0x601c, 0xa086,
+ 0x0003, 0x11b0, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c,
+ 0x510c, 0x080c, 0x9742, 0x080c, 0x974e, 0x000e, 0x0898, 0x7e3a,
+ 0x7e36, 0x012e, 0x00fe, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005,
+ 0x601c, 0xa086, 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c60, 0x0016,
+ 0x0026, 0x0086, 0x2041, 0x0000, 0x0099, 0x080c, 0x69a9, 0x008e,
+ 0x002e, 0x001e, 0x0005, 0x00f6, 0x0126, 0x2079, 0xafc7, 0x2091,
+ 0x8000, 0x080c, 0x6a36, 0x080c, 0x6aa8, 0x012e, 0x00fe, 0x0005,
+ 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0066, 0x0016, 0x0006, 0x0126,
+ 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x8cff,
+ 0x0904, 0x6985, 0x6018, 0xa080, 0x0028, 0x2004, 0xa206, 0x1904,
+ 0x6980, 0x88ff, 0x0120, 0x6050, 0xa106, 0x1904, 0x6980, 0x7024,
+ 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c,
+ 0x6581, 0x080c, 0x7834, 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7027,
+ 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120,
+ 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100, 0x6824, 0xd084,
+ 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003, 0x0009, 0x630a,
+ 0x04b8, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616, 0x7010, 0xac36,
+ 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012, 0x0010, 0x7013,
+ 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008,
+ 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c, 0x9596, 0x0188,
+ 0x601c, 0xa086, 0x0003, 0x1510, 0x6837, 0x0103, 0x6b4a, 0x6847,
+ 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa, 0x080c, 0x510c, 0x080c,
+ 0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804, 0x690f,
+ 0x2c78, 0x600c, 0x2060, 0x0804, 0x690f, 0x012e, 0x000e, 0x001e,
+ 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+ 0x0006, 0x1128, 0x080c, 0xabfa, 0x080c, 0xa91f, 0x0c10, 0x601c,
+ 0xa086, 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x0968, 0x08c8,
+ 0x601c, 0xa086, 0x0005, 0x19a8, 0x6004, 0xa086, 0x0085, 0x0d50,
+ 0x0880, 0x00c6, 0x0006, 0x0126, 0x2091, 0x8000, 0xa280, 0xae34,
+ 0x2004, 0xa065, 0x0904, 0x6a32, 0x00f6, 0x00e6, 0x00d6, 0x0066,
+ 0x2071, 0xafc7, 0x6654, 0x7018, 0xac06, 0x1108, 0x761a, 0x701c,
+ 0xac06, 0x1130, 0x86ff, 0x1118, 0x7018, 0x701e, 0x0008, 0x761e,
+ 0x6058, 0xa07d, 0x0108, 0x7e56, 0xa6ed, 0x0000, 0x0110, 0x2f00,
+ 0x685a, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4, 0xc0dc,
+ 0x6002, 0x080c, 0x4c07, 0x0904, 0x6a2e, 0x7624, 0x86ff, 0x05e8,
+ 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069, 0x0100,
+ 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834, 0x68c3,
+ 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+ 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+ 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+ 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e, 0x2660,
+ 0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660, 0x6003,
+ 0x0009, 0x630a, 0x00ce, 0x0804, 0x69d9, 0x8dff, 0x0158, 0x6837,
+ 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0xabfa,
+ 0x080c, 0x510c, 0x080c, 0x7b88, 0x0804, 0x69d9, 0x006e, 0x00de,
+ 0x00ee, 0x00fe, 0x012e, 0x000e, 0x00ce, 0x0005, 0x0006, 0x0066,
+ 0x00c6, 0x00d6, 0x2031, 0x0000, 0x7814, 0xa065, 0x0904, 0x6a88,
+ 0x600c, 0x0006, 0x600f, 0x0000, 0x7824, 0xac06, 0x1540, 0x2069,
+ 0x0100, 0x68c0, 0xa005, 0x01f0, 0x080c, 0x6581, 0x080c, 0x7834,
+ 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069,
+ 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
+ 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+ 0x003e, 0x0028, 0x6003, 0x0009, 0x630a, 0x2c30, 0x00b0, 0x6010,
+ 0x2068, 0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11b8,
+ 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+ 0x9742, 0x080c, 0x974e, 0x080c, 0x7b88, 0x000e, 0x0804, 0x6a3d,
+ 0x7e16, 0x7e12, 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x601c,
+ 0xa086, 0x0006, 0x1118, 0x080c, 0xa91f, 0x0c58, 0x601c, 0xa086,
+ 0x0002, 0x1128, 0x6004, 0xa086, 0x0085, 0x09d0, 0x0c10, 0x601c,
+ 0xa086, 0x0005, 0x19f0, 0x6004, 0xa086, 0x0085, 0x0d60, 0x08c8,
+ 0x0006, 0x0066, 0x00c6, 0x00d6, 0x7818, 0xa065, 0x0904, 0x6b0e,
+ 0x6054, 0x0006, 0x6057, 0x0000, 0x605b, 0x0000, 0x6000, 0xc0d4,
+ 0xc0dc, 0x6002, 0x080c, 0x4c07, 0x0904, 0x6b0b, 0x7e24, 0x86ff,
+ 0x05e8, 0xa680, 0x0004, 0x2004, 0xad06, 0x15c0, 0x00d6, 0x2069,
+ 0x0100, 0x68c0, 0xa005, 0x0548, 0x080c, 0x6581, 0x080c, 0x7834,
+ 0x68c3, 0x0000, 0x080c, 0x7ca8, 0x7827, 0x0000, 0x0036, 0x2069,
+ 0x0140, 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803,
+ 0x0000, 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001,
+ 0x003e, 0x00de, 0x00c6, 0x603c, 0xa005, 0x0110, 0x8001, 0x603e,
+ 0x2660, 0x080c, 0x974e, 0x00ce, 0x0048, 0x00de, 0x00c6, 0x2660,
+ 0x6003, 0x0009, 0x630a, 0x00ce, 0x0804, 0x6aba, 0x8dff, 0x0138,
+ 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c,
+ 0x7b88, 0x0804, 0x6aba, 0x000e, 0x0804, 0x6aad, 0x781e, 0x781a,
+ 0x00de, 0x00ce, 0x006e, 0x000e, 0x0005, 0x00e6, 0x00d6, 0x0066,
+ 0x6000, 0xd0dc, 0x0188, 0x604c, 0xa06d, 0x0170, 0x6848, 0xa606,
+ 0x1158, 0x2071, 0xafc7, 0x7024, 0xa035, 0x0130, 0xa080, 0x0004,
+ 0x2004, 0xad06, 0x1108, 0x0021, 0x006e, 0x00de, 0x00ee, 0x0005,
+ 0x00f6, 0x2079, 0x0100, 0x78c0, 0xa005, 0x1138, 0x00c6, 0x2660,
+ 0x6003, 0x0009, 0x630a, 0x00ce, 0x04a0, 0x080c, 0x7834, 0x78c3,
+ 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2079, 0x0140,
+ 0x7b04, 0xa384, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000,
+ 0x2079, 0x0100, 0x7824, 0xd084, 0x0110, 0x7827, 0x0001, 0x080c,
+ 0x7ca8, 0x003e, 0x080c, 0x4c07, 0x00c6, 0x603c, 0xa005, 0x0110,
+ 0x8001, 0x603e, 0x2660, 0x080c, 0x8078, 0x00ce, 0x6837, 0x0103,
+ 0x6b4a, 0x6847, 0x0000, 0x080c, 0x97fd, 0x080c, 0x510c, 0x080c,
+ 0x7b88, 0x00fe, 0x0005, 0x00e6, 0x00c6, 0x2071, 0xafc7, 0x7004,
+ 0xa084, 0x0007, 0x0002, 0x6b85, 0x6b88, 0x6b9e, 0x6bb7, 0x6bf0,
+ 0x6b85, 0x6b83, 0x6b83, 0x080c, 0x14f6, 0x00ce, 0x00ee, 0x0005,
+ 0x7024, 0xa065, 0x0148, 0x7020, 0x8001, 0x7022, 0x600c, 0xa015,
+ 0x0150, 0x7216, 0x600f, 0x0000, 0x7007, 0x0000, 0x7027, 0x0000,
+ 0x00ce, 0x00ee, 0x0005, 0x7216, 0x7212, 0x0cb0, 0x6018, 0x2060,
+ 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x7020, 0x8001, 0x7022,
+ 0x0120, 0x6054, 0xa015, 0x0140, 0x721e, 0x7007, 0x0000, 0x7027,
+ 0x0000, 0x00ce, 0x00ee, 0x0005, 0x7218, 0x721e, 0x0cb0, 0x7024,
+ 0xa065, 0x0598, 0x700c, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c,
+ 0xa015, 0x0120, 0x720e, 0x600f, 0x0000, 0x0428, 0x720e, 0x720a,
+ 0x0410, 0x7014, 0xac06, 0x1160, 0x080c, 0x7b88, 0x600c, 0xa015,
+ 0x0120, 0x7216, 0x600f, 0x0000, 0x00b0, 0x7216, 0x7212, 0x0098,
+ 0x6018, 0x2060, 0x080c, 0x4c07, 0x6000, 0xc0dc, 0x6002, 0x080c,
+ 0x7b88, 0x701c, 0xa065, 0x0138, 0x6054, 0xa015, 0x0110, 0x721e,
+ 0x0010, 0x7218, 0x721e, 0x7027, 0x0000, 0x00ce, 0x00ee, 0x0005,
+ 0x7024, 0xa065, 0x0140, 0x080c, 0x7b88, 0x600c, 0xa015, 0x0150,
+ 0x720e, 0x600f, 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x00ce,
+ 0x00ee, 0x0005, 0x720e, 0x720a, 0x0cb0, 0x00d6, 0x2069, 0xafc7,
+ 0x6830, 0xa084, 0x0003, 0x0002, 0x6c12, 0x6c14, 0x6c38, 0x6c10,
+ 0x080c, 0x14f6, 0x00de, 0x0005, 0x00c6, 0x6840, 0xa086, 0x0001,
+ 0x01b8, 0x683c, 0xa065, 0x0130, 0x600c, 0xa015, 0x0170, 0x6a3a,
+ 0x600f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000, 0x2011, 0xafe6,
+ 0x2013, 0x0000, 0x00ce, 0x00de, 0x0005, 0x683a, 0x6836, 0x0c90,
+ 0x6843, 0x0000, 0x6838, 0xa065, 0x0d68, 0x6003, 0x0003, 0x0c50,
+ 0x00c6, 0x6843, 0x0000, 0x6847, 0x0000, 0x683c, 0xa065, 0x0168,
+ 0x600c, 0xa015, 0x0130, 0x6a3a, 0x600f, 0x0000, 0x683f, 0x0000,
+ 0x0020, 0x683f, 0x0000, 0x683a, 0x6836, 0x00ce, 0x00de, 0x0005,
+ 0x00d6, 0x2069, 0xafc7, 0x6804, 0xa084, 0x0007, 0x0002, 0x6c61,
+ 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cff, 0x6c5f, 0x6c5f, 0x080c,
+ 0x14f6, 0x6820, 0xa005, 0x1110, 0x00de, 0x0005, 0x00c6, 0x680c,
+ 0xa065, 0x0150, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000, 0x080c,
+ 0x6d49, 0x00ce, 0x00de, 0x0005, 0x6814, 0xa065, 0x0150, 0x6807,
+ 0x0001, 0x6826, 0x682b, 0x0000, 0x080c, 0x6d49, 0x00ce, 0x00de,
+ 0x0005, 0x00e6, 0x0036, 0x6a1c, 0xa2f5, 0x0000, 0x0904, 0x6cf9,
+ 0x704c, 0xa00d, 0x0118, 0x7088, 0xa005, 0x01a0, 0x7054, 0xa075,
+ 0x0120, 0xa20e, 0x0904, 0x6cf9, 0x0028, 0x6818, 0xa20e, 0x0904,
+ 0x6cf9, 0x2070, 0x704c, 0xa00d, 0x0d88, 0x7088, 0xa005, 0x1d70,
+ 0x2e00, 0x681e, 0x733c, 0x7038, 0xa302, 0x1e40, 0x080c, 0x804f,
+ 0x0904, 0x6cf9, 0x8318, 0x733e, 0x6112, 0x2e10, 0x621a, 0xa180,
+ 0x0014, 0x2004, 0xa084, 0x00ff, 0x605a, 0xa180, 0x0014, 0x2003,
+ 0x0000, 0xa180, 0x0015, 0x2004, 0xa08a, 0x199a, 0x0210, 0x2001,
+ 0x1999, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x00f6,
+ 0x2c78, 0x71a0, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd1bc,
+ 0x0150, 0x7100, 0xd1f4, 0x0120, 0x7114, 0xa18c, 0x00ff, 0x0040,
+ 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c, 0x00ff,
+ 0x2061, 0x0100, 0x619a, 0x080c, 0x736f, 0x7300, 0xc3dd, 0x7302,
+ 0x6807, 0x0002, 0x2f18, 0x6b26, 0x682b, 0x0000, 0x781f, 0x0003,
+ 0x7803, 0x0001, 0x7807, 0x0040, 0x00fe, 0x00ee, 0x00ce, 0x00de,
+ 0x0005, 0x003e, 0x00ee, 0x00ce, 0x0cd0, 0x00de, 0x0005, 0x00c6,
+ 0x680c, 0xa065, 0x0138, 0x6807, 0x0004, 0x6826, 0x682b, 0x0000,
+ 0x080c, 0x6d49, 0x00ce, 0x00de, 0x0005, 0x00f6, 0x00d6, 0x2069,
+ 0xafc7, 0x6830, 0xa086, 0x0000, 0x11c0, 0x2001, 0xad0c, 0x200c,
+ 0xd1bc, 0x1550, 0x6838, 0xa07d, 0x0180, 0x6833, 0x0001, 0x683e,
+ 0x6847, 0x0000, 0x0126, 0x00f6, 0x2091, 0x2400, 0x002e, 0x080c,
+ 0x1ee6, 0x1130, 0x012e, 0x080c, 0x76a5, 0x00de, 0x00fe, 0x0005,
+ 0x012e, 0xe000, 0x6843, 0x0000, 0x7803, 0x0002, 0x780c, 0xa015,
+ 0x0140, 0x6a3a, 0x780f, 0x0000, 0x6833, 0x0000, 0x683f, 0x0000,
+ 0x0c60, 0x683a, 0x6836, 0x0cc0, 0xc1bc, 0x2102, 0x080c, 0x57d1,
+ 0x0888, 0x601c, 0xa084, 0x000f, 0x000b, 0x0005, 0x6d57, 0x6d5c,
+ 0x7210, 0x732c, 0x6d5c, 0x7210, 0x732c, 0x6d57, 0x6d5c, 0x080c,
+ 0x6b73, 0x080c, 0x6c50, 0x0005, 0x0156, 0x0136, 0x0146, 0x00c6,
+ 0x00f6, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x6118, 0x2178,
+ 0x79a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150,
+ 0x7900, 0xd1f4, 0x0120, 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009,
+ 0x0000, 0x0028, 0xa1f8, 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78,
+ 0x2061, 0x0100, 0x619a, 0xa08a, 0x0040, 0x1a04, 0x6dd0, 0x0033,
+ 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005, 0x6e7c, 0x6ec7,
+ 0x6ef4, 0x6fc1, 0x6fef, 0x6ff7, 0x701d, 0x702e, 0x703f, 0x7047,
+ 0x705d, 0x7047, 0x70b7, 0x702e, 0x70d8, 0x70e0, 0x703f, 0x70e0,
+ 0x70f1, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x6dce,
+ 0x6dce, 0x6dce, 0x6dce, 0x6dce, 0x790d, 0x7932, 0x7947, 0x796a,
+ 0x798b, 0x701d, 0x6dce, 0x701d, 0x7047, 0x6dce, 0x6ef4, 0x6fc1,
+ 0x6dce, 0x7daa, 0x7047, 0x6dce, 0x7dca, 0x7047, 0x6dce, 0x703f,
+ 0x6e75, 0x6de0, 0x6dce, 0x7def, 0x7e64, 0x7f3b, 0x6dce, 0x7f4c,
+ 0x7018, 0x7f68, 0x6dce, 0x79a0, 0x7fc3, 0x6dce, 0x080c, 0x14f6,
+ 0x2100, 0x0033, 0x00fe, 0x00ce, 0x014e, 0x013e, 0x015e, 0x0005,
+ 0x6dde, 0x6dde, 0x6dde, 0x6e14, 0x6e32, 0x6e48, 0x080c, 0x14f6,
+ 0x00d6, 0x20a1, 0x020b, 0x080c, 0x710e, 0x7810, 0x2068, 0x20a3,
+ 0x2414, 0x20a3, 0x0018, 0x20a3, 0x0800, 0x683c, 0x20a2, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x6850,
+ 0x20a2, 0x6854, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3,
+ 0x0018, 0x080c, 0x7821, 0x00de, 0x0005, 0x00d6, 0x7818, 0x2068,
+ 0x68a0, 0x2069, 0xad00, 0x6ad0, 0xd2ac, 0x1110, 0xd0bc, 0x0110,
+ 0xa085, 0x0001, 0x00de, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c,
+ 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x7810, 0xa0e8, 0x000f,
+ 0x6808, 0x20a2, 0x680c, 0x20a2, 0x6810, 0x20a2, 0x6814, 0x20a2,
+ 0x6818, 0x20a2, 0x681c, 0x20a2, 0x60c3, 0x0010, 0x080c, 0x7821,
+ 0x00de, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+ 0x20a3, 0x7800, 0x20a3, 0x0000, 0x7808, 0x8007, 0x20a2, 0x20a3,
+ 0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+ 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200,
+ 0x20a3, 0x0000, 0x20a3, 0xdf10, 0x20a3, 0x0034, 0x2099, 0xad05,
+ 0x20a9, 0x0004, 0x53a6, 0x2099, 0xad01, 0x20a9, 0x0004, 0x53a6,
+ 0x2099, 0xafad, 0x20a9, 0x001a, 0x3304, 0x8007, 0x20a2, 0x9398,
+ 0x1f04, 0x6e64, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x004c,
+ 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x2001, 0xad14, 0x2004,
+ 0x609a, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+ 0x20a3, 0x5200, 0x20a3, 0x0000, 0x00d6, 0x2069, 0xad51, 0x6804,
+ 0xd084, 0x0150, 0x6828, 0x20a3, 0x0000, 0x0016, 0x080c, 0x268a,
+ 0x21a2, 0x001e, 0x00de, 0x0028, 0x00de, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+ 0x2099, 0xad01, 0x53a6, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1138,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xa082, 0x007f, 0x0238, 0x2001,
+ 0xad1b, 0x20a6, 0x2001, 0xad1c, 0x20a6, 0x0040, 0x20a3, 0x0000,
+ 0x2001, 0xad14, 0x2004, 0xa084, 0x00ff, 0x20a2, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x710e, 0x20a3, 0x0500, 0x20a3, 0x0000, 0x2001,
+ 0xad34, 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0xa082, 0x007f, 0x0238, 0x2001, 0xad1b, 0x20a6, 0x2001, 0xad1c,
+ 0x20a6, 0x0040, 0x20a3, 0x0000, 0x2001, 0xad14, 0x2004, 0xa084,
+ 0x00ff, 0x20a2, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x60c3,
+ 0x0010, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e,
+ 0x00c6, 0x7818, 0x2060, 0x2001, 0x0000, 0x080c, 0x5037, 0x00ce,
+ 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1130, 0x20a3,
+ 0x0400, 0x620c, 0xc2b4, 0x620e, 0x0010, 0x20a3, 0x0300, 0x20a3,
+ 0x0000, 0x7818, 0xa080, 0x0028, 0x2004, 0xa086, 0x007e, 0x1904,
+ 0x6f83, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x01c8, 0x2099, 0xaf8d,
+ 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x3304, 0xa084, 0x2000,
+ 0x20a2, 0x9398, 0x33a6, 0x9398, 0x20a3, 0x0000, 0x9398, 0x2001,
+ 0x2710, 0x20a2, 0x9398, 0x33a6, 0x9398, 0x33a6, 0x00d0, 0x2099,
+ 0xaf8d, 0x33a6, 0x9398, 0x33a6, 0x9398, 0x3304, 0x080c, 0x574f,
+ 0x1118, 0xa084, 0x37ff, 0x0010, 0xa084, 0x3fff, 0x20a2, 0x9398,
+ 0x33a6, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a9, 0x0004, 0x2099, 0xad05, 0x53a6, 0x20a9, 0x0004,
+ 0x2099, 0xad01, 0x53a6, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04,
+ 0x6f5d, 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6f63, 0x2099,
+ 0xaf95, 0x3304, 0xc0dd, 0x20a2, 0x2001, 0xad71, 0x2004, 0xd0e4,
+ 0x0158, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x9398, 0x9398, 0x9398,
+ 0x33a6, 0x20a9, 0x0004, 0x0010, 0x20a9, 0x0007, 0x20a3, 0x0000,
+ 0x1f04, 0x6f7e, 0x0468, 0x2001, 0xad34, 0x2004, 0xd0a4, 0x0140,
+ 0x2001, 0xaf8e, 0x2004, 0x60e3, 0x0000, 0x080c, 0x26cb, 0x60e2,
+ 0x2099, 0xaf8d, 0x20a9, 0x0008, 0x53a6, 0x20a9, 0x0004, 0x2099,
+ 0xad05, 0x53a6, 0x20a9, 0x0004, 0x2099, 0xad01, 0x53a6, 0x20a9,
+ 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fa1, 0x20a9, 0x0008, 0x20a3,
+ 0x0000, 0x1f04, 0x6fa7, 0x2099, 0xaf95, 0x20a9, 0x0008, 0x53a6,
+ 0x20a9, 0x0008, 0x20a3, 0x0000, 0x1f04, 0x6fb2, 0x20a9, 0x000a,
+ 0x20a3, 0x0000, 0x1f04, 0x6fb8, 0x60c3, 0x0074, 0x080c, 0x7821,
+ 0x0005, 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x2010, 0x20a3,
+ 0x0014, 0x20a3, 0x0800, 0x20a3, 0x2000, 0xa006, 0x20a2, 0x20a2,
+ 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51, 0x7904, 0x00fe,
+ 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110, 0xa085, 0x0010,
+ 0xa085, 0x0002, 0x00d6, 0x0804, 0x7099, 0x20a2, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x710e, 0x20a3, 0x5000, 0x0804, 0x6f0f, 0x20a1,
+ 0x020b, 0x080c, 0x710e, 0x20a3, 0x2110, 0x20a3, 0x0014, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005,
+ 0x20a1, 0x020b, 0x080c, 0x71a2, 0x0020, 0x20a1, 0x020b, 0x080c,
+ 0x71aa, 0x20a3, 0x0200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b,
+ 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0003,
+ 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6f0f, 0x20a1,
+ 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x7828,
+ 0xa005, 0x0110, 0x20a2, 0x0010, 0x20a3, 0x0003, 0x7810, 0x20a2,
+ 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x00d6, 0x20a1, 0x020b,
+ 0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3, 0x0800,
+ 0x7818, 0x2068, 0x6894, 0xa086, 0x0014, 0x1178, 0x6998, 0xa184,
+ 0xc000, 0x1140, 0xd1ec, 0x0118, 0x20a3, 0x2100, 0x0040, 0x20a3,
+ 0x0100, 0x0028, 0x20a3, 0x0400, 0x0010, 0x20a3, 0x0700, 0xa006,
+ 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x00f6, 0x2079, 0xad51,
+ 0x7904, 0x00fe, 0xd1ac, 0x1110, 0xa085, 0x0020, 0xd1a4, 0x0110,
+ 0xa085, 0x0010, 0x2009, 0xad73, 0x210c, 0xd184, 0x1110, 0xa085,
+ 0x0002, 0x0026, 0x2009, 0xad71, 0x210c, 0xd1e4, 0x0130, 0xc0c5,
+ 0xa094, 0x0030, 0xa296, 0x0010, 0x0140, 0xd1ec, 0x0130, 0xa094,
+ 0x0030, 0xa296, 0x0010, 0x0108, 0xc0bd, 0x002e, 0x20a2, 0x20a2,
+ 0x20a2, 0x60c3, 0x0014, 0x080c, 0x7821, 0x00de, 0x0005, 0x20a1,
+ 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0210, 0x20a3, 0x0014, 0x20a3,
+ 0x0000, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x0014, 0x080c, 0x7821, 0x0005,
+ 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x0804, 0x6e82,
+ 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x20a3, 0x0003, 0x20a3, 0x2a00, 0x60c3, 0x0008, 0x080c, 0x7821,
+ 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x20a1, 0x020b, 0x080c,
+ 0x71aa, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0x000b, 0x20a3,
+ 0x0000, 0x60c3, 0x0008, 0x080c, 0x7821, 0x0005, 0x0026, 0x0036,
+ 0x0046, 0x2019, 0x3200, 0x2021, 0x0800, 0x0038, 0x0026, 0x0036,
+ 0x0046, 0x2019, 0x2200, 0x2021, 0x0100, 0x20e1, 0x9080, 0x20e1,
+ 0x4000, 0x7818, 0xa080, 0x0028, 0x2014, 0xa286, 0x007e, 0x11a0,
+ 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffe, 0x20a3, 0x0000, 0x2011,
+ 0xad14, 0x2214, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x0118, 0x2011,
+ 0xad1c, 0x2214, 0x22a2, 0x04d0, 0xa286, 0x007f, 0x1138, 0x00d6,
+ 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffd, 0x00c8, 0x2001, 0xad34,
+ 0x2004, 0xd0ac, 0x1110, 0xd2bc, 0x01c8, 0xa286, 0x0080, 0x00d6,
+ 0x1130, 0xa385, 0x00ff, 0x20a2, 0x20a3, 0xfffc, 0x0040, 0xa2e8,
+ 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x2069,
+ 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa2e8,
+ 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de,
+ 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0029,
+ 0x20a2, 0x004e, 0x003e, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+ 0x20a3, 0x0000, 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x002e, 0x0005, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000,
+ 0x20a3, 0x02ff, 0x2011, 0xfffc, 0x22a2, 0x00d6, 0x2069, 0xad1b,
+ 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x20a3, 0x2029, 0x20a3, 0x0000,
+ 0x08e0, 0x20a3, 0x0100, 0x20a3, 0x0000, 0x20a3, 0xfc02, 0x20a3,
+ 0x0000, 0x0005, 0x0026, 0x0036, 0x0046, 0x2019, 0x3300, 0x2021,
+ 0x0800, 0x0038, 0x0026, 0x0036, 0x0046, 0x2019, 0x2300, 0x2021,
+ 0x0100, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+ 0x02d8, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa305, 0x20a2,
+ 0x6814, 0x20a2, 0x6810, 0xa005, 0x1140, 0x6814, 0xa005, 0x1128,
+ 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x0028, 0x2069, 0xad1b, 0x2da6,
+ 0x8d68, 0x2da6, 0x00de, 0x0080, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+ 0x6810, 0xa305, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+ 0x2011, 0xad14, 0x2214, 0x22a2, 0xa485, 0x0098, 0x20a2, 0x20a3,
+ 0x0000, 0x004e, 0x003e, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000,
+ 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e,
+ 0x0005, 0x080c, 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2,
+ 0x7810, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005,
+ 0x00c6, 0x00f6, 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a,
+ 0x008c, 0x1a0c, 0x14f6, 0x6118, 0x2178, 0x79a0, 0x2011, 0xad34,
+ 0x2214, 0xd2ac, 0x1110, 0xd1bc, 0x0150, 0x7900, 0xd1f4, 0x0120,
+ 0x7914, 0xa18c, 0x00ff, 0x0040, 0x2009, 0x0000, 0x0028, 0xa1f8,
+ 0x2be6, 0x2f0d, 0xa18c, 0x00ff, 0x2c78, 0x2061, 0x0100, 0x619a,
+ 0xa082, 0x0085, 0x001b, 0x00fe, 0x00ce, 0x0005, 0x7247, 0x7251,
+ 0x726c, 0x7245, 0x7245, 0x7245, 0x7247, 0x080c, 0x14f6, 0x0146,
+ 0x20a1, 0x020b, 0x04a1, 0x60c3, 0x0000, 0x080c, 0x7821, 0x014e,
+ 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c, 0x72b8, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x7808, 0x20a2, 0x7810, 0x20a2, 0x20a3, 0x0000,
+ 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+ 0x080c, 0x7821, 0x014e, 0x0005, 0x0146, 0x20a1, 0x020b, 0x080c,
+ 0x72f2, 0x20a3, 0x0003, 0x20a3, 0x0300, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x60c3, 0x0004, 0x080c, 0x7821, 0x014e, 0x0005, 0x0026,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e, 0x0288,
+ 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+ 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8100,
+ 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+ 0x2214, 0x22a2, 0x20a3, 0x0009, 0x20a3, 0x0000, 0x0804, 0x7175,
+ 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118, 0xa092, 0x007e,
+ 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x8400,
+ 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+ 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+ 0x8400, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011,
+ 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2, 0x20a3, 0x0000,
+ 0x0804, 0x7201, 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+ 0xa092, 0x007e, 0x0288, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+ 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6,
+ 0x8d68, 0x2da6, 0x00de, 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c,
+ 0x6810, 0xa085, 0x8500, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3,
+ 0x0000, 0x2011, 0xad14, 0x2214, 0x22a2, 0x2001, 0x0099, 0x20a2,
+ 0x20a3, 0x0000, 0x0804, 0x7201, 0x00c6, 0x00f6, 0x2c78, 0x7804,
+ 0xa08a, 0x0040, 0x0a0c, 0x14f6, 0xa08a, 0x0053, 0x1a0c, 0x14f6,
+ 0x7918, 0x2160, 0x61a0, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+ 0xd1bc, 0x0150, 0x6100, 0xd1f4, 0x0120, 0x6114, 0xa18c, 0x00ff,
+ 0x0040, 0x2009, 0x0000, 0x0028, 0xa1e0, 0x2be6, 0x2c0d, 0xa18c,
+ 0x00ff, 0x2061, 0x0100, 0x619a, 0xa082, 0x0040, 0x001b, 0x00fe,
+ 0x00ce, 0x0005, 0x736f, 0x747b, 0x7418, 0x761a, 0x736d, 0x736d,
+ 0x736d, 0x736d, 0x736d, 0x736d, 0x736d, 0x7b41, 0x7b51, 0x7b61,
+ 0x7b71, 0x736d, 0x7f79, 0x736d, 0x7b30, 0x080c, 0x14f6, 0x00d6,
+ 0x0156, 0x0146, 0x780b, 0xffff, 0x20a1, 0x020b, 0x080c, 0x73cf,
+ 0x7910, 0x2168, 0x6948, 0x7952, 0x21a2, 0xa016, 0x22a2, 0x22a2,
+ 0x22a2, 0x694c, 0xa184, 0x000f, 0x1118, 0x2001, 0x0005, 0x0040,
+ 0xd184, 0x0118, 0x2001, 0x0004, 0x0018, 0xa084, 0x0006, 0x8004,
+ 0x0016, 0x2008, 0x7858, 0xa084, 0x00ff, 0x8007, 0xa105, 0x001e,
+ 0x20a2, 0xd1ac, 0x0118, 0x20a3, 0x0002, 0x0048, 0xd1b4, 0x0118,
+ 0x20a3, 0x0001, 0x0020, 0x20a3, 0x0000, 0x2230, 0x0010, 0x6a80,
+ 0x6e7c, 0x20a9, 0x0008, 0x0136, 0xad88, 0x0017, 0x2198, 0x20a1,
+ 0x021b, 0x53a6, 0x013e, 0x20a1, 0x020b, 0x22a2, 0x26a2, 0x60c3,
+ 0x0020, 0x20e1, 0x9080, 0x6014, 0xa084, 0x0004, 0xa085, 0x0009,
+ 0x6016, 0x2001, 0xafe3, 0x2003, 0x07d0, 0x2001, 0xafe2, 0x2003,
+ 0x0009, 0x080c, 0x17bf, 0x014e, 0x015e, 0x00de, 0x0005, 0x20e1,
+ 0x9080, 0x20e1, 0x4000, 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210,
+ 0xa294, 0x00ff, 0x2202, 0x8217, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0x2019, 0xad34, 0x231c, 0xd3ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+ 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+ 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0600, 0x20a2,
+ 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2009, 0xad14, 0x210c,
+ 0x21a2, 0x20a3, 0x0829, 0x20a3, 0x0000, 0x22a2, 0x20a3, 0x0000,
+ 0x2fa2, 0x20a3, 0xffff, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x0005,
+ 0x00d6, 0x0156, 0x0136, 0x0146, 0x20a1, 0x020b, 0x00c1, 0x7810,
+ 0x2068, 0x6860, 0x20a2, 0x685c, 0x20a2, 0x6880, 0x20a2, 0x687c,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x60c3, 0x000c,
+ 0x080c, 0x7821, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005, 0x0026,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028, 0x2004,
+ 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188, 0x00d6,
+ 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2, 0x6814,
+ 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de, 0x0088,
+ 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0500, 0x20a2,
+ 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14, 0x2214,
+ 0x22a2, 0x20a3, 0x0889, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2,
+ 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x7810,
+ 0xa06d, 0x080c, 0x5025, 0x0148, 0x684c, 0xa084, 0x2020, 0xa086,
+ 0x2020, 0x1118, 0x7820, 0xc0cd, 0x7822, 0x20a1, 0x020b, 0x080c,
+ 0x75d0, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x7810,
+ 0xa084, 0xf000, 0x1130, 0x7810, 0xa084, 0x0700, 0x8007, 0x0043,
+ 0x0010, 0xa006, 0x002b, 0x014e, 0x013e, 0x015e, 0x00de, 0x0005,
+ 0x74b2, 0x7547, 0x7550, 0x7579, 0x758c, 0x75a7, 0x75b0, 0x74b0,
+ 0x080c, 0x14f6, 0x0016, 0x0036, 0x694c, 0xa18c, 0x0003, 0x0118,
+ 0xa186, 0x0003, 0x1170, 0x6b78, 0x7820, 0xd0cc, 0x0108, 0xc3e5,
+ 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x003e, 0x001e, 0x0804,
+ 0x7583, 0xa186, 0x0001, 0x190c, 0x14f6, 0x6b78, 0x7820, 0xd0cc,
+ 0x0108, 0xc3e5, 0x23a2, 0x6868, 0x20a2, 0x6864, 0x20a2, 0x22a2,
+ 0x6874, 0x20a2, 0x22a2, 0x687c, 0x20a2, 0x2009, 0x0018, 0xa384,
+ 0x0300, 0x0904, 0x7541, 0xd3c4, 0x0110, 0x687c, 0xa108, 0xd3cc,
+ 0x0110, 0x6874, 0xa108, 0x0156, 0x20a9, 0x000d, 0xad80, 0x0020,
+ 0x201c, 0x831f, 0x23a2, 0x8000, 0x1f04, 0x74f0, 0x015e, 0x22a2,
+ 0x22a2, 0x22a2, 0xa184, 0x0003, 0x0904, 0x7541, 0x20a1, 0x020b,
+ 0x20e1, 0x9080, 0x20e1, 0x4000, 0x0006, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+ 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+ 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+ 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+ 0x2214, 0x22a2, 0x000e, 0x7b20, 0xd3cc, 0x0118, 0x20a3, 0x0889,
+ 0x0010, 0x20a3, 0x0898, 0x20a2, 0x080c, 0x7810, 0x22a2, 0x20a3,
+ 0x0000, 0x61c2, 0x003e, 0x001e, 0x080c, 0x7821, 0x0005, 0x2011,
+ 0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0488,
+ 0x2011, 0x0302, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016,
+ 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x0012, 0x22a2, 0x20a3, 0x0008,
+ 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x20a3, 0x7000, 0x20a3, 0x0500,
+ 0x22a2, 0x20a3, 0x000a, 0x22a2, 0x22a2, 0x20a3, 0x2500, 0x22a2,
+ 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0032, 0x080c, 0x7821,
+ 0x0005, 0x2011, 0x0028, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2,
+ 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x22a2, 0x60c3,
+ 0x0018, 0x080c, 0x7821, 0x0005, 0x2011, 0x0100, 0x7820, 0xd0cc,
+ 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x22a2, 0x22a2, 0x22a2, 0x22a2,
+ 0x22a2, 0x20a3, 0x0008, 0x22a2, 0x7854, 0xa084, 0x00ff, 0x20a2,
+ 0x22a2, 0x22a2, 0x60c3, 0x0020, 0x080c, 0x7821, 0x0005, 0x2011,
+ 0x0008, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0xa016, 0x0888,
+ 0x0036, 0x7b10, 0xa384, 0xff00, 0x7812, 0xa384, 0x00ff, 0x8001,
+ 0x1138, 0x7820, 0xd0cc, 0x0108, 0xc2e5, 0x22a2, 0x003e, 0x0808,
+ 0x0046, 0x2021, 0x0800, 0x0006, 0x7820, 0xd0cc, 0x000e, 0x0108,
+ 0xc4e5, 0x24a2, 0x004e, 0x22a2, 0x20a2, 0x003e, 0x0804, 0x7583,
+ 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+ 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+ 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0700,
+ 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+ 0x2214, 0x22a2, 0x7820, 0xd0cc, 0x0118, 0x20a3, 0x0889, 0x0010,
+ 0x20a3, 0x0898, 0x20a3, 0x0000, 0x080c, 0x7810, 0x22a2, 0x20a3,
+ 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x002e, 0x0005, 0x00d6, 0x0156, 0x0136, 0x0146, 0x0016, 0x0036,
+ 0x7810, 0xa084, 0x0700, 0x8007, 0x003b, 0x003e, 0x001e, 0x014e,
+ 0x013e, 0x015e, 0x00de, 0x0005, 0x7634, 0x7634, 0x7636, 0x7634,
+ 0x7634, 0x7634, 0x7658, 0x7634, 0x080c, 0x14f6, 0x7910, 0xa18c,
+ 0xf8ff, 0xa18d, 0x0600, 0x7912, 0x20a1, 0x020b, 0x2009, 0x0003,
+ 0x00f9, 0x00d6, 0x2069, 0xad51, 0x6804, 0xd0bc, 0x0130, 0x682c,
+ 0xa084, 0x00ff, 0x8007, 0x20a2, 0x0010, 0x20a3, 0x3f00, 0x00de,
+ 0x22a2, 0x22a2, 0x22a2, 0x60c3, 0x0001, 0x080c, 0x7821, 0x0005,
+ 0x20a1, 0x020b, 0x2009, 0x0003, 0x0019, 0x20a3, 0x7f00, 0x0c80,
+ 0x0026, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818, 0xa080, 0x0028,
+ 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110, 0xd0bc, 0x0188,
+ 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100, 0x20a2,
+ 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6, 0x00de,
+ 0x0088, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085, 0x0100,
+ 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000, 0x2011, 0xad14,
+ 0x2214, 0x22a2, 0x20a3, 0x0888, 0xa18d, 0x0008, 0x21a2, 0x080c,
+ 0x7810, 0x22a2, 0x20a3, 0x0000, 0x7a08, 0x22a2, 0x2fa2, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+ 0x0056, 0x0046, 0x0036, 0x2061, 0x0100, 0x2071, 0xad00, 0x7150,
+ 0x7818, 0x2068, 0x68a0, 0x2028, 0x76d0, 0xd6ac, 0x1130, 0xd0bc,
+ 0x1120, 0x6910, 0x6a14, 0x7450, 0x0020, 0x6910, 0x6a14, 0x736c,
+ 0x7470, 0x781c, 0xa0be, 0x0006, 0x0904, 0x775b, 0xa0be, 0x000a,
+ 0x15e8, 0xa185, 0x0200, 0x6062, 0x6266, 0x636a, 0x646e, 0x6073,
+ 0x2029, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084, 0x00ff, 0x688e,
+ 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082, 0x7808, 0x6086,
+ 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+ 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+ 0x609f, 0x0000, 0x080c, 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084,
+ 0xfff0, 0xa005, 0x0110, 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e,
+ 0x004e, 0x005e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x70d0, 0xd0ac,
+ 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+ 0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+ 0x646e, 0x6073, 0x0809, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+ 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6082,
+ 0x7808, 0x6086, 0x7810, 0x2070, 0x7014, 0x608a, 0x7010, 0x608e,
+ 0x700c, 0x60c6, 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5,
+ 0x60d7, 0x0000, 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120,
+ 0x6a14, 0xa294, 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c,
+ 0x8014, 0x2009, 0x07d0, 0x60c4, 0xa084, 0xfff0, 0xa005, 0x0110,
+ 0x2009, 0x1b58, 0x080c, 0x6586, 0x003e, 0x004e, 0x005e, 0x00ce,
+ 0x00de, 0x00ee, 0x0005, 0x7810, 0x2070, 0x704c, 0xa084, 0x0003,
+ 0xa086, 0x0002, 0x0904, 0x77b1, 0x2001, 0xad34, 0x2004, 0xd0ac,
+ 0x1110, 0xd5bc, 0x0138, 0xa185, 0x0100, 0x6062, 0x6266, 0x636a,
+ 0x646e, 0x0038, 0xa185, 0x0100, 0x6062, 0x6266, 0x606b, 0x0000,
+ 0x646e, 0x6073, 0x0880, 0x6077, 0x0008, 0x688c, 0x8000, 0xa084,
+ 0x00ff, 0x688e, 0x8007, 0x607a, 0x7834, 0x607e, 0x2f00, 0x6086,
+ 0x7808, 0x6082, 0x7060, 0x608a, 0x705c, 0x608e, 0x7080, 0x60c6,
+ 0x707c, 0x60ca, 0x707c, 0x792c, 0xa108, 0x792e, 0x7080, 0x7928,
+ 0xa109, 0x792a, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+ 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+ 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x080c, 0x8011, 0x0804,
+ 0x7749, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x1110, 0xd5bc, 0x0138,
+ 0xa185, 0x0700, 0x6062, 0x6266, 0x636a, 0x646e, 0x0038, 0xa185,
+ 0x0700, 0x6062, 0x6266, 0x606b, 0x0000, 0x646e, 0x080c, 0x5025,
+ 0x0180, 0x00d6, 0x7810, 0xa06d, 0x684c, 0x00de, 0xa084, 0x2020,
+ 0xa086, 0x2020, 0x1130, 0x7820, 0xc0cd, 0x7822, 0x6073, 0x0889,
+ 0x0010, 0x6073, 0x0898, 0x6077, 0x0000, 0x688c, 0x8000, 0xa084,
+ 0x00ff, 0x688e, 0x8007, 0x607a, 0x607f, 0x0000, 0x2f00, 0x6086,
+ 0x7808, 0x6082, 0x7014, 0x608a, 0x7010, 0x608e, 0x700c, 0x60c6,
+ 0x7008, 0x60ca, 0x686c, 0x60ce, 0x60af, 0x95d5, 0x60d7, 0x0000,
+ 0xa582, 0x0080, 0x0248, 0x6a00, 0xd2f4, 0x0120, 0x6a14, 0xa294,
+ 0x00ff, 0x0010, 0x2011, 0x0000, 0x629e, 0x7820, 0xd0cc, 0x0120,
+ 0x080c, 0x8014, 0x0804, 0x7749, 0x080c, 0x8011, 0x0804, 0x7749,
+ 0x7a18, 0xa280, 0x0023, 0x2014, 0x8210, 0xa294, 0x00ff, 0x2202,
+ 0x8217, 0x0005, 0x00d6, 0x2069, 0xafc7, 0x6843, 0x0001, 0x00de,
+ 0x0005, 0x20e1, 0x9080, 0x60a3, 0x0056, 0x60a7, 0x9575, 0x0019,
+ 0x080c, 0x6578, 0x0005, 0x0006, 0x6014, 0xa084, 0x0004, 0xa085,
+ 0x0009, 0x6016, 0x000e, 0x0005, 0x0006, 0x00c6, 0x2061, 0x0100,
+ 0x6014, 0xa084, 0x0004, 0xa085, 0x0008, 0x6016, 0x00ce, 0x000e,
+ 0x0005, 0x00c6, 0x00d6, 0x0016, 0x0026, 0x2061, 0x0100, 0x2069,
+ 0x0140, 0x080c, 0x574f, 0x1178, 0x2001, 0xafe3, 0x2004, 0xa005,
+ 0x1598, 0x080c, 0x57d1, 0x1118, 0x080c, 0x6578, 0x0468, 0x00c6,
+ 0x2061, 0xafc7, 0x00d8, 0x6904, 0xa194, 0x4000, 0x0550, 0x08a1,
+ 0x6803, 0x1000, 0x6803, 0x0000, 0x00c6, 0x2061, 0xafc7, 0x6128,
+ 0xa192, 0x00c8, 0x1258, 0x8108, 0x612a, 0x6124, 0x00ce, 0x81ff,
+ 0x0198, 0x080c, 0x6578, 0x080c, 0x782b, 0x0070, 0x6124, 0xa1e5,
+ 0x0000, 0x0140, 0x080c, 0xaca2, 0x2009, 0x0014, 0x080c, 0x80a7,
+ 0x080c, 0x6581, 0x00ce, 0x0000, 0x002e, 0x001e, 0x00de, 0x00ce,
+ 0x0005, 0x2001, 0xafe3, 0x2004, 0xa005, 0x1db0, 0x00c6, 0x2061,
+ 0xafc7, 0x6128, 0xa192, 0x0003, 0x1e08, 0x8108, 0x612a, 0x00ce,
+ 0x080c, 0x6578, 0x080c, 0x485e, 0x0c38, 0x00c6, 0x00d6, 0x00e6,
+ 0x0016, 0x0026, 0x080c, 0x658e, 0x2071, 0xafc7, 0x713c, 0x81ff,
+ 0x0570, 0x2061, 0x0100, 0x2069, 0x0140, 0x080c, 0x574f, 0x1188,
+ 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c, 0x2160,
+ 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x080c, 0x57d1,
+ 0x00b0, 0x6904, 0xa194, 0x4000, 0x01c0, 0x6803, 0x1000, 0x6803,
+ 0x0000, 0x0036, 0x2019, 0x0001, 0x080c, 0x7a64, 0x003e, 0x713c,
+ 0x2160, 0x080c, 0xaca2, 0x2009, 0x004a, 0x080c, 0x80a7, 0x002e,
+ 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x0c58, 0x00e6, 0x00d6,
+ 0x00c6, 0x0066, 0x0056, 0x0046, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x6018, 0x2068, 0x6ca0, 0x2071, 0xafc7, 0x7018, 0x2068, 0x8dff,
+ 0x0198, 0x68a0, 0xa406, 0x0118, 0x6854, 0x2068, 0x0cc0, 0x6010,
+ 0x2060, 0x643c, 0x6540, 0x6e48, 0x2d60, 0x080c, 0x4e41, 0x0120,
+ 0x080c, 0x7b88, 0xa085, 0x0001, 0x012e, 0x000e, 0x004e, 0x005e,
+ 0x006e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0x20a1, 0x020b, 0x080c,
+ 0x710e, 0x20a3, 0x1200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x781c,
+ 0xa086, 0x0004, 0x1110, 0x6098, 0x0018, 0x2001, 0xad14, 0x2004,
+ 0x20a2, 0x7834, 0x20a2, 0x7838, 0x20a2, 0x20a9, 0x0010, 0xa006,
+ 0x20a2, 0x1f04, 0x7928, 0x20a2, 0x20a2, 0x60c3, 0x002c, 0x080c,
+ 0x7821, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x710e,
+ 0x20a3, 0x0f00, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808, 0x20a2,
+ 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005, 0x0156,
+ 0x0146, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0200, 0x20a3,
+ 0x0000, 0x20a9, 0x0006, 0x2011, 0xad40, 0x2019, 0xad41, 0x23a6,
+ 0x22a6, 0xa398, 0x0002, 0xa290, 0x0002, 0x1f04, 0x7957, 0x20a3,
+ 0x0000, 0x20a3, 0x0000, 0x60c3, 0x001c, 0x080c, 0x7821, 0x014e,
+ 0x015e, 0x0005, 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b,
+ 0x080c, 0x7183, 0x080c, 0x7199, 0x7810, 0xa080, 0x0000, 0x2004,
+ 0xa080, 0x0015, 0x2098, 0x7808, 0xa088, 0x0002, 0x21a8, 0x53a6,
+ 0xa080, 0x0004, 0x8003, 0x60c2, 0x080c, 0x7821, 0x002e, 0x001e,
+ 0x014e, 0x015e, 0x0005, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c,
+ 0x710e, 0x20a3, 0x6200, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x7808,
+ 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+ 0x0156, 0x0146, 0x0016, 0x0026, 0x20a1, 0x020b, 0x080c, 0x710e,
+ 0x7810, 0xa080, 0x0000, 0x2004, 0xa080, 0x0017, 0x2098, 0x7808,
+ 0xa088, 0x0002, 0x21a8, 0x53a6, 0x8003, 0x60c2, 0x080c, 0x7821,
+ 0x002e, 0x001e, 0x014e, 0x015e, 0x0005, 0x00e6, 0x00c6, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x700c, 0x2060, 0x8cff,
+ 0x0178, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x600c, 0x0006,
+ 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x7b88, 0x00ce, 0x0c78,
+ 0x700f, 0x0000, 0x700b, 0x0000, 0x012e, 0x000e, 0x00ce, 0x00ee,
+ 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0026,
+ 0x0016, 0x0006, 0x2091, 0x8000, 0x2069, 0x0100, 0x2079, 0x0140,
+ 0x2071, 0xafc7, 0x7024, 0x2060, 0x8cff, 0x05a0, 0x080c, 0x7834,
+ 0x68c3, 0x0000, 0x080c, 0x6581, 0x2009, 0x0013, 0x080c, 0x80a7,
+ 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158, 0x6827, 0x0004, 0x7804,
+ 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000, 0x7803, 0x0000, 0x0078,
+ 0xd084, 0x0118, 0x6827, 0x0001, 0x0010, 0x1f04, 0x7a02, 0x7804,
+ 0xa084, 0x1000, 0x0120, 0x7803, 0x0100, 0x7803, 0x0000, 0x6824,
+ 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e,
+ 0x012e, 0x0005, 0x2001, 0xad00, 0x2004, 0xa096, 0x0001, 0x0550,
+ 0xa096, 0x0004, 0x0538, 0x6817, 0x0008, 0x68c3, 0x0000, 0x2011,
+ 0x481b, 0x080c, 0x650d, 0x20a9, 0x01f4, 0x6824, 0xd094, 0x0158,
+ 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0, 0x7803, 0x1000,
+ 0x7803, 0x0000, 0x0078, 0xd084, 0x0118, 0x6827, 0x0001, 0x0010,
+ 0x1f04, 0x7a3d, 0x7804, 0xa084, 0x1000, 0x0120, 0x7803, 0x0100,
+ 0x7803, 0x0000, 0x000e, 0x001e, 0x002e, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x015e, 0x012e, 0x0005, 0x0126, 0x0156, 0x00f6, 0x00e6,
+ 0x00d6, 0x00c6, 0x0026, 0x0016, 0x0006, 0x2091, 0x8000, 0x2069,
+ 0x0100, 0x2079, 0x0140, 0x2071, 0xafc7, 0x703c, 0x2060, 0x8cff,
+ 0x0904, 0x7ad5, 0x6817, 0x0010, 0x2009, 0x00fa, 0x8109, 0x1df0,
+ 0x68c7, 0x0000, 0x68cb, 0x0008, 0x080c, 0x658e, 0x080c, 0x20b5,
+ 0x0046, 0x2009, 0x017f, 0x200b, 0x00a5, 0x2021, 0x0169, 0x2404,
+ 0xa084, 0x000f, 0xa086, 0x0004, 0x11b0, 0x68c7, 0x0000, 0x68cb,
+ 0x0008, 0x00e6, 0x00f6, 0x2079, 0x0020, 0x2071, 0xb01e, 0x6814,
+ 0xa084, 0x0184, 0xa085, 0x0012, 0x6816, 0x7803, 0x0008, 0x7003,
+ 0x0000, 0x00fe, 0x00ee, 0x200b, 0x0000, 0x004e, 0xa39d, 0x0000,
+ 0x1120, 0x2009, 0x0049, 0x080c, 0x80a7, 0x20a9, 0x03e8, 0x6824,
+ 0xd094, 0x0158, 0x6827, 0x0004, 0x7804, 0xa084, 0x4000, 0x01a0,
+ 0x7803, 0x1000, 0x7803, 0x0000, 0x0078, 0xd08c, 0x0118, 0x6827,
+ 0x0002, 0x0010, 0x1f04, 0x7ab7, 0x7804, 0xa084, 0x1000, 0x0120,
+ 0x7803, 0x0100, 0x7803, 0x0000, 0x6824, 0x000e, 0x001e, 0x002e,
+ 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x015e, 0x012e, 0x0005, 0x00d6,
+ 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a06, 0x012e, 0x00de,
+ 0x0005, 0x00d6, 0x0126, 0x2091, 0x8000, 0x2069, 0xafc7, 0x6a32,
+ 0x012e, 0x00de, 0x0005, 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0006,
+ 0x0126, 0x2071, 0xafc7, 0x7614, 0x2660, 0x2678, 0x2091, 0x8000,
+ 0x8cff, 0x0538, 0x601c, 0xa206, 0x1500, 0x7014, 0xac36, 0x1110,
+ 0x660c, 0x7616, 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118,
+ 0x2f00, 0x7012, 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00,
+ 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x080c,
+ 0x974e, 0x080c, 0x7b88, 0x00ce, 0x08d8, 0x2c78, 0x600c, 0x2060,
+ 0x08b8, 0x012e, 0x000e, 0x006e, 0x00ce, 0x00ee, 0x00fe, 0x0005,
+ 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810, 0x20a2,
+ 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x1000, 0x0804,
+ 0x7b80, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x4000,
+ 0x0478, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x2000,
+ 0x00f8, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0400,
+ 0x0078, 0x0156, 0x0146, 0x20a1, 0x020b, 0x080c, 0x73cf, 0x7810,
+ 0x20a2, 0xa006, 0x20a2, 0x20a2, 0x20a2, 0x20a2, 0x20a3, 0x0200,
+ 0x0089, 0x60c3, 0x0020, 0x080c, 0x7821, 0x014e, 0x015e, 0x0005,
+ 0x00e6, 0x2071, 0xafc7, 0x7020, 0xa005, 0x0110, 0x8001, 0x7022,
+ 0x00ee, 0x0005, 0x20a9, 0x0008, 0x20a2, 0x1f04, 0x7b94, 0x20a2,
+ 0x20a2, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6, 0x0076, 0x0066,
+ 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x7614, 0x2660,
+ 0x2678, 0x2039, 0x0001, 0x87ff, 0x0904, 0x7c24, 0x8cff, 0x0904,
+ 0x7c24, 0x601c, 0xa086, 0x0006, 0x1904, 0x7c1f, 0x88ff, 0x0138,
+ 0x2800, 0xac06, 0x1904, 0x7c1f, 0x2039, 0x0000, 0x0050, 0x6018,
+ 0xa206, 0x1904, 0x7c1f, 0x85ff, 0x0120, 0x6050, 0xa106, 0x1904,
+ 0x7c1f, 0x7024, 0xac06, 0x1538, 0x2069, 0x0100, 0x68c0, 0xa005,
+ 0x01f0, 0x080c, 0x6581, 0x6817, 0x0008, 0x68c3, 0x0000, 0x080c,
+ 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140, 0x6b04, 0xa384,
+ 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000, 0x2069, 0x0100,
+ 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e, 0x0020, 0x6003,
+ 0x0009, 0x630a, 0x0460, 0x7014, 0xac36, 0x1110, 0x660c, 0x7616,
+ 0x7010, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7012,
+ 0x0010, 0x7013, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+ 0x7e0e, 0x0008, 0x2678, 0x89ff, 0x1158, 0x600f, 0x0000, 0x6010,
+ 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e,
+ 0x080c, 0x7b88, 0x88ff, 0x1190, 0x00ce, 0x0804, 0x7bab, 0x2c78,
+ 0x600c, 0x2060, 0x0804, 0x7bab, 0xa006, 0x012e, 0x000e, 0x006e,
+ 0x007e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x6017, 0x0000,
+ 0x00ce, 0xa8c5, 0x0001, 0x0c88, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+ 0x0066, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7,
+ 0x7638, 0x2660, 0x2678, 0x8cff, 0x0904, 0x7c98, 0x601c, 0xa086,
+ 0x0006, 0x1904, 0x7c93, 0x87ff, 0x0128, 0x2700, 0xac06, 0x1904,
+ 0x7c93, 0x0040, 0x6018, 0xa206, 0x15f0, 0x85ff, 0x0118, 0x6050,
+ 0xa106, 0x15c8, 0x703c, 0xac06, 0x1170, 0x0036, 0x2019, 0x0001,
+ 0x080c, 0x7a64, 0x7033, 0x0000, 0x703f, 0x0000, 0x7043, 0x0000,
+ 0x7047, 0x0000, 0x003e, 0x7038, 0xac36, 0x1110, 0x660c, 0x763a,
+ 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x7036,
+ 0x0010, 0x7037, 0x0000, 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110,
+ 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0x6010, 0x2068, 0x080c,
+ 0x9596, 0x0110, 0x080c, 0xa91f, 0x080c, 0x974e, 0x87ff, 0x1190,
+ 0x00ce, 0x0804, 0x7c43, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7c43,
+ 0xa006, 0x012e, 0x000e, 0x002e, 0x006e, 0x00ce, 0x00de, 0x00ee,
+ 0x00fe, 0x0005, 0x6017, 0x0000, 0x00ce, 0xa7bd, 0x0001, 0x0c88,
+ 0x00e6, 0x2071, 0xafc7, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002,
+ 0x1118, 0x7007, 0x0005, 0x0010, 0x7007, 0x0000, 0x00ee, 0x0005,
+ 0x00f6, 0x00e6, 0x00c6, 0x0066, 0x0026, 0x0006, 0x0126, 0x2091,
+ 0x8000, 0x2071, 0xafc7, 0x2c10, 0x7638, 0x2660, 0x2678, 0x8cff,
+ 0x0518, 0x2200, 0xac06, 0x11e0, 0x7038, 0xac36, 0x1110, 0x660c,
+ 0x763a, 0x7034, 0xac36, 0x1140, 0x2c00, 0xaf36, 0x0118, 0x2f00,
+ 0x7036, 0x0010, 0x7037, 0x0000, 0x660c, 0x2c00, 0xaf06, 0x0110,
+ 0x7e0e, 0x0008, 0x2678, 0x600f, 0x0000, 0xa085, 0x0001, 0x0020,
+ 0x2c78, 0x600c, 0x2060, 0x08d8, 0x012e, 0x000e, 0x002e, 0x006e,
+ 0x00ce, 0x00ee, 0x00fe, 0x0005, 0x00f6, 0x00e6, 0x00d6, 0x00c6,
+ 0x0066, 0x0006, 0x0126, 0x2091, 0x8000, 0x2071, 0xafc7, 0x760c,
+ 0x2660, 0x2678, 0x8cff, 0x0904, 0x7d7e, 0x6018, 0xa080, 0x0028,
+ 0x2004, 0xa206, 0x1904, 0x7d79, 0x7024, 0xac06, 0x1508, 0x2069,
+ 0x0100, 0x68c0, 0xa005, 0x0904, 0x7d55, 0x080c, 0x7834, 0x68c3,
+ 0x0000, 0x080c, 0x7ca8, 0x7027, 0x0000, 0x0036, 0x2069, 0x0140,
+ 0x6b04, 0xa384, 0x1000, 0x0120, 0x6803, 0x0100, 0x6803, 0x0000,
+ 0x2069, 0x0100, 0x6824, 0xd084, 0x0110, 0x6827, 0x0001, 0x003e,
+ 0x700c, 0xac36, 0x1110, 0x660c, 0x760e, 0x7008, 0xac36, 0x1140,
+ 0x2c00, 0xaf36, 0x0118, 0x2f00, 0x700a, 0x0010, 0x700b, 0x0000,
+ 0x660c, 0x0066, 0x2c00, 0xaf06, 0x0110, 0x7e0e, 0x0008, 0x2678,
+ 0x600f, 0x0000, 0x080c, 0x9778, 0x1158, 0x080c, 0x2aff, 0x080c,
+ 0x9789, 0x11f0, 0x080c, 0x85f3, 0x00d8, 0x080c, 0x7ca8, 0x08c0,
+ 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0090, 0x6010, 0x2068,
+ 0x080c, 0x9596, 0x0168, 0x601c, 0xa086, 0x0003, 0x11f8, 0x6837,
+ 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742,
+ 0x080c, 0x994e, 0x080c, 0x974e, 0x080c, 0x7b88, 0x00ce, 0x0804,
+ 0x7d02, 0x2c78, 0x600c, 0x2060, 0x0804, 0x7d02, 0x012e, 0x000e,
+ 0x006e, 0x00ce, 0x00de, 0x00ee, 0x00fe, 0x0005, 0x601c, 0xa086,
+ 0x0006, 0x1d30, 0x080c, 0xa91f, 0x0c18, 0x0036, 0x0156, 0x0136,
+ 0x0146, 0x3908, 0xa006, 0xa190, 0x0020, 0x221c, 0xa39e, 0x28f9,
+ 0x1118, 0x8210, 0x8000, 0x0cc8, 0xa005, 0x0138, 0x20a9, 0x0020,
+ 0x2198, 0xa110, 0x22a0, 0x22c8, 0x53a3, 0x014e, 0x013e, 0x015e,
+ 0x003e, 0x0005, 0x00d6, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+ 0x0200, 0x20a3, 0x0014, 0x60c3, 0x0014, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x2099, 0xafa6, 0x20a9, 0x0004, 0x53a6, 0x20a3, 0x0004,
+ 0x20a3, 0x7878, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x080c, 0x7821,
+ 0x00de, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3, 0x0214,
+ 0x20a3, 0x0018, 0x20a3, 0x0800, 0x7810, 0xa084, 0xff00, 0x20a2,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x20a3, 0x0000,
+ 0x7810, 0xa084, 0x00ff, 0x20a2, 0x7828, 0x20a2, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x60c3, 0x0018, 0x080c, 0x7821, 0x0005, 0x00d6,
+ 0x0016, 0x2f68, 0x2009, 0x0035, 0x080c, 0x9a34, 0x1904, 0x7e5d,
+ 0x20a1, 0x020b, 0x080c, 0x710e, 0x20a3, 0x1300, 0x20a3, 0x0000,
+ 0x7828, 0x2068, 0x681c, 0xa086, 0x0003, 0x0580, 0x7818, 0xa080,
+ 0x0028, 0x2014, 0x2001, 0xad34, 0x2004, 0xd0ac, 0x11d0, 0xa286,
+ 0x007e, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffe, 0x04b8, 0xa286,
+ 0x007f, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffd, 0x0478, 0xd2bc,
+ 0x0180, 0xa286, 0x0080, 0x1128, 0x20a3, 0x00ff, 0x20a3, 0xfffc,
+ 0x0428, 0xa2e8, 0xae34, 0x2d6c, 0x6810, 0x20a2, 0x6814, 0x20a2,
+ 0x00e8, 0x20a3, 0x0000, 0x6098, 0x20a2, 0x00c0, 0x2001, 0xad34,
+ 0x2004, 0xd0ac, 0x1138, 0x7818, 0xa080, 0x0028, 0x2004, 0xa082,
+ 0x007e, 0x0240, 0x00d6, 0x2069, 0xad1b, 0x2da6, 0x8d68, 0x2da6,
+ 0x00de, 0x0020, 0x20a3, 0x0000, 0x6034, 0x20a2, 0x7834, 0x20a2,
+ 0x7838, 0x20a2, 0x20a3, 0x0000, 0x20a3, 0x0000, 0x60c3, 0x000c,
+ 0x080c, 0x7821, 0x001e, 0x00de, 0x0005, 0x7817, 0x0001, 0x7803,
+ 0x0006, 0x001e, 0x00de, 0x0005, 0x00d6, 0x0026, 0x7928, 0x2168,
+ 0x691c, 0xa186, 0x0006, 0x01c0, 0xa186, 0x0003, 0x0904, 0x7ed3,
+ 0xa186, 0x0005, 0x0904, 0x7ebc, 0xa186, 0x0004, 0x05b8, 0xa186,
+ 0x0008, 0x0904, 0x7ec4, 0x7807, 0x0037, 0x7813, 0x1700, 0x080c,
+ 0x7f3b, 0x002e, 0x00de, 0x0005, 0x080c, 0x7ef7, 0x2009, 0x4000,
+ 0x6800, 0x0002, 0x7e9d, 0x7ea8, 0x7e9f, 0x7ea8, 0x7ea4, 0x7e9d,
+ 0x7e9d, 0x7ea8, 0x7ea8, 0x7ea8, 0x7ea8, 0x7e9d, 0x7e9d, 0x7e9d,
+ 0x7e9d, 0x7e9d, 0x7ea8, 0x7e9d, 0x7ea8, 0x080c, 0x14f6, 0x6820,
+ 0xd0e4, 0x0110, 0xd0cc, 0x0110, 0xa00e, 0x0010, 0x2009, 0x2000,
+ 0x6828, 0x20a2, 0x682c, 0x20a2, 0x0804, 0x7eed, 0x080c, 0x7ef7,
+ 0x20a3, 0x0000, 0x20a3, 0x0000, 0x2009, 0x4000, 0x6a00, 0xa286,
+ 0x0002, 0x1108, 0xa00e, 0x0488, 0x04d1, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x2009, 0x4000, 0x0448, 0x0491, 0x20a3, 0x0000, 0x20a3,
+ 0x0000, 0x2009, 0x4000, 0xa286, 0x0005, 0x0118, 0xa286, 0x0002,
+ 0x1108, 0xa00e, 0x00d0, 0x0419, 0x6810, 0x2068, 0x697c, 0x6810,
+ 0xa112, 0x6980, 0x6814, 0xa103, 0x20a2, 0x22a2, 0x7928, 0xa180,
+ 0x0000, 0x2004, 0xa08e, 0x0002, 0x0130, 0xa08e, 0x0004, 0x0118,
+ 0x2009, 0x4000, 0x0010, 0x2009, 0x0000, 0x21a2, 0x20a3, 0x0000,
+ 0x60c3, 0x0018, 0x080c, 0x7821, 0x002e, 0x00de, 0x0005, 0x0036,
+ 0x0046, 0x0056, 0x0066, 0x20a1, 0x020b, 0x080c, 0x71aa, 0xa006,
+ 0x20a3, 0x0200, 0x20a2, 0x7934, 0x21a2, 0x7938, 0x21a2, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1118,
+ 0xa092, 0x007e, 0x0268, 0x00d6, 0x2069, 0xad1b, 0x2d2c, 0x8d68,
+ 0x2d34, 0xa0e8, 0xae34, 0x2d6c, 0x6b10, 0x6c14, 0x00de, 0x0030,
+ 0x2019, 0x0000, 0x6498, 0x2029, 0x0000, 0x6634, 0x7828, 0xa080,
+ 0x0007, 0x2004, 0xa086, 0x0003, 0x1128, 0x25a2, 0x26a2, 0x23a2,
+ 0x24a2, 0x0020, 0x23a2, 0x24a2, 0x25a2, 0x26a2, 0x006e, 0x005e,
+ 0x004e, 0x003e, 0x0005, 0x20a1, 0x020b, 0x080c, 0x71aa, 0x20a3,
+ 0x0100, 0x20a3, 0x0000, 0x20a3, 0x0009, 0x7810, 0x20a2, 0x60c3,
+ 0x0008, 0x080c, 0x7821, 0x0005, 0x20a1, 0x020b, 0x080c, 0x7106,
+ 0x20a3, 0x1400, 0x20a3, 0x0000, 0x7834, 0x20a2, 0x7838, 0x20a2,
+ 0x7828, 0x20a2, 0x782c, 0x20a2, 0x7830, 0xa084, 0x00ff, 0x8007,
+ 0x20a2, 0x20a3, 0x0000, 0x60c3, 0x0010, 0x080c, 0x7821, 0x0005,
+ 0x20a1, 0x020b, 0x080c, 0x71a2, 0x20a3, 0x0100, 0x20a3, 0x0000,
+ 0x7828, 0x20a2, 0x7810, 0x20a2, 0x60c3, 0x0008, 0x080c, 0x7821,
+ 0x0005, 0x0146, 0x20a1, 0x020b, 0x0031, 0x60c3, 0x0000, 0x080c,
+ 0x7821, 0x014e, 0x0005, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7818,
+ 0xa080, 0x0028, 0x2004, 0x2011, 0xad34, 0x2214, 0xd2ac, 0x1110,
+ 0xd0bc, 0x0188, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810, 0xa085,
+ 0x0300, 0x20a2, 0x6814, 0x20a2, 0x2069, 0xad1b, 0x2da6, 0x8d68,
+ 0x2da6, 0x00de, 0x0078, 0x00d6, 0xa0e8, 0xae34, 0x2d6c, 0x6810,
+ 0xa085, 0x0300, 0x20a2, 0x6814, 0x20a2, 0x00de, 0x20a3, 0x0000,
+ 0x6234, 0x22a2, 0x20a3, 0x0819, 0x20a3, 0x0000, 0x080c, 0x7810,
+ 0x22a2, 0x20a3, 0x0000, 0x2fa2, 0x7a08, 0x22a2, 0x20a3, 0x0000,
+ 0x20a3, 0x0000, 0x0005, 0x20a1, 0x020b, 0x0079, 0x7910, 0x21a2,
+ 0x20a3, 0x0000, 0x60c3, 0x0000, 0x20e1, 0x9080, 0x60a7, 0x9575,
+ 0x080c, 0x782b, 0x080c, 0x6578, 0x0005, 0x0156, 0x0136, 0x0036,
+ 0x00d6, 0x00e6, 0x20e1, 0x9080, 0x20e1, 0x4000, 0x7854, 0x2068,
+ 0xadf0, 0x000f, 0x7210, 0xa296, 0x00c0, 0xa294, 0xfffd, 0x7212,
+ 0x7214, 0xa294, 0x0300, 0x7216, 0x7100, 0xa194, 0x00ff, 0x7308,
+ 0xa384, 0x00ff, 0xa08d, 0xc200, 0x7102, 0xa384, 0xff00, 0xa215,
+ 0x720a, 0x7004, 0x720c, 0x700e, 0x7206, 0x20a9, 0x000a, 0x2e98,
+ 0x53a6, 0x60a3, 0x0035, 0x6a38, 0xa294, 0x7000, 0xa286, 0x3000,
+ 0x0110, 0x60a3, 0x0037, 0x00ee, 0x00de, 0x003e, 0x013e, 0x015e,
+ 0x0005, 0x2009, 0x0092, 0x0010, 0x2009, 0x0096, 0x60ab, 0x0036,
+ 0x6116, 0x0005, 0x2061, 0xb400, 0x2a70, 0x7064, 0x7046, 0x704b,
+ 0xb400, 0x0005, 0x00e6, 0x0126, 0x2071, 0xad00, 0x2091, 0x8000,
+ 0x7544, 0xa582, 0x0010, 0x0608, 0x7048, 0x2060, 0x6000, 0xa086,
+ 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0,
+ 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8,
+ 0x0018, 0x7058, 0xa502, 0x1230, 0x754a, 0xa085, 0x0001, 0x012e,
+ 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6,
+ 0x2071, 0xad00, 0x7544, 0xa582, 0x0010, 0x0600, 0x7048, 0x2060,
+ 0x6000, 0xa086, 0x0000, 0x0148, 0xace0, 0x0018, 0x7058, 0xac02,
+ 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98, 0x6003, 0x0008, 0x8529,
+ 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502, 0x1228, 0x754a, 0xa085,
+ 0x0001, 0x00ee, 0x0005, 0x704b, 0xb400, 0x0cc8, 0xa006, 0x0cc8,
+ 0xac82, 0xb400, 0x0a0c, 0x14f6, 0x2001, 0xad16, 0x2004, 0xac02,
+ 0x1a0c, 0x14f6, 0xa006, 0x6006, 0x600a, 0x600e, 0x6012, 0x6016,
+ 0x601a, 0x601f, 0x0000, 0x6003, 0x0000, 0x6052, 0x6056, 0x6022,
+ 0x6026, 0x602a, 0x602e, 0x6032, 0x6036, 0x603a, 0x603e, 0x2061,
+ 0xad00, 0x6044, 0x8000, 0x6046, 0xa086, 0x0001, 0x0108, 0x0005,
+ 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0cc0, 0x601c,
+ 0xa084, 0x000f, 0x0002, 0x80b6, 0x80c5, 0x80e0, 0x80fb, 0x9a61,
+ 0x9a7c, 0x9a97, 0x80b6, 0x80c5, 0x80b6, 0x8116, 0xa186, 0x0013,
+ 0x1128, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x0005, 0xa18e, 0x0047,
+ 0x1118, 0xa016, 0x080c, 0x1824, 0x0005, 0x0066, 0x6000, 0xa0b2,
+ 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x80de, 0x8478,
+ 0x862d, 0x80de, 0x86a2, 0x81cf, 0x80de, 0x80de, 0x840a, 0x8a91,
+ 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x80de, 0x080c, 0x14f6,
+ 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e,
+ 0x0005, 0x80f9, 0x909a, 0x80f9, 0x80f9, 0x80f9, 0x80f9, 0x80f9,
+ 0x80f9, 0x9045, 0x9200, 0x80f9, 0x90c7, 0x913e, 0x90c7, 0x913e,
+ 0x80f9, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c,
+ 0x14f6, 0x0013, 0x006e, 0x0005, 0x8114, 0x8ad2, 0x8b98, 0x8cb8,
+ 0x8e12, 0x8114, 0x8114, 0x8114, 0x8aac, 0x8ff5, 0x8ff8, 0x8114,
+ 0x8114, 0x8114, 0x8114, 0x9022, 0x080c, 0x14f6, 0x0066, 0x6000,
+ 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x812f,
+ 0x812f, 0x812f, 0x8152, 0x81a5, 0x812f, 0x812f, 0x812f, 0x8131,
+ 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x812f, 0x080c,
+ 0x14f6, 0xa186, 0x0003, 0x190c, 0x14f6, 0x00d6, 0x6003, 0x0003,
+ 0x6106, 0x6010, 0x2068, 0x684f, 0x0040, 0x687c, 0x680a, 0x6880,
+ 0x680e, 0x6813, 0x0000, 0x6817, 0x0000, 0x00de, 0x2c10, 0x080c,
+ 0x1e6e, 0x080c, 0x680b, 0x0126, 0x2091, 0x8000, 0x080c, 0x6d0d,
+ 0x012e, 0x0005, 0xa182, 0x0047, 0x0002, 0x815e, 0x815e, 0x8160,
+ 0x817f, 0x815e, 0x815e, 0x815e, 0x815e, 0x8191, 0x080c, 0x14f6,
+ 0x00d6, 0x0016, 0x080c, 0x6c05, 0x080c, 0x6d0d, 0x6003, 0x0004,
+ 0x6110, 0x2168, 0x6854, 0x8003, 0x800b, 0x810b, 0xa108, 0x6116,
+ 0x684f, 0x0020, 0x685c, 0x685a, 0x6874, 0x687e, 0x6878, 0x6882,
+ 0x6897, 0x0000, 0x689b, 0x0000, 0x001e, 0x00de, 0x0005, 0x080c,
+ 0x6c05, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0120, 0x684b,
+ 0x0006, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c, 0x6d0d,
+ 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110, 0x2168,
+ 0x080c, 0x9596, 0x0120, 0x684b, 0x0029, 0x080c, 0x510c, 0x00de,
+ 0x080c, 0x8078, 0x080c, 0x6d0d, 0x0005, 0xa182, 0x0047, 0x0002,
+ 0x81b3, 0x81c2, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1, 0x81b1,
+ 0x81b1, 0x080c, 0x14f6, 0x00d6, 0x6010, 0x2068, 0x684c, 0xc0f4,
+ 0x684e, 0x00de, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c,
+ 0x1824, 0x0005, 0x00d6, 0x6110, 0x2168, 0x684b, 0x0000, 0x6853,
+ 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x0005, 0xa1b6,
+ 0x0015, 0x1118, 0x080c, 0x8078, 0x0030, 0xa1b6, 0x0016, 0x190c,
+ 0x14f6, 0x080c, 0x8078, 0x0005, 0x20a9, 0x000e, 0x2e98, 0x6010,
+ 0x20a0, 0x53a3, 0x20a9, 0x0006, 0x3310, 0x3420, 0x9398, 0x94a0,
+ 0x3318, 0x3428, 0x222e, 0x2326, 0xa290, 0x0002, 0xa5a8, 0x0002,
+ 0xa398, 0x0002, 0xa4a0, 0x0002, 0x1f04, 0x81ea, 0x00e6, 0x080c,
+ 0x9596, 0x0130, 0x6010, 0x2070, 0x7007, 0x0000, 0x7037, 0x0103,
+ 0x00ee, 0x080c, 0x8078, 0x0005, 0x00d6, 0x0036, 0x7330, 0xa386,
+ 0x0200, 0x1130, 0x6018, 0x2068, 0x6813, 0x00ff, 0x6817, 0xfffd,
+ 0x6010, 0xa005, 0x0130, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103,
+ 0x6b32, 0x080c, 0x8078, 0x003e, 0x00de, 0x0005, 0x0016, 0x20a9,
+ 0x002a, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+ 0x53a3, 0x20a9, 0x002a, 0x6010, 0xa080, 0x0001, 0x2004, 0xa080,
+ 0x0002, 0x20a0, 0x53a3, 0x00e6, 0x6010, 0x2004, 0x2070, 0x7037,
+ 0x0103, 0x00ee, 0x080c, 0x8078, 0x001e, 0x0005, 0x0016, 0x2009,
+ 0x0000, 0x7030, 0xa086, 0x0100, 0x0140, 0x7038, 0xa084, 0x00ff,
+ 0x808e, 0x703c, 0xa084, 0x00ff, 0x8086, 0xa080, 0x0004, 0xa108,
+ 0x21a8, 0xae80, 0x000c, 0x2098, 0x6010, 0xa080, 0x0002, 0x20a0,
+ 0x080c, 0x48be, 0x00e6, 0x080c, 0x9596, 0x0140, 0x6010, 0x2070,
+ 0x7007, 0x0000, 0x7034, 0x70b2, 0x7037, 0x0103, 0x00ee, 0x080c,
+ 0x8078, 0x001e, 0x0005, 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2c68,
+ 0x0016, 0x2009, 0x0035, 0x080c, 0x9a34, 0x001e, 0x1168, 0x0026,
+ 0x6228, 0x2268, 0x002e, 0x2071, 0xb28c, 0x6b1c, 0xa386, 0x0003,
+ 0x0130, 0xa386, 0x0006, 0x0128, 0x080c, 0x8078, 0x0020, 0x0031,
+ 0x0010, 0x080c, 0x8323, 0x00de, 0x00ee, 0x0005, 0x00f6, 0x6810,
+ 0x2078, 0xa186, 0x0015, 0x0904, 0x830c, 0xa18e, 0x0016, 0x1904,
+ 0x8321, 0x700c, 0xa084, 0xff00, 0xa086, 0x1700, 0x1904, 0x82eb,
+ 0x8fff, 0x0904, 0x831f, 0x6808, 0xa086, 0xffff, 0x1904, 0x830e,
+ 0x784c, 0xa084, 0x0060, 0xa086, 0x0020, 0x1150, 0x797c, 0x7810,
+ 0xa106, 0x1904, 0x830e, 0x7980, 0x7814, 0xa106, 0x1904, 0x830e,
+ 0x080c, 0x9742, 0x6858, 0x7852, 0x784c, 0xc0dc, 0xc0f4, 0xc0d4,
+ 0x784e, 0x0026, 0xa00e, 0x6a14, 0x2001, 0x000a, 0x080c, 0x6665,
+ 0x7854, 0xa20a, 0x0208, 0x8011, 0x7a56, 0x82ff, 0x002e, 0x1138,
+ 0x00c6, 0x2d60, 0x080c, 0x9374, 0x00ce, 0x0804, 0x831f, 0x00c6,
+ 0x00d6, 0x2f68, 0x6838, 0xd0fc, 0x1118, 0x080c, 0x4993, 0x0010,
+ 0x080c, 0x4b7c, 0x00de, 0x00ce, 0x1548, 0x00c6, 0x2d60, 0x080c,
+ 0x8078, 0x00ce, 0x04a0, 0x7008, 0xa086, 0x000b, 0x11a0, 0x6018,
+ 0x200c, 0xc1bc, 0x2102, 0x00c6, 0x2d60, 0x7853, 0x0003, 0x6007,
+ 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c,
+ 0x6c50, 0x00ce, 0x00e0, 0x700c, 0xa086, 0x2a00, 0x1138, 0x2001,
+ 0xafa5, 0x2004, 0x683e, 0x0098, 0x0471, 0x0098, 0x8fff, 0x090c,
+ 0x14f6, 0x00c6, 0x00d6, 0x2d60, 0x2f68, 0x684b, 0x0003, 0x080c,
+ 0x926f, 0x080c, 0x9742, 0x080c, 0x974e, 0x00de, 0x00ce, 0x080c,
+ 0x8078, 0x00fe, 0x0005, 0xa186, 0x0015, 0x1128, 0x2001, 0xafa5,
+ 0x2004, 0x683e, 0x0068, 0xa18e, 0x0016, 0x1160, 0x00c6, 0x2d00,
+ 0x2060, 0x080c, 0xabb4, 0x080c, 0x6618, 0x080c, 0x8078, 0x00ce,
+ 0x080c, 0x8078, 0x0005, 0x0026, 0x0036, 0x0046, 0x7228, 0x7c80,
+ 0x7b7c, 0xd2f4, 0x0130, 0x2001, 0xafa5, 0x2004, 0x683e, 0x0804,
+ 0x839d, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x6804, 0xa086,
+ 0x0050, 0x1168, 0x00c6, 0x2d00, 0x2060, 0x6003, 0x0001, 0x6007,
+ 0x0050, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x04f0, 0x6800,
+ 0xa086, 0x000f, 0x01c8, 0x8fff, 0x090c, 0x14f6, 0x6820, 0xd0dc,
+ 0x1198, 0x6800, 0xa086, 0x0004, 0x1198, 0x784c, 0xd0ac, 0x0180,
+ 0x784c, 0xc0dc, 0xc0f4, 0x784e, 0x7850, 0xc0f4, 0xc0fc, 0x7852,
+ 0x2001, 0x0001, 0x682e, 0x00e0, 0x2001, 0x0007, 0x682e, 0x00c0,
+ 0x784c, 0xd0b4, 0x1130, 0xd0ac, 0x0db8, 0x784c, 0xd0f4, 0x1da0,
+ 0x0c38, 0xd2ec, 0x1d88, 0x7024, 0xa306, 0x1118, 0x7020, 0xa406,
+ 0x0d58, 0x7020, 0x6836, 0x7024, 0x683a, 0x2001, 0x0005, 0x682e,
+ 0x080c, 0x9894, 0x080c, 0x6c50, 0x0010, 0x080c, 0x8078, 0x004e,
+ 0x003e, 0x002e, 0x0005, 0x00e6, 0x00d6, 0x0026, 0x6034, 0x2068,
+ 0x6a1c, 0xa286, 0x0007, 0x0904, 0x83ee, 0xa286, 0x0002, 0x05f0,
+ 0xa286, 0x0000, 0x05d8, 0x6808, 0x6338, 0xa306, 0x15b8, 0x2071,
+ 0xb28c, 0xa186, 0x0015, 0x0560, 0xa18e, 0x0016, 0x1190, 0x6030,
+ 0xa084, 0x00ff, 0xa086, 0x0001, 0x1160, 0x700c, 0xa086, 0x2a00,
+ 0x1140, 0x6034, 0xa080, 0x0008, 0x200c, 0xc1dd, 0xc1f5, 0x2102,
+ 0x00b8, 0x00c6, 0x6034, 0x2060, 0x6010, 0x2068, 0x080c, 0x9596,
+ 0x090c, 0x14f6, 0x6853, 0x0003, 0x6007, 0x0085, 0x6003, 0x000b,
+ 0x601f, 0x0002, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ce, 0x0030,
+ 0x6034, 0x2070, 0x2001, 0xafa5, 0x2004, 0x703e, 0x080c, 0x8078,
+ 0x002e, 0x00de, 0x00ee, 0x0005, 0x00d6, 0x20a9, 0x000e, 0x2e98,
+ 0x6010, 0x20a0, 0x53a3, 0xa1b6, 0x0015, 0x1148, 0x6018, 0x2068,
+ 0x7038, 0x680a, 0x703c, 0x680e, 0x6800, 0xc08d, 0x6802, 0x00de,
+ 0x0804, 0x81f6, 0x2100, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b2,
+ 0x0040, 0x1a04, 0x846e, 0x0002, 0x8462, 0x8456, 0x8462, 0x8462,
+ 0x8462, 0x8462, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+ 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+ 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+ 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8462, 0x8462, 0x8454,
+ 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8454, 0x8454, 0x8454,
+ 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8462, 0x8462,
+ 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454, 0x8454,
+ 0x8454, 0x8462, 0x8454, 0x8454, 0x080c, 0x14f6, 0x6003, 0x0001,
+ 0x6106, 0x080c, 0x67ee, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+ 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c, 0x67ee, 0x0126,
+ 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x2600, 0x0002,
+ 0x8462, 0x8476, 0x8476, 0x8462, 0x8462, 0x8476, 0x080c, 0x14f6,
+ 0x6004, 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x0904,
+ 0x8518, 0xa1b6, 0x0027, 0x1904, 0x84de, 0x080c, 0x6b73, 0x6004,
+ 0x080c, 0x9778, 0x0188, 0x080c, 0x9789, 0x0904, 0x84d8, 0xa08e,
+ 0x0021, 0x0904, 0x84db, 0xa08e, 0x0022, 0x0904, 0x84d8, 0xa08e,
+ 0x003d, 0x0904, 0x84db, 0x04a8, 0x080c, 0x2aff, 0x2001, 0x0007,
+ 0x080c, 0x4c30, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+ 0xa186, 0x007e, 0x1148, 0x2001, 0xad34, 0x2014, 0xc285, 0x080c,
+ 0x574f, 0x1108, 0xc2ad, 0x2202, 0x0016, 0x0026, 0x0036, 0x2110,
+ 0x2019, 0x0028, 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c,
+ 0x681d, 0x00c6, 0x6018, 0xa065, 0x0110, 0x080c, 0x4ecf, 0x00ce,
+ 0x2c08, 0x080c, 0xa712, 0x007e, 0x003e, 0x002e, 0x001e, 0x080c,
+ 0x4c9f, 0x080c, 0x994e, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+ 0x080c, 0x85f3, 0x0cb0, 0x080c, 0x8621, 0x0c98, 0xa186, 0x0014,
+ 0x1db0, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x080c, 0x9778, 0x1188,
+ 0x080c, 0x2aff, 0x6018, 0xa080, 0x0028, 0x200c, 0x080c, 0x85f3,
+ 0xa186, 0x007e, 0x1128, 0x2001, 0xad34, 0x200c, 0xc185, 0x2102,
+ 0x08c0, 0x080c, 0x9789, 0x1118, 0x080c, 0x85f3, 0x0890, 0x6004,
+ 0xa08e, 0x0032, 0x1158, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+ 0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x0818, 0x6004, 0xa08e,
+ 0x0021, 0x0d50, 0xa08e, 0x0022, 0x090c, 0x85f3, 0x0804, 0x84d1,
+ 0xa0b2, 0x0040, 0x1a04, 0x85db, 0x2008, 0x0002, 0x8560, 0x8561,
+ 0x8564, 0x8567, 0x856a, 0x856d, 0x855e, 0x855e, 0x855e, 0x855e,
+ 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+ 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+ 0x855e, 0x855e, 0x855e, 0x855e, 0x8570, 0x857f, 0x855e, 0x8581,
+ 0x857f, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x857f, 0x857f,
+ 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e, 0x855e,
+ 0x85bb, 0x857f, 0x855e, 0x857b, 0x855e, 0x855e, 0x855e, 0x857c,
+ 0x855e, 0x855e, 0x855e, 0x857f, 0x85b2, 0x855e, 0x080c, 0x14f6,
+ 0x00f0, 0x2001, 0x000b, 0x0460, 0x2001, 0x0003, 0x0448, 0x2001,
+ 0x0005, 0x0430, 0x2001, 0x0001, 0x0418, 0x2001, 0x0009, 0x0400,
+ 0x080c, 0x6b73, 0x6003, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e,
+ 0x080c, 0x6c50, 0x00a0, 0x0018, 0x0010, 0x080c, 0x4c30, 0x0804,
+ 0x85cc, 0x080c, 0x6b73, 0x2001, 0xafa3, 0x2004, 0x6016, 0x2001,
+ 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x080c, 0x6c50, 0x0005,
+ 0x080c, 0x4c30, 0x080c, 0x6b73, 0x6003, 0x0002, 0x2001, 0xafa5,
+ 0x2004, 0x603e, 0x0036, 0x2019, 0xad5c, 0x2304, 0xa084, 0xff00,
+ 0x1120, 0x2001, 0xafa3, 0x201c, 0x0040, 0x8007, 0xa09a, 0x0004,
+ 0x0ec0, 0x8003, 0x801b, 0x831b, 0xa318, 0x6316, 0x003e, 0x080c,
+ 0x6c50, 0x08e8, 0x080c, 0x6b73, 0x080c, 0x994e, 0x080c, 0x8078,
+ 0x080c, 0x6c50, 0x08a0, 0x00e6, 0x00f6, 0x2071, 0xad81, 0x2079,
+ 0x0000, 0x080c, 0x2df1, 0x00fe, 0x00ee, 0x080c, 0x6b73, 0x080c,
+ 0x8078, 0x080c, 0x6c50, 0x0818, 0x080c, 0x6b73, 0x2001, 0xafa5,
+ 0x2004, 0x603e, 0x6003, 0x0002, 0x2001, 0xafa3, 0x2004, 0x6016,
+ 0x080c, 0x6c50, 0x0005, 0x2600, 0x2008, 0x0002, 0x85e6, 0x85e4,
+ 0x85e4, 0x85cc, 0x85cc, 0x85e4, 0x080c, 0x14f6, 0x080c, 0x6b73,
+ 0x00d6, 0x6010, 0x2068, 0x080c, 0x15f0, 0x00de, 0x080c, 0x8078,
+ 0x080c, 0x6c50, 0x0005, 0x00e6, 0x0026, 0x0016, 0x080c, 0x9596,
+ 0x0508, 0x6010, 0x2070, 0x7034, 0xa086, 0x0139, 0x1148, 0x2001,
+ 0x0030, 0x2009, 0x0000, 0x2011, 0x4005, 0x080c, 0x9a05, 0x0090,
+ 0x7038, 0xd0fc, 0x0178, 0x7007, 0x0000, 0x0016, 0x6004, 0xa08e,
+ 0x0021, 0x0160, 0xa08e, 0x003d, 0x0148, 0x001e, 0x7037, 0x0103,
+ 0x7033, 0x0100, 0x001e, 0x002e, 0x00ee, 0x0005, 0x001e, 0x0009,
+ 0x0cc8, 0x00e6, 0xacf0, 0x0004, 0x2e74, 0x7000, 0x2070, 0x7037,
+ 0x0103, 0x7023, 0x8001, 0x00ee, 0x0005, 0x00d6, 0x6618, 0x2668,
+ 0x6804, 0xa084, 0x00ff, 0x00de, 0xa0b2, 0x000c, 0x1a0c, 0x14f6,
+ 0x6604, 0xa6b6, 0x0043, 0x1120, 0x080c, 0x99c1, 0x0804, 0x8692,
+ 0x6604, 0xa6b6, 0x0033, 0x1120, 0x080c, 0x9971, 0x0804, 0x8692,
+ 0x6604, 0xa6b6, 0x0028, 0x1120, 0x080c, 0x97b9, 0x0804, 0x8692,
+ 0x6604, 0xa6b6, 0x0029, 0x1118, 0x080c, 0x97d0, 0x04d8, 0x6604,
+ 0xa6b6, 0x001f, 0x1118, 0x080c, 0x81dc, 0x04a0, 0x6604, 0xa6b6,
+ 0x0000, 0x1118, 0x080c, 0x83f4, 0x0468, 0x6604, 0xa6b6, 0x0022,
+ 0x1118, 0x080c, 0x8204, 0x0430, 0x6604, 0xa6b6, 0x0035, 0x1118,
+ 0x080c, 0x826b, 0x00f8, 0x6604, 0xa6b6, 0x0039, 0x1118, 0x080c,
+ 0x83a3, 0x00c0, 0x6604, 0xa6b6, 0x003d, 0x1118, 0x080c, 0x821e,
+ 0x0088, 0x6604, 0xa6b6, 0x0044, 0x1118, 0x080c, 0x823e, 0x0050,
+ 0xa1b6, 0x0015, 0x1110, 0x0053, 0x0028, 0xa1b6, 0x0016, 0x1118,
+ 0x0804, 0x883f, 0x0005, 0x080c, 0x80be, 0x0ce0, 0x86b9, 0x86bc,
+ 0x86b9, 0x86fe, 0x86b9, 0x87cc, 0x884d, 0x86b9, 0x86b9, 0x881b,
+ 0x86b9, 0x882f, 0xa1b6, 0x0048, 0x0140, 0x20e1, 0x0005, 0x3d18,
+ 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x00e6, 0xacf0, 0x0004,
+ 0x2e74, 0x7000, 0x2070, 0x7037, 0x0103, 0x00ee, 0x080c, 0x8078,
+ 0x0005, 0xe000, 0xe000, 0x0005, 0x00e6, 0x2071, 0xad00, 0x7080,
+ 0xa086, 0x0074, 0x1530, 0x080c, 0xa6e9, 0x11b0, 0x00d6, 0x6018,
+ 0x2068, 0x7030, 0xd08c, 0x0128, 0x6800, 0xd0bc, 0x0110, 0xc0c5,
+ 0x6802, 0x00d9, 0x00de, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c,
+ 0x2aff, 0x080c, 0x8078, 0x0078, 0x2001, 0x000a, 0x080c, 0x4c30,
+ 0x080c, 0x2aff, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee,
+ 0x0010, 0x080c, 0x87bd, 0x00ee, 0x0005, 0x6800, 0xd084, 0x0168,
+ 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2069, 0xad51, 0x6804, 0xd0a4,
+ 0x0120, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x0005, 0x00d6, 0x2011,
+ 0xad20, 0x2204, 0xa086, 0x0074, 0x1904, 0x87ba, 0x6018, 0x2068,
+ 0x6aa0, 0xa286, 0x007e, 0x1120, 0x080c, 0x894d, 0x0804, 0x875e,
+ 0x080c, 0x8943, 0x6018, 0x2068, 0xa080, 0x0028, 0x2014, 0xa286,
+ 0x0080, 0x11c0, 0x6813, 0x00ff, 0x6817, 0xfffc, 0x6010, 0xa005,
+ 0x0138, 0x2068, 0x6807, 0x0000, 0x6837, 0x0103, 0x6833, 0x0200,
+ 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078,
+ 0x0804, 0x87bb, 0x00e6, 0x2071, 0xad34, 0x2e04, 0xd09c, 0x0188,
+ 0x2071, 0xb280, 0x7108, 0x720c, 0xa18c, 0x00ff, 0x1118, 0xa284,
+ 0xff00, 0x0138, 0x6018, 0x2070, 0x70a0, 0xd0bc, 0x1110, 0x7112,
+ 0x7216, 0x00ee, 0x6010, 0xa005, 0x0128, 0x2068, 0x6838, 0xd0f4,
+ 0x0108, 0x0880, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+ 0x6007, 0x0003, 0x080c, 0x67ee, 0x0804, 0x87bb, 0x685c, 0xd0e4,
+ 0x01d0, 0x080c, 0x9903, 0x080c, 0x574f, 0x0110, 0xd0dc, 0x1900,
+ 0x2011, 0xad34, 0x2204, 0xc0ad, 0x2012, 0x2001, 0xaf8e, 0x2004,
+ 0x00f6, 0x2079, 0x0100, 0x78e3, 0x0000, 0x080c, 0x26cb, 0x78e2,
+ 0x00fe, 0x0804, 0x8728, 0x080c, 0x9937, 0x2011, 0xad34, 0x2204,
+ 0xc0a5, 0x2012, 0x0006, 0x080c, 0xa801, 0x000e, 0x1904, 0x8728,
+ 0xc0b5, 0x2012, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x00c6, 0x2009,
+ 0x00ef, 0x00f6, 0x2079, 0x0100, 0x79ea, 0x7932, 0x7936, 0x00fe,
+ 0x080c, 0x26a0, 0x00f6, 0x2079, 0xad00, 0x7972, 0x2100, 0x2009,
+ 0x0000, 0x080c, 0x2676, 0x794e, 0x00fe, 0x8108, 0x080c, 0x4c80,
+ 0x2c00, 0x00ce, 0x1904, 0x8728, 0x601a, 0x2001, 0x0002, 0x080c,
+ 0x4c30, 0x601f, 0x0001, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c,
+ 0x67ee, 0x0008, 0x0011, 0x00de, 0x0005, 0x2001, 0xad00, 0x2004,
+ 0xa086, 0x0003, 0x0120, 0x2001, 0x0007, 0x080c, 0x4c30, 0x080c,
+ 0x2aff, 0x080c, 0x8078, 0x0005, 0x00e6, 0x0026, 0x0016, 0x2071,
+ 0xad00, 0x7080, 0xa086, 0x0014, 0x15f0, 0x7000, 0xa086, 0x0003,
+ 0x1128, 0x6010, 0xa005, 0x1110, 0x080c, 0x3cce, 0x00d6, 0x6018,
+ 0x2068, 0x080c, 0x4d72, 0x080c, 0x86ed, 0x00de, 0x080c, 0x89f7,
+ 0x1550, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005, 0x0518,
+ 0x2001, 0x0006, 0x080c, 0x4c30, 0x00e6, 0x6010, 0xa075, 0x01a8,
+ 0x7034, 0xa084, 0x00ff, 0xa086, 0x0039, 0x1148, 0x2001, 0x0000,
+ 0x2009, 0x0000, 0x2011, 0x4000, 0x080c, 0x9a05, 0x0030, 0x7007,
+ 0x0000, 0x7037, 0x0103, 0x7033, 0x0200, 0x00ee, 0x080c, 0x2aff,
+ 0x080c, 0x8078, 0x0020, 0x080c, 0x85f3, 0x080c, 0x87bd, 0x001e,
+ 0x002e, 0x00ee, 0x0005, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+ 0x1158, 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007,
+ 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c, 0x87bd, 0x0005, 0x2011,
+ 0xad20, 0x2204, 0xa086, 0x0004, 0x1138, 0x2001, 0x0007, 0x080c,
+ 0x4c30, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x000b,
+ 0x0005, 0x86b9, 0x8854, 0x86b9, 0x888a, 0x86b9, 0x88ff, 0x884d,
+ 0x86b9, 0x86b9, 0x8912, 0x86b9, 0x8922, 0x6604, 0xa6b6, 0x001e,
+ 0x1110, 0x080c, 0x8078, 0x0005, 0x00d6, 0x00c6, 0x080c, 0x8932,
+ 0x1178, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+ 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x00f8,
+ 0x2009, 0xb28e, 0x2104, 0xa086, 0x0009, 0x1160, 0x6018, 0x2068,
+ 0x6840, 0xa084, 0x00ff, 0xa005, 0x0180, 0x8001, 0x6842, 0x6017,
+ 0x000a, 0x0068, 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086,
+ 0x1900, 0x1118, 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x00ce,
+ 0x00de, 0x0005, 0x080c, 0x8940, 0x00d6, 0x2069, 0xaf9d, 0x2d04,
+ 0xa005, 0x0168, 0x6018, 0x2068, 0x68a0, 0xa086, 0x007e, 0x1138,
+ 0x2069, 0xad1c, 0x2d04, 0x8000, 0x206a, 0x00de, 0x0010, 0x00de,
+ 0x0078, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x2001, 0x0002, 0x080c,
+ 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x0428,
+ 0x080c, 0x85f3, 0x2009, 0xb28e, 0x2134, 0xa6b4, 0x00ff, 0xa686,
+ 0x0005, 0x01e0, 0xa686, 0x000b, 0x01b0, 0x2009, 0xb28f, 0x2104,
+ 0xa084, 0xff00, 0x1118, 0xa686, 0x0009, 0x0180, 0xa086, 0x1900,
+ 0x1150, 0xa686, 0x0009, 0x0150, 0x2001, 0x0004, 0x080c, 0x4c30,
+ 0x080c, 0x8078, 0x0010, 0x080c, 0x87bd, 0x0005, 0x00d6, 0x6010,
+ 0x2068, 0x080c, 0x9596, 0x0128, 0x6838, 0xd0fc, 0x0110, 0x00de,
+ 0x0c90, 0x6018, 0x2068, 0x6840, 0xa084, 0x00ff, 0xa005, 0x0140,
+ 0x8001, 0x6842, 0x6017, 0x000a, 0x6007, 0x0016, 0x00de, 0x0c28,
+ 0x68a0, 0xa086, 0x007e, 0x1138, 0x00e6, 0x2071, 0xad00, 0x080c,
+ 0x48f5, 0x00ee, 0x0010, 0x080c, 0x2ad9, 0x00de, 0x08a0, 0x080c,
+ 0x8940, 0x1158, 0x2001, 0x0004, 0x080c, 0x4c30, 0x6003, 0x0001,
+ 0x6007, 0x0003, 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c,
+ 0x87bd, 0x0005, 0x0469, 0x1158, 0x2001, 0x0008, 0x080c, 0x4c30,
+ 0x6003, 0x0001, 0x6007, 0x0005, 0x080c, 0x67ee, 0x0010, 0x080c,
+ 0x87bd, 0x0005, 0x00e9, 0x1158, 0x2001, 0x000a, 0x080c, 0x4c30,
+ 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010, 0x080c,
+ 0x87bd, 0x0005, 0x2009, 0xb28e, 0x2104, 0xa086, 0x0003, 0x1138,
+ 0x2009, 0xb28f, 0x2104, 0xa084, 0xff00, 0xa086, 0x2a00, 0x0005,
+ 0xa085, 0x0001, 0x0005, 0x00c6, 0x0016, 0xac88, 0x0006, 0x2164,
+ 0x080c, 0x4ceb, 0x001e, 0x00ce, 0x0005, 0x00f6, 0x00e6, 0x00d6,
+ 0x0036, 0x0016, 0x6018, 0x2068, 0x2071, 0xad34, 0x2e04, 0xa085,
+ 0x0003, 0x2072, 0x080c, 0x89cc, 0x0538, 0x2001, 0xad52, 0x2004,
+ 0xd0a4, 0x0158, 0xa006, 0x2020, 0x2009, 0x002a, 0x080c, 0xa96c,
+ 0x2001, 0xad0c, 0x200c, 0xc195, 0x2102, 0x2019, 0x002a, 0x2009,
+ 0x0001, 0x080c, 0x2aac, 0x2071, 0xad00, 0x080c, 0x28fa, 0x00c6,
+ 0x0156, 0x20a9, 0x0081, 0x2009, 0x007f, 0x080c, 0x2bc9, 0x8108,
+ 0x1f04, 0x897d, 0x015e, 0x00ce, 0x080c, 0x8943, 0x6813, 0x00ff,
+ 0x6817, 0xfffe, 0x2071, 0xb280, 0x2079, 0x0100, 0x2e04, 0xa084,
+ 0x00ff, 0x2069, 0xad1b, 0x206a, 0x78e6, 0x0006, 0x8e70, 0x2e04,
+ 0x2069, 0xad1c, 0x206a, 0x78ea, 0x7832, 0x7836, 0x2010, 0xa084,
+ 0xff00, 0x001e, 0xa105, 0x2009, 0xad27, 0x200a, 0x2200, 0xa084,
+ 0x00ff, 0x2008, 0x080c, 0x26a0, 0x080c, 0x574f, 0x0170, 0x2069,
+ 0xb28e, 0x2071, 0xaf9f, 0x6810, 0x2072, 0x6814, 0x7006, 0x6818,
+ 0x700a, 0x681c, 0x700e, 0x080c, 0x9903, 0x0040, 0x2001, 0x0006,
+ 0x080c, 0x4c30, 0x080c, 0x2aff, 0x080c, 0x8078, 0x001e, 0x003e,
+ 0x00de, 0x00ee, 0x00fe, 0x0005, 0x0026, 0x0036, 0x00e6, 0x0156,
+ 0x2019, 0xad27, 0x231c, 0x83ff, 0x01e8, 0x2071, 0xb280, 0x2e14,
+ 0xa294, 0x00ff, 0x7004, 0xa084, 0xff00, 0xa205, 0xa306, 0x1190,
+ 0x2011, 0xb296, 0xad98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c,
+ 0x1148, 0x2011, 0xb29a, 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c,
+ 0x8a7c, 0x1100, 0x015e, 0x00ee, 0x003e, 0x002e, 0x0005, 0x00e6,
+ 0x2071, 0xb28c, 0x7004, 0xa086, 0x0014, 0x11a8, 0x7008, 0xa086,
+ 0x0800, 0x1188, 0x700c, 0xd0ec, 0x0160, 0xa084, 0x0f00, 0xa086,
+ 0x0100, 0x1138, 0x7024, 0xd0a4, 0x1110, 0xd0ac, 0x0110, 0xa006,
+ 0x0010, 0xa085, 0x0001, 0x00ee, 0x0005, 0x00e6, 0x00d6, 0x00c6,
+ 0x0076, 0x0056, 0x0046, 0x0026, 0x0006, 0x0126, 0x2091, 0x8000,
+ 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400,
+ 0x2071, 0xad00, 0x7244, 0x7064, 0xa202, 0x16f0, 0x080c, 0xa990,
+ 0x05a0, 0x671c, 0xa786, 0x0001, 0x0580, 0xa786, 0x0007, 0x0568,
+ 0x2500, 0xac06, 0x0550, 0x2400, 0xac06, 0x0538, 0x00c6, 0x6000,
+ 0xa086, 0x0004, 0x1110, 0x080c, 0x190b, 0xa786, 0x0008, 0x1148,
+ 0x080c, 0x9789, 0x1130, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x974e,
+ 0x00a0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0160, 0xa786, 0x0003,
+ 0x11e8, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000, 0x080c, 0x510c,
+ 0x080c, 0x9742, 0x080c, 0x974e, 0x00ce, 0xace0, 0x0018, 0x7058,
+ 0xac02, 0x1210, 0x0804, 0x8a2a, 0x012e, 0x000e, 0x002e, 0x004e,
+ 0x005e, 0x007e, 0x00ce, 0x00de, 0x00ee, 0x0005, 0xa786, 0x0006,
+ 0x1d00, 0x080c, 0xa91f, 0x0c30, 0x220c, 0x2304, 0xa106, 0x1130,
+ 0x8210, 0x8318, 0x1f04, 0x8a7c, 0xa006, 0x0005, 0x2304, 0xa102,
+ 0x0218, 0x2001, 0x0001, 0x0010, 0x2001, 0x0000, 0xa18d, 0x0001,
+ 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6, 0x080c, 0x9778,
+ 0x0120, 0x080c, 0x9789, 0x0168, 0x0028, 0x080c, 0x2aff, 0x080c,
+ 0x9789, 0x0138, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50,
+ 0x0005, 0x080c, 0x85f3, 0x0cb0, 0xa182, 0x0040, 0x0002, 0x8ac2,
+ 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2, 0x8ac2,
+ 0x8ac2, 0x8ac2, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac4, 0x8ac2, 0x8ac2,
+ 0x8ac2, 0x8ac4, 0x080c, 0x14f6, 0x600b, 0xffff, 0x6003, 0x0001,
+ 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50,
+ 0x012e, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0040,
+ 0x0804, 0x8b5e, 0xa186, 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c,
+ 0x2ad9, 0x00d6, 0x6110, 0x2168, 0x080c, 0x9596, 0x0168, 0x6837,
+ 0x0103, 0x684b, 0x0029, 0x6847, 0x0000, 0x694c, 0xc1c5, 0x694e,
+ 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x080c,
+ 0x6c50, 0x0005, 0xa186, 0x0014, 0x1120, 0x6004, 0xa082, 0x0040,
+ 0x0428, 0xa186, 0x0046, 0x0138, 0xa186, 0x0045, 0x0120, 0xa186,
+ 0x0047, 0x190c, 0x14f6, 0x2001, 0x0109, 0x2004, 0xd084, 0x0198,
+ 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+ 0x002e, 0x001e, 0x000e, 0x012e, 0xe000, 0x6000, 0xa086, 0x0002,
+ 0x1110, 0x0804, 0x8b98, 0x080c, 0x80be, 0x0005, 0x0002, 0x8b3c,
+ 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a, 0x8b3a,
+ 0x8b3a, 0x8b3a, 0x8b57, 0x8b57, 0x8b57, 0x8b57, 0x8b3a, 0x8b57,
+ 0x8b3a, 0x8b57, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x00d6, 0x6110,
+ 0x2168, 0x080c, 0x9596, 0x0168, 0x6837, 0x0103, 0x684b, 0x0006,
+ 0x6847, 0x0000, 0x6850, 0xc0ec, 0x6852, 0x080c, 0x510c, 0x080c,
+ 0x9742, 0x00de, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+ 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x0002, 0x8b74,
+ 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72, 0x8b72,
+ 0x8b72, 0x8b72, 0x8b86, 0x8b86, 0x8b86, 0x8b86, 0x8b72, 0x8b91,
+ 0x8b72, 0x8b86, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x2001, 0xafa5,
+ 0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c50, 0x6010, 0xa088,
+ 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x0005, 0x080c, 0x6b73,
+ 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x000f, 0x080c, 0x6c50,
+ 0x0005, 0x080c, 0x6b73, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005,
+ 0xa182, 0x0040, 0x0002, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+ 0x8bb0, 0x8c88, 0x8ca9, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae,
+ 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x8bae, 0x080c, 0x14f6,
+ 0x00e6, 0x00d6, 0x603f, 0x0000, 0x2071, 0xb280, 0x7124, 0x610a,
+ 0x2071, 0xb28c, 0x6110, 0x2168, 0x7614, 0xa6b4, 0x0fff, 0x86ff,
+ 0x0904, 0x8c54, 0xa68c, 0x0c00, 0x01e8, 0x00f6, 0x2c78, 0x080c,
+ 0x5029, 0x00fe, 0x0198, 0x684c, 0xd0ac, 0x0180, 0x6020, 0xd0dc,
+ 0x1168, 0x6850, 0xd0bc, 0x1150, 0x7318, 0x6814, 0xa306, 0x1904,
+ 0x8c66, 0x731c, 0x6810, 0xa306, 0x1904, 0x8c66, 0x7318, 0x6b62,
+ 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0518, 0xa186,
+ 0x0028, 0x1128, 0x080c, 0x9767, 0x684b, 0x001c, 0x00e8, 0xd6dc,
+ 0x01a0, 0x684b, 0x0015, 0x684c, 0xd0ac, 0x0170, 0x6914, 0x6a10,
+ 0x2100, 0xa205, 0x0148, 0x7018, 0xa106, 0x1118, 0x701c, 0xa206,
+ 0x0118, 0x6962, 0x6a5e, 0xc6dc, 0x0038, 0xd6d4, 0x0118, 0x684b,
+ 0x0007, 0x0010, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46, 0xa01e,
+ 0xd6c4, 0x01f0, 0xa686, 0x0100, 0x1140, 0x2001, 0xb299, 0x2004,
+ 0xa005, 0x1118, 0xc6c4, 0x0804, 0x8bbf, 0x7328, 0x732c, 0x6b56,
+ 0x83ff, 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036,
+ 0x2308, 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e,
+ 0xd6cc, 0x0904, 0x8c79, 0x7124, 0x695a, 0x81ff, 0x0904, 0x8c79,
+ 0xa192, 0x0021, 0x1250, 0x2071, 0xb298, 0x831c, 0x2300, 0xae18,
+ 0xad90, 0x001d, 0x080c, 0x927f, 0x04a0, 0x6838, 0xd0fc, 0x0120,
+ 0x2009, 0x0020, 0x695a, 0x0c78, 0x00f6, 0x2d78, 0x080c, 0x9224,
+ 0x00fe, 0x080c, 0x926f, 0x0438, 0x00f6, 0x2c78, 0x080c, 0x5029,
+ 0x00fe, 0x0188, 0x684c, 0xd0ac, 0x0170, 0x6020, 0xd0dc, 0x1158,
+ 0x6850, 0xd0bc, 0x1140, 0x684c, 0xd0f4, 0x1128, 0x080c, 0x9866,
+ 0x00de, 0x00ee, 0x00e0, 0x684b, 0x0000, 0x6837, 0x0103, 0x6e46,
+ 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c,
+ 0x8e04, 0x080c, 0x510c, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e,
+ 0x080c, 0x9834, 0x00de, 0x00ee, 0x1110, 0x080c, 0x8078, 0x0005,
+ 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00, 0x7e0c,
+ 0x7d08, 0x6010, 0x2078, 0x784c, 0xd0ac, 0x0120, 0x6003, 0x0002,
+ 0x00fe, 0x0005, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e, 0x00fe, 0x603f,
+ 0x0000, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b, 0x080c, 0x6d0d,
+ 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x6003, 0x0004, 0x6110,
+ 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005,
+ 0xa182, 0x0040, 0x0002, 0x8cce, 0x8cce, 0x8cce, 0x8cce, 0x8cce,
+ 0x8cd0, 0x8d61, 0x8cce, 0x8cce, 0x8d77, 0x8ddb, 0x8cce, 0x8cce,
+ 0x8cce, 0x8cce, 0x8dea, 0x8cce, 0x8cce, 0x8cce, 0x080c, 0x14f6,
+ 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c, 0x6110, 0x2178,
+ 0x7614, 0xa6b4, 0x0fff, 0x7e46, 0x7f4c, 0xc7e5, 0x7f4e, 0x6218,
+ 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904, 0x8d5c, 0xa694,
+ 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862, 0x701c, 0x785e,
+ 0xa284, 0x0300, 0x0904, 0x8d5c, 0x080c, 0x15d9, 0x090c, 0x14f6,
+ 0x2d00, 0x784a, 0x7f4c, 0xc7cd, 0x7f4e, 0x6837, 0x0103, 0x7838,
+ 0x683a, 0x783c, 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00,
+ 0x0120, 0x7318, 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186,
+ 0x0002, 0x0180, 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060,
+ 0xd6dc, 0x0118, 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b,
+ 0x0007, 0x0010, 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854,
+ 0x6856, 0xa01e, 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff,
+ 0x0170, 0xa38a, 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308,
+ 0x2019, 0xb298, 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc,
+ 0x01d8, 0x7124, 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250,
+ 0x2071, 0xb298, 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c,
+ 0x927f, 0x0050, 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a,
+ 0x0c78, 0x2d78, 0x080c, 0x9224, 0x00de, 0x00ee, 0x00fe, 0x007e,
+ 0x0005, 0x00f6, 0x6003, 0x0003, 0x2079, 0xb28c, 0x7c04, 0x7b00,
+ 0x7e0c, 0x7d08, 0x6010, 0x2078, 0x7c12, 0x7b16, 0x7e0a, 0x7d0e,
+ 0x00fe, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x781a, 0x0005, 0x00d6,
+ 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x2001, 0xafa5,
+ 0x2004, 0x603e, 0x6003, 0x0002, 0x080c, 0x6c05, 0x080c, 0x6d0d,
+ 0x6110, 0x2168, 0x694c, 0xd1e4, 0x0904, 0x8dd9, 0xd1cc, 0x0540,
+ 0x6948, 0x6838, 0xd0fc, 0x01e8, 0x0016, 0x684c, 0x0006, 0x6850,
+ 0x0006, 0xad90, 0x000d, 0xa198, 0x000d, 0x2009, 0x0020, 0x0156,
+ 0x21a8, 0x2304, 0x2012, 0x8318, 0x8210, 0x1f04, 0x8da1, 0x015e,
+ 0x000e, 0x6852, 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600,
+ 0x0418, 0x0016, 0x080c, 0x1600, 0x00de, 0x080c, 0x926f, 0x00e0,
+ 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff, 0xa0b6, 0x0002, 0x0180,
+ 0xa086, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd1dc, 0x0118,
+ 0x684b, 0x0015, 0x0038, 0xd1d4, 0x0118, 0x684b, 0x0007, 0x0010,
+ 0x684b, 0x0000, 0x080c, 0x510c, 0x080c, 0x9834, 0x1110, 0x080c,
+ 0x8078, 0x00de, 0x0005, 0x2019, 0x0001, 0x080c, 0x7a64, 0x6003,
+ 0x0002, 0x2001, 0xafa5, 0x2004, 0x603e, 0x080c, 0x6c05, 0x080c,
+ 0x6d0d, 0x0005, 0x080c, 0x6c05, 0x080c, 0x2ad9, 0x00d6, 0x6110,
+ 0x2168, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x684b, 0x0029,
+ 0x6847, 0x0000, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+ 0x8078, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0015, 0xd1fc, 0x0138,
+ 0x684b, 0x0007, 0x8002, 0x8000, 0x810a, 0xa189, 0x0000, 0x6962,
+ 0x685e, 0x0005, 0xa182, 0x0040, 0x0002, 0x8e28, 0x8e28, 0x8e28,
+ 0x8e28, 0x8e28, 0x8e2a, 0x8e28, 0x8ee3, 0x8eef, 0x8e28, 0x8e28,
+ 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28, 0x8e28,
+ 0x080c, 0x14f6, 0x0076, 0x00f6, 0x00e6, 0x00d6, 0x2071, 0xb28c,
+ 0x6110, 0x2178, 0x7614, 0xa6b4, 0x0fff, 0x00f6, 0x2c78, 0x080c,
+ 0x5029, 0x00fe, 0x0150, 0xa684, 0x00ff, 0x1138, 0x6020, 0xd0f4,
+ 0x0120, 0x080c, 0x9866, 0x0804, 0x8ede, 0x7e46, 0x7f4c, 0xc7e5,
+ 0x7f4e, 0x6218, 0x2268, 0x6a3c, 0x8211, 0x6a3e, 0x86ff, 0x0904,
+ 0x8ed4, 0xa694, 0xff00, 0xa284, 0x0c00, 0x0120, 0x7018, 0x7862,
+ 0x701c, 0x785e, 0xa284, 0x0300, 0x0904, 0x8ed2, 0xa686, 0x0100,
+ 0x1140, 0x2001, 0xb299, 0x2004, 0xa005, 0x1118, 0xc6c4, 0x7e46,
+ 0x0c28, 0x080c, 0x15d9, 0x090c, 0x14f6, 0x2d00, 0x784a, 0x7f4c,
+ 0xa7bd, 0x0200, 0x7f4e, 0x6837, 0x0103, 0x7838, 0x683a, 0x783c,
+ 0x683e, 0x7840, 0x6842, 0x6e46, 0xa68c, 0x0c00, 0x0120, 0x7318,
+ 0x6b62, 0x731c, 0x6b5e, 0xa68c, 0x00ff, 0xa186, 0x0002, 0x0180,
+ 0xa186, 0x0028, 0x1118, 0x684b, 0x001c, 0x0060, 0xd6dc, 0x0118,
+ 0x684b, 0x0015, 0x0038, 0xd6d4, 0x0118, 0x684b, 0x0007, 0x0010,
+ 0x684b, 0x0000, 0x6f4e, 0x7850, 0x6852, 0x7854, 0x6856, 0xa01e,
+ 0xd6c4, 0x0198, 0x7328, 0x732c, 0x6b56, 0x83ff, 0x0170, 0xa38a,
+ 0x0009, 0x0210, 0x2019, 0x0008, 0x0036, 0x2308, 0x2019, 0xb298,
+ 0xad90, 0x0019, 0x080c, 0x927f, 0x003e, 0xd6cc, 0x01d8, 0x7124,
+ 0x695a, 0x81ff, 0x01b8, 0xa192, 0x0021, 0x1250, 0x2071, 0xb298,
+ 0x831c, 0x2300, 0xae18, 0xad90, 0x001d, 0x080c, 0x927f, 0x0050,
+ 0x7838, 0xd0fc, 0x0120, 0x2009, 0x0020, 0x695a, 0x0c78, 0x2d78,
+ 0x080c, 0x9224, 0xd6dc, 0x1110, 0xa006, 0x0030, 0x2001, 0x0001,
+ 0x2071, 0xb28c, 0x7218, 0x731c, 0x080c, 0x186f, 0x00de, 0x00ee,
+ 0x00fe, 0x007e, 0x0005, 0x2001, 0xafa5, 0x2004, 0x603e, 0x20e1,
+ 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824, 0x0005, 0x2001,
+ 0xafa5, 0x2004, 0x603e, 0x00d6, 0x6003, 0x0002, 0x6110, 0x2168,
+ 0x694c, 0xd1e4, 0x0904, 0x8ff3, 0x603f, 0x0000, 0x00f6, 0x2c78,
+ 0x080c, 0x5029, 0x00fe, 0x0548, 0x6814, 0x6910, 0xa115, 0x0528,
+ 0x6a60, 0xa206, 0x1118, 0x685c, 0xa106, 0x01f8, 0x684c, 0xc0e4,
+ 0x684e, 0x6847, 0x0000, 0x6863, 0x0000, 0x685f, 0x0000, 0x697c,
+ 0x6810, 0xa102, 0x603a, 0x6980, 0x6814, 0xa103, 0x6036, 0x6020,
+ 0xc0f5, 0x6022, 0x00d6, 0x6018, 0x2068, 0x683c, 0x8000, 0x683e,
+ 0x00de, 0x080c, 0x9866, 0x0804, 0x8ff3, 0x694c, 0xd1cc, 0x0904,
+ 0x8fc3, 0x6948, 0x6838, 0xd0fc, 0x0904, 0x8f88, 0x0016, 0x684c,
+ 0x0006, 0x6850, 0x0006, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff,
+ 0xa0b6, 0x0002, 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c,
+ 0x784b, 0x001c, 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b,
+ 0x0015, 0x080c, 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080,
+ 0xd1d4, 0x0128, 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c,
+ 0xd0ac, 0x0130, 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04,
+ 0x6848, 0x784a, 0x6860, 0x7862, 0x685c, 0x785e, 0xad90, 0x000d,
+ 0xaf98, 0x000d, 0x2009, 0x0020, 0x0156, 0x21a8, 0x2304, 0x2012,
+ 0x8318, 0x8210, 0x1f04, 0x8f76, 0x015e, 0x00fe, 0x000e, 0x6852,
+ 0x000e, 0x684e, 0x001e, 0x2168, 0x080c, 0x1600, 0x0804, 0x8fee,
+ 0x0016, 0x00f6, 0x2178, 0x7944, 0xa184, 0x00ff, 0xa0b6, 0x0002,
+ 0x01e0, 0xa086, 0x0028, 0x1128, 0x684b, 0x001c, 0x784b, 0x001c,
+ 0x00e8, 0xd1dc, 0x0158, 0x684b, 0x0015, 0x784b, 0x0015, 0x080c,
+ 0x99ee, 0x0118, 0x7944, 0xc1dc, 0x7946, 0x0080, 0xd1d4, 0x0128,
+ 0x684b, 0x0007, 0x784b, 0x0007, 0x0048, 0x684c, 0xd0ac, 0x0130,
+ 0x6810, 0x6914, 0xa115, 0x0110, 0x080c, 0x8e04, 0x6860, 0x7862,
+ 0x685c, 0x785e, 0x684c, 0x784e, 0x00fe, 0x080c, 0x1600, 0x00de,
+ 0x080c, 0x926f, 0x0458, 0x6837, 0x0103, 0x6944, 0xa184, 0x00ff,
+ 0xa0b6, 0x0002, 0x01b0, 0xa086, 0x0028, 0x1118, 0x684b, 0x001c,
+ 0x00d8, 0xd1dc, 0x0148, 0x684b, 0x0015, 0x080c, 0x99ee, 0x0118,
+ 0x6944, 0xc1dc, 0x6946, 0x0080, 0xd1d4, 0x0118, 0x684b, 0x0007,
+ 0x0058, 0x684b, 0x0000, 0x684c, 0xd0ac, 0x0130, 0x6810, 0x6914,
+ 0xa115, 0x0110, 0x080c, 0x8e04, 0x080c, 0x510c, 0x080c, 0x9834,
+ 0x1110, 0x080c, 0x8078, 0x00de, 0x0005, 0x080c, 0x6b73, 0x0010,
+ 0x080c, 0x6c05, 0x080c, 0x9596, 0x01c0, 0x00d6, 0x6110, 0x2168,
+ 0x6837, 0x0103, 0x2009, 0xad0c, 0x210c, 0xd18c, 0x11c0, 0xd184,
+ 0x1198, 0x6108, 0x694a, 0xa18e, 0x0029, 0x1110, 0x080c, 0xabfa,
+ 0x6847, 0x0000, 0x080c, 0x510c, 0x00de, 0x080c, 0x8078, 0x080c,
+ 0x6c50, 0x080c, 0x6d0d, 0x0005, 0x684b, 0x0004, 0x0c88, 0x684b,
+ 0x0004, 0x0c70, 0xa182, 0x0040, 0x0002, 0x9038, 0x9038, 0x9038,
+ 0x9038, 0x9038, 0x903a, 0x9038, 0x903d, 0x9038, 0x9038, 0x9038,
+ 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038, 0x9038,
+ 0x080c, 0x14f6, 0x080c, 0x8078, 0x0005, 0x0006, 0x0026, 0xa016,
+ 0x080c, 0x1824, 0x002e, 0x000e, 0x0005, 0xa182, 0x0085, 0x0002,
+ 0x9051, 0x904f, 0x904f, 0x905d, 0x904f, 0x904f, 0x904f, 0x080c,
+ 0x14f6, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005, 0x0026, 0x0056, 0x00d6,
+ 0x00e6, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0x9586,
+ 0x01a0, 0x2268, 0x6800, 0xa086, 0x0000, 0x0178, 0x6018, 0x6d18,
+ 0xa52e, 0x1158, 0x00c6, 0x2d60, 0x080c, 0x928f, 0x00ce, 0x0128,
+ 0x6803, 0x0002, 0x6007, 0x0086, 0x0010, 0x6007, 0x0087, 0x6003,
+ 0x0001, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00f6, 0x2278, 0x080c,
+ 0x5029, 0x00fe, 0x0150, 0x6820, 0xd0ec, 0x0138, 0x00c6, 0x2260,
+ 0x603f, 0x0000, 0x080c, 0x9866, 0x00ce, 0x00ee, 0x00de, 0x005e,
+ 0x002e, 0x0005, 0xa186, 0x0013, 0x1160, 0x6004, 0xa08a, 0x0085,
+ 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c, 0x14f6, 0xa082, 0x0085,
+ 0x0072, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c, 0x14f6,
+ 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x90be,
+ 0x90c0, 0x90c0, 0x90be, 0x90be, 0x90be, 0x90be, 0x080c, 0x14f6,
+ 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa186,
+ 0x0013, 0x1128, 0x6004, 0xa082, 0x0085, 0x2008, 0x04a8, 0xa186,
+ 0x0027, 0x11e8, 0x080c, 0x6b73, 0x080c, 0x2ad9, 0x00d6, 0x6010,
+ 0x2068, 0x080c, 0x9596, 0x0150, 0x6837, 0x0103, 0x6847, 0x0000,
+ 0x684b, 0x0029, 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c,
+ 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c, 0x80be, 0x0ce0, 0xa186,
+ 0x0014, 0x1dd0, 0x080c, 0x6b73, 0x00d6, 0x6010, 0x2068, 0x080c,
+ 0x9596, 0x0d60, 0x6837, 0x0103, 0x6847, 0x0000, 0x684b, 0x0006,
+ 0x6850, 0xc0ec, 0x6852, 0x08f0, 0x0002, 0x910e, 0x910c, 0x910c,
+ 0x910c, 0x910c, 0x910c, 0x9126, 0x080c, 0x14f6, 0x080c, 0x6b73,
+ 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+ 0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+ 0x6016, 0x6003, 0x000c, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73,
+ 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+ 0x0035, 0x1118, 0x2001, 0xafa3, 0x0010, 0x2001, 0xafa4, 0x2004,
+ 0x6016, 0x6003, 0x000e, 0x080c, 0x6c50, 0x0005, 0xa182, 0x008c,
+ 0x1220, 0xa182, 0x0085, 0x0208, 0x001a, 0x080c, 0x80be, 0x0005,
+ 0x914f, 0x914f, 0x914f, 0x914f, 0x9151, 0x91a4, 0x914f, 0x080c,
+ 0x14f6, 0x00d6, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0168,
+ 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0039, 0x0118, 0xa186,
+ 0x0035, 0x1118, 0x00de, 0x0804, 0x91b7, 0x080c, 0x9742, 0x080c,
+ 0x9596, 0x01c8, 0x6010, 0x2068, 0x6837, 0x0103, 0x6850, 0xd0b4,
+ 0x0128, 0x684b, 0x0006, 0xc0ec, 0x6852, 0x0048, 0xd0bc, 0x0118,
+ 0x684b, 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847,
+ 0x0000, 0x080c, 0x510c, 0x2c68, 0x080c, 0x8022, 0x01c0, 0x6003,
+ 0x0001, 0x6007, 0x001e, 0x600b, 0xffff, 0x2009, 0xb28e, 0x210c,
+ 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x6918, 0x611a, 0x080c,
+ 0x9956, 0x6950, 0x6152, 0x601f, 0x0001, 0x080c, 0x67a8, 0x2d60,
+ 0x080c, 0x8078, 0x00de, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029,
+ 0x00fe, 0x0598, 0x6030, 0xa08c, 0xff00, 0x810f, 0xa186, 0x0035,
+ 0x0130, 0xa186, 0x001e, 0x0118, 0xa186, 0x0039, 0x1530, 0x00d6,
+ 0x2c68, 0x080c, 0x9a34, 0x1904, 0x91fc, 0x080c, 0x8022, 0x01d8,
+ 0x6106, 0x6003, 0x0001, 0x601f, 0x0001, 0x6918, 0x611a, 0x6928,
+ 0x612a, 0x692c, 0x612e, 0x6930, 0xa18c, 0x00ff, 0x6132, 0x6934,
+ 0x6136, 0x6938, 0x613a, 0x6950, 0x6152, 0x080c, 0x9956, 0x080c,
+ 0x67a8, 0x080c, 0x6c50, 0x2d60, 0x00f8, 0x00d6, 0x6010, 0x2068,
+ 0x080c, 0x9596, 0x01c8, 0x6837, 0x0103, 0x6850, 0xd0b4, 0x0128,
+ 0xc0ec, 0x6852, 0x684b, 0x0006, 0x0048, 0xd0bc, 0x0118, 0x684b,
+ 0x0002, 0x0020, 0x684b, 0x0005, 0x080c, 0x9803, 0x6847, 0x0000,
+ 0x080c, 0x510c, 0x080c, 0x9742, 0x00de, 0x080c, 0x8078, 0x0005,
+ 0x0016, 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0140, 0x6837,
+ 0x0103, 0x684b, 0x0028, 0x6847, 0x0000, 0x080c, 0x510c, 0x00de,
+ 0x001e, 0xa186, 0x0013, 0x0148, 0xa186, 0x0014, 0x0130, 0xa186,
+ 0x0027, 0x0118, 0x080c, 0x80be, 0x0030, 0x080c, 0x6b73, 0x080c,
+ 0x974e, 0x080c, 0x6c50, 0x0005, 0x0056, 0x0066, 0x00d6, 0x00f6,
+ 0x2029, 0x0001, 0xa182, 0x0101, 0x1208, 0x0010, 0x2009, 0x0100,
+ 0x2130, 0x2069, 0xb298, 0x831c, 0x2300, 0xad18, 0x2009, 0x0020,
+ 0xaf90, 0x001d, 0x080c, 0x927f, 0xa6b2, 0x0020, 0x7804, 0xa06d,
+ 0x0110, 0x080c, 0x1600, 0x080c, 0x15d9, 0x0500, 0x8528, 0x6837,
+ 0x0110, 0x683b, 0x0000, 0x2d20, 0x7c06, 0xa68a, 0x003d, 0x1228,
+ 0x2608, 0xad90, 0x000f, 0x0459, 0x0088, 0xa6b2, 0x003c, 0x2009,
+ 0x003c, 0x2d78, 0xad90, 0x000f, 0x0411, 0x0c28, 0x00fe, 0x852f,
+ 0xa5ad, 0x0003, 0x7d36, 0xa5ac, 0x0000, 0x0028, 0x00fe, 0x852f,
+ 0xa5ad, 0x0003, 0x7d36, 0x00de, 0x006e, 0x005e, 0x0005, 0x00f6,
+ 0x8dff, 0x0158, 0x6804, 0xa07d, 0x0130, 0x6807, 0x0000, 0x080c,
+ 0x510c, 0x2f68, 0x0cb8, 0x080c, 0x510c, 0x00fe, 0x0005, 0x0156,
+ 0xa184, 0x0001, 0x0108, 0x8108, 0x810c, 0x21a8, 0x2304, 0x8007,
+ 0x2012, 0x8318, 0x8210, 0x1f04, 0x9286, 0x015e, 0x0005, 0x0066,
+ 0x0126, 0x2091, 0x8000, 0x2031, 0x0001, 0x601c, 0xa084, 0x000f,
+ 0x0083, 0x012e, 0x006e, 0x0005, 0x0126, 0x2091, 0x8000, 0x0066,
+ 0x2031, 0x0000, 0x601c, 0xa084, 0x000f, 0x001b, 0x006e, 0x012e,
+ 0x0005, 0x92c3, 0x92c3, 0x92be, 0x92e5, 0x92b1, 0x92be, 0x92e5,
+ 0x92be, 0x080c, 0x14f6, 0x0036, 0x2019, 0x0010, 0x080c, 0xa566,
+ 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0xa006, 0x0005,
+ 0xa085, 0x0001, 0x0005, 0x00d6, 0x86ff, 0x11d8, 0x6010, 0x2068,
+ 0x080c, 0x9596, 0x01c0, 0x6834, 0xa086, 0x0139, 0x1128, 0x684b,
+ 0x0005, 0x6853, 0x0000, 0x0028, 0xa00e, 0x2001, 0x0005, 0x080c,
+ 0x51df, 0x080c, 0x9803, 0x080c, 0x510c, 0x080c, 0x8078, 0xa085,
+ 0x0001, 0x00de, 0x0005, 0xa006, 0x0ce0, 0x6000, 0xa08a, 0x0010,
+ 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x92fc, 0x9319, 0x92fe, 0x9338,
+ 0x9316, 0x92fc, 0x92be, 0x92c3, 0x92c3, 0x92be, 0x92be, 0x92be,
+ 0x92be, 0x92be, 0x92be, 0x92be, 0x080c, 0x14f6, 0x86ff, 0x1198,
+ 0x00d6, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0x9803,
+ 0x00de, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c,
+ 0x67a8, 0x080c, 0x6c50, 0xa085, 0x0001, 0x0005, 0x080c, 0x190b,
+ 0x0c28, 0x00e6, 0x2071, 0xafc7, 0x7024, 0xac06, 0x1110, 0x080c,
+ 0x79e1, 0x601c, 0xa084, 0x000f, 0xa086, 0x0006, 0x1150, 0x0086,
+ 0x0096, 0x2049, 0x0001, 0x2c40, 0x080c, 0x7b9a, 0x009e, 0x008e,
+ 0x0010, 0x080c, 0x78de, 0x00ee, 0x1948, 0x080c, 0x92be, 0x0005,
+ 0x0036, 0x00e6, 0x2071, 0xafc7, 0x703c, 0xac06, 0x1140, 0x2019,
+ 0x0000, 0x080c, 0x7a64, 0x00ee, 0x003e, 0x0804, 0x92fe, 0x080c,
+ 0x7cb8, 0x00ee, 0x003e, 0x1904, 0x92fe, 0x080c, 0x92be, 0x0005,
+ 0x00c6, 0x601c, 0xa084, 0x000f, 0x0013, 0x00ce, 0x0005, 0x9369,
+ 0x93d3, 0x9501, 0x9374, 0x974e, 0x9369, 0xa558, 0x8078, 0x93d3,
+ 0x9362, 0x955f, 0x080c, 0x14f6, 0x080c, 0x9789, 0x1110, 0x080c,
+ 0x85f3, 0x0005, 0x080c, 0x6b73, 0x080c, 0x6c50, 0x080c, 0x8078,
+ 0x0005, 0x6017, 0x0001, 0x0005, 0x6010, 0xa080, 0x0019, 0x2c02,
+ 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x938f,
+ 0x9391, 0x93b1, 0x93c3, 0x93d0, 0x938f, 0x9369, 0x9369, 0x9369,
+ 0x93c3, 0x93c3, 0x938f, 0x938f, 0x938f, 0x938f, 0x93cd, 0x080c,
+ 0x14f6, 0x00e6, 0x6010, 0x2070, 0x7050, 0xc0b5, 0x7052, 0x2071,
+ 0xafc7, 0x7024, 0xac06, 0x0190, 0x080c, 0x78de, 0x6007, 0x0085,
+ 0x6003, 0x000b, 0x601f, 0x0002, 0x2001, 0xafa4, 0x2004, 0x6016,
+ 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x6017, 0x0001,
+ 0x0cd8, 0x00d6, 0x6010, 0x2068, 0x6850, 0xc0b5, 0x6852, 0x00de,
+ 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x080c, 0x67a8,
+ 0x080c, 0x6c50, 0x0005, 0x00d6, 0x6017, 0x0001, 0x6010, 0x2068,
+ 0x6850, 0xc0b5, 0x6852, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005,
+ 0x080c, 0x190b, 0x08f0, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6,
+ 0x000b, 0x0005, 0x93ea, 0x9371, 0x93ec, 0x93ea, 0x93ec, 0x93ec,
+ 0x936a, 0x93ea, 0x9364, 0x9364, 0x93ea, 0x93ea, 0x93ea, 0x93ea,
+ 0x93ea, 0x93ea, 0x080c, 0x14f6, 0x00d6, 0x6018, 0x2068, 0x6804,
+ 0xa084, 0x00ff, 0x00de, 0xa08a, 0x000c, 0x1a0c, 0x14f6, 0x000b,
+ 0x0005, 0x9405, 0x94a7, 0x9407, 0x9441, 0x9407, 0x9441, 0x9407,
+ 0x9411, 0x9405, 0x9441, 0x9405, 0x942d, 0x080c, 0x14f6, 0x6004,
+ 0xa08e, 0x0016, 0x0588, 0xa08e, 0x0004, 0x0570, 0xa08e, 0x0002,
+ 0x0558, 0x6004, 0x080c, 0x9789, 0x0904, 0x94c0, 0xa08e, 0x0021,
+ 0x0904, 0x94c4, 0xa08e, 0x0022, 0x0904, 0x94c0, 0xa08e, 0x003d,
+ 0x0904, 0x94c4, 0xa08e, 0x0039, 0x0904, 0x94c8, 0xa08e, 0x0035,
+ 0x0904, 0x94c8, 0xa08e, 0x001e, 0x0188, 0xa08e, 0x0001, 0x1150,
+ 0x00d6, 0x6018, 0x2068, 0x6804, 0xa084, 0x00ff, 0x00de, 0xa086,
+ 0x0006, 0x0110, 0x080c, 0x2ad9, 0x080c, 0x85f3, 0x080c, 0x974e,
+ 0x0005, 0x00c6, 0x00d6, 0x6104, 0xa186, 0x0016, 0x0904, 0x9498,
+ 0xa186, 0x0002, 0x1518, 0x6018, 0x2068, 0x2001, 0xad34, 0x2004,
+ 0xd0ac, 0x1904, 0x94ea, 0x68a0, 0xd0bc, 0x1904, 0x94ea, 0x6840,
+ 0xa084, 0x00ff, 0xa005, 0x0190, 0x8001, 0x6842, 0x6013, 0x0000,
+ 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x080c, 0x8022,
+ 0x0128, 0x2d00, 0x601a, 0x601f, 0x0001, 0x0450, 0x00de, 0x00ce,
+ 0x6004, 0xa08e, 0x0002, 0x11a8, 0x6018, 0xa080, 0x0028, 0x2004,
+ 0xa086, 0x007e, 0x1170, 0x2009, 0xad34, 0x2104, 0xc085, 0x200a,
+ 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x00ee, 0x080c, 0x85f3,
+ 0x0020, 0x080c, 0x85f3, 0x080c, 0x2ad9, 0x00e6, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x2aff, 0x012e, 0x00ee, 0x080c, 0x974e, 0x0005,
+ 0x2001, 0x0002, 0x080c, 0x4c30, 0x6003, 0x0001, 0x6007, 0x0002,
+ 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x0c80, 0x00c6,
+ 0x00d6, 0x6104, 0xa186, 0x0016, 0x0d58, 0x6018, 0x2068, 0x6840,
+ 0xa084, 0x00ff, 0xa005, 0x0904, 0x946e, 0x8001, 0x6842, 0x6003,
+ 0x0001, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00de, 0x00ce, 0x08b8,
+ 0x080c, 0x85f3, 0x0804, 0x943e, 0x080c, 0x8621, 0x0804, 0x943e,
+ 0x00d6, 0x2c68, 0x6104, 0x080c, 0x9a34, 0x00de, 0x0118, 0x080c,
+ 0x8078, 0x00b8, 0x6004, 0x8007, 0x6130, 0xa18c, 0x00ff, 0xa105,
+ 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0002, 0x6038,
+ 0x600a, 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c,
+ 0x6c50, 0x0005, 0x00de, 0x00ce, 0x080c, 0x85f3, 0x080c, 0x2ad9,
+ 0x00e6, 0x0126, 0x2091, 0x8000, 0x080c, 0x2aff, 0x6013, 0x0000,
+ 0x601f, 0x0007, 0x6017, 0x0398, 0x603f, 0x0000, 0x012e, 0x00ee,
+ 0x0005, 0x6000, 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005,
+ 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518, 0x9518,
+ 0x9518, 0x9369, 0x9518, 0x9371, 0x951a, 0x9371, 0x9527, 0x9518,
+ 0x080c, 0x14f6, 0x6004, 0xa086, 0x008b, 0x0148, 0x6007, 0x008b,
+ 0x6003, 0x000d, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0005, 0x080c,
+ 0x9742, 0x080c, 0x9596, 0x0580, 0x080c, 0x2ad9, 0x00d6, 0x080c,
+ 0x9596, 0x0168, 0x6010, 0x2068, 0x6837, 0x0103, 0x684b, 0x0006,
+ 0x6847, 0x0000, 0x6850, 0xc0ed, 0x6852, 0x080c, 0x510c, 0x2c68,
+ 0x080c, 0x8022, 0x0150, 0x6818, 0x601a, 0x080c, 0x9956, 0x00c6,
+ 0x2d60, 0x080c, 0x974e, 0x00ce, 0x0008, 0x2d60, 0x00de, 0x6013,
+ 0x0000, 0x601f, 0x0001, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+ 0x67ee, 0x080c, 0x6c50, 0x0010, 0x080c, 0x974e, 0x0005, 0x6000,
+ 0xa08a, 0x0010, 0x1a0c, 0x14f6, 0x000b, 0x0005, 0x9576, 0x9576,
+ 0x9576, 0x9578, 0x9579, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576,
+ 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x9576, 0x080c, 0x14f6,
+ 0x0005, 0x080c, 0x7cb8, 0x190c, 0x14f6, 0x6110, 0x2168, 0x684b,
+ 0x0006, 0x080c, 0x510c, 0x080c, 0x8078, 0x0005, 0xa284, 0x0007,
+ 0x1158, 0xa282, 0xb400, 0x0240, 0x2001, 0xad16, 0x2004, 0xa202,
+ 0x1218, 0xa085, 0x0001, 0x0005, 0xa006, 0x0ce8, 0x0026, 0x6210,
+ 0xa294, 0xf000, 0x002e, 0x0005, 0x00e6, 0x00c6, 0x0036, 0x0006,
+ 0x0126, 0x2091, 0x8000, 0x2061, 0xb400, 0x2071, 0xad00, 0x7344,
+ 0x7064, 0xa302, 0x12a8, 0x601c, 0xa206, 0x1160, 0x080c, 0x98e3,
+ 0x0148, 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x00c6, 0x080c,
+ 0x8078, 0x00ce, 0xace0, 0x0018, 0x7058, 0xac02, 0x1208, 0x0c38,
+ 0x012e, 0x000e, 0x003e, 0x00ce, 0x00ee, 0x0005, 0x00e6, 0x00c6,
+ 0x0016, 0xa188, 0xae34, 0x210c, 0x81ff, 0x0170, 0x2061, 0xb400,
+ 0x2071, 0xad00, 0x0016, 0x080c, 0x8022, 0x001e, 0x0138, 0x611a,
+ 0x080c, 0x2ad9, 0x080c, 0x8078, 0xa006, 0x0010, 0xa085, 0x0001,
+ 0x001e, 0x00ce, 0x00ee, 0x0005, 0x00c6, 0x0056, 0x0126, 0x2091,
+ 0x8000, 0x00c6, 0x080c, 0x8022, 0x005e, 0x0180, 0x6612, 0x651a,
+ 0x080c, 0x9956, 0x601f, 0x0003, 0x2009, 0x004b, 0x080c, 0x80a7,
+ 0xa085, 0x0001, 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0,
+ 0x00c6, 0x0056, 0x0126, 0x2091, 0x8000, 0x62a0, 0x00c6, 0x080c,
+ 0x8022, 0x005e, 0x0508, 0x6013, 0x0000, 0x651a, 0x080c, 0x9956,
+ 0x601f, 0x0003, 0x00c6, 0x2560, 0x080c, 0x4ecf, 0x00ce, 0x080c,
+ 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c,
+ 0xa712, 0x007e, 0x2009, 0x004c, 0x080c, 0x80a7, 0xa085, 0x0001,
+ 0x012e, 0x005e, 0x00ce, 0x0005, 0xa006, 0x0cd0, 0x00f6, 0x00c6,
+ 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0180, 0x7e12,
+ 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0005, 0x080c, 0x9683,
+ 0x2f60, 0x2009, 0x004d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+ 0x00ce, 0x00fe, 0x0005, 0x00f6, 0x00c6, 0x0046, 0x00c6, 0x080c,
+ 0x8022, 0x2c78, 0x00ce, 0x0178, 0x7e12, 0x2c00, 0x781a, 0x781f,
+ 0x0003, 0x2021, 0x0005, 0x0439, 0x2f60, 0x2009, 0x004e, 0x080c,
+ 0x80a7, 0xa085, 0x0001, 0x004e, 0x00ce, 0x00fe, 0x0005, 0x00f6,
+ 0x00c6, 0x0046, 0x00c6, 0x080c, 0x8022, 0x2c78, 0x00ce, 0x0178,
+ 0x7e12, 0x2c00, 0x781a, 0x781f, 0x0003, 0x2021, 0x0004, 0x0059,
+ 0x2f60, 0x2009, 0x0052, 0x080c, 0x80a7, 0xa085, 0x0001, 0x004e,
+ 0x00ce, 0x00fe, 0x0005, 0x0096, 0x0076, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x4e71, 0x0118, 0x2001, 0x9688, 0x0028, 0x080c, 0x4e43,
+ 0x0158, 0x2001, 0x968e, 0x0006, 0xa00e, 0x2400, 0x080c, 0x51df,
+ 0x080c, 0x510c, 0x000e, 0x0807, 0x2418, 0x080c, 0x6b15, 0x62a0,
+ 0x0086, 0x2041, 0x0001, 0x2039, 0x0001, 0x2608, 0x080c, 0x6900,
+ 0x008e, 0x080c, 0x681d, 0x2f08, 0x2648, 0x080c, 0xa712, 0x613c,
+ 0x81ff, 0x090c, 0x69a9, 0x012e, 0x007e, 0x009e, 0x0005, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+ 0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+ 0x2009, 0x001f, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+ 0x080c, 0x8022, 0x001e, 0x0188, 0x660a, 0x611a, 0x080c, 0x9956,
+ 0x601f, 0x0008, 0x2d00, 0x6012, 0x2009, 0x0021, 0x080c, 0x80a7,
+ 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188,
+ 0x660a, 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012,
+ 0x2009, 0x003d, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce,
+ 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126, 0x2091, 0x8000, 0x00c6,
+ 0x080c, 0x9807, 0x001e, 0x0180, 0x611a, 0x080c, 0x9956, 0x601f,
+ 0x0001, 0x2d00, 0x6012, 0x2009, 0x0000, 0x080c, 0x80a7, 0xa085,
+ 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006, 0x0cd8, 0x00c6, 0x0126,
+ 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0188, 0x660a,
+ 0x611a, 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009,
+ 0x0044, 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005,
+ 0xa006, 0x0cd8, 0x0026, 0x00d6, 0x6218, 0x2268, 0x6a3c, 0x82ff,
+ 0x0110, 0x8211, 0x6a3e, 0x00de, 0x002e, 0x0005, 0x0006, 0x6000,
+ 0xa086, 0x0000, 0x0190, 0x6013, 0x0000, 0x601f, 0x0007, 0x2001,
+ 0xafa3, 0x2004, 0x0006, 0xa082, 0x0051, 0x000e, 0x0208, 0x8004,
+ 0x6016, 0x080c, 0xabb4, 0x603f, 0x0000, 0x000e, 0x0005, 0x0066,
+ 0x00c6, 0x00d6, 0x2031, 0xad52, 0x2634, 0xd6e4, 0x0128, 0x6618,
+ 0x2660, 0x6e48, 0x080c, 0x4dfc, 0x00de, 0x00ce, 0x006e, 0x0005,
+ 0x0006, 0x0016, 0x6004, 0xa08e, 0x0002, 0x0140, 0xa08e, 0x0003,
+ 0x0128, 0xa08e, 0x0004, 0x0110, 0xa085, 0x0001, 0x001e, 0x000e,
+ 0x0005, 0x0006, 0x00d6, 0x6010, 0xa06d, 0x0148, 0x6834, 0xa086,
+ 0x0139, 0x0138, 0x6838, 0xd0fc, 0x0110, 0xa006, 0x0010, 0xa085,
+ 0x0001, 0x00de, 0x000e, 0x0005, 0x00c6, 0x0126, 0x2091, 0x8000,
+ 0x00c6, 0x080c, 0x8022, 0x001e, 0x0190, 0x611a, 0x080c, 0x9956,
+ 0x601f, 0x0001, 0x2d00, 0x6012, 0x080c, 0x2ad9, 0x2009, 0x0028,
+ 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+ 0x0cd8, 0xa186, 0x0015, 0x1178, 0x2011, 0xad20, 0x2204, 0xa086,
+ 0x0074, 0x1148, 0x080c, 0x8943, 0x6003, 0x0001, 0x6007, 0x0029,
+ 0x080c, 0x67ee, 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005,
+ 0xa186, 0x0016, 0x1128, 0x2001, 0x0004, 0x080c, 0x4c30, 0x00e8,
+ 0xa186, 0x0015, 0x11e8, 0x2011, 0xad20, 0x2204, 0xa086, 0x0014,
+ 0x11b8, 0x00d6, 0x6018, 0x2068, 0x080c, 0x4d72, 0x00de, 0x080c,
+ 0x89f7, 0x1170, 0x00d6, 0x6018, 0x2068, 0x6890, 0x00de, 0xa005,
+ 0x0138, 0x2001, 0x0006, 0x080c, 0x4c30, 0x080c, 0x81f6, 0x0020,
+ 0x080c, 0x85f3, 0x080c, 0x8078, 0x0005, 0x6848, 0xa086, 0x0005,
+ 0x1108, 0x0009, 0x0005, 0x6850, 0xc0ad, 0x6852, 0x0005, 0x00e6,
+ 0x0126, 0x2071, 0xad00, 0x2091, 0x8000, 0x7544, 0xa582, 0x0001,
+ 0x0608, 0x7048, 0x2060, 0x6000, 0xa086, 0x0000, 0x0148, 0xace0,
+ 0x0018, 0x7058, 0xac02, 0x1208, 0x0cb0, 0x2061, 0xb400, 0x0c98,
+ 0x6003, 0x0008, 0x8529, 0x7546, 0xaca8, 0x0018, 0x7058, 0xa502,
+ 0x1230, 0x754a, 0xa085, 0x0001, 0x012e, 0x00ee, 0x0005, 0x704b,
+ 0xb400, 0x0cc0, 0xa006, 0x0cc0, 0x00e6, 0x2071, 0xb28c, 0x7014,
+ 0xd0e4, 0x0150, 0x6013, 0x0000, 0x6003, 0x0001, 0x6007, 0x0050,
+ 0x080c, 0x67a8, 0x080c, 0x6c50, 0x00ee, 0x0005, 0x00c6, 0x00f6,
+ 0x2c78, 0x080c, 0x5029, 0x00fe, 0x0120, 0x601c, 0xa084, 0x000f,
+ 0x0013, 0x00ce, 0x0005, 0x9369, 0x985e, 0x9861, 0x9864, 0xa9a7,
+ 0xa9c2, 0xa9c5, 0x9369, 0x9369, 0x080c, 0x14f6, 0xe000, 0xe000,
+ 0x0005, 0xe000, 0xe000, 0x0005, 0x0009, 0x0005, 0x00f6, 0x2c78,
+ 0x080c, 0x5029, 0x0538, 0x080c, 0x8022, 0x1128, 0x2001, 0xafa5,
+ 0x2004, 0x783e, 0x00f8, 0x7818, 0x601a, 0x080c, 0x9956, 0x781c,
+ 0xa086, 0x0003, 0x0128, 0x7808, 0x6036, 0x2f00, 0x603a, 0x0020,
+ 0x7808, 0x603a, 0x2f00, 0x6036, 0x602a, 0x601f, 0x0001, 0x6007,
+ 0x0035, 0x6003, 0x0001, 0x7950, 0x6152, 0x080c, 0x67a8, 0x080c,
+ 0x6c50, 0x2f60, 0x00fe, 0x0005, 0x0016, 0x00f6, 0x682c, 0x6032,
+ 0xa08e, 0x0001, 0x0138, 0xa086, 0x0005, 0x0140, 0xa006, 0x602a,
+ 0x602e, 0x00a0, 0x6820, 0xc0f4, 0xc0d5, 0x6822, 0x6810, 0x2078,
+ 0x787c, 0x6938, 0xa102, 0x7880, 0x6934, 0xa103, 0x1e78, 0x6834,
+ 0x602a, 0x6838, 0xa084, 0xfffc, 0x683a, 0x602e, 0x2d00, 0x6036,
+ 0x6808, 0x603a, 0x6918, 0x611a, 0x6950, 0x6152, 0x601f, 0x0001,
+ 0x6007, 0x0039, 0x6003, 0x0001, 0x080c, 0x67a8, 0x6803, 0x0002,
+ 0x00fe, 0x001e, 0x0005, 0x00f6, 0x2c78, 0x080c, 0x5029, 0x1118,
+ 0xa085, 0x0001, 0x0070, 0x6020, 0xd0f4, 0x1150, 0xc0f5, 0x6022,
+ 0x6010, 0x2078, 0x7828, 0x603a, 0x782c, 0x6036, 0x080c, 0x190b,
+ 0xa006, 0x00fe, 0x0005, 0x0006, 0x0016, 0x6004, 0xa08e, 0x0034,
+ 0x01b8, 0xa08e, 0x0035, 0x01a0, 0xa08e, 0x0036, 0x0188, 0xa08e,
+ 0x0037, 0x0170, 0xa08e, 0x0038, 0x0158, 0xa08e, 0x0039, 0x0140,
+ 0xa08e, 0x003a, 0x0128, 0xa08e, 0x003b, 0x0110, 0xa085, 0x0001,
+ 0x001e, 0x000e, 0x0005, 0x0006, 0x0016, 0x0026, 0x0036, 0x00e6,
+ 0x2001, 0xaf9f, 0x200c, 0x8000, 0x2014, 0x2001, 0x0032, 0x080c,
+ 0x6665, 0x2001, 0xafa3, 0x82ff, 0x1110, 0x2011, 0x0002, 0x2202,
+ 0x2001, 0xafa1, 0x200c, 0x8000, 0x2014, 0x2071, 0xaf8d, 0x711a,
+ 0x721e, 0x2001, 0x0064, 0x080c, 0x6665, 0x2001, 0xafa4, 0x82ff,
+ 0x1110, 0x2011, 0x0002, 0x2202, 0x2009, 0xafa5, 0xa280, 0x000a,
+ 0x200a, 0x00ee, 0x003e, 0x002e, 0x001e, 0x000e, 0x0005, 0x0006,
+ 0x00e6, 0x2001, 0xafa3, 0x2003, 0x0028, 0x2001, 0xafa4, 0x2003,
+ 0x0014, 0x2071, 0xaf8d, 0x701b, 0x0000, 0x701f, 0x07d0, 0x2001,
+ 0xafa5, 0x2003, 0x001e, 0x00ee, 0x000e, 0x0005, 0x00d6, 0x6054,
+ 0xa06d, 0x0110, 0x080c, 0x15f0, 0x00de, 0x0005, 0x0005, 0x00c6,
+ 0x0126, 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0178,
+ 0x611a, 0x0ca1, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0033,
+ 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+ 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+ 0x1500, 0x7080, 0xa086, 0x0018, 0x11e0, 0x6010, 0x2068, 0x6a3c,
+ 0xd2e4, 0x1160, 0x2c78, 0x080c, 0x6e05, 0x01d8, 0x706c, 0x6a50,
+ 0xa206, 0x1160, 0x7070, 0x6a54, 0xa206, 0x1140, 0x6218, 0xa290,
+ 0x0028, 0x2214, 0x2009, 0x0000, 0x080c, 0x2b1e, 0x080c, 0x81f6,
+ 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+ 0x0005, 0x7050, 0x6a54, 0xa206, 0x0d48, 0x0c80, 0x00c6, 0x0126,
+ 0x2091, 0x8000, 0x00c6, 0x080c, 0x8022, 0x001e, 0x0180, 0x611a,
+ 0x080c, 0x9956, 0x601f, 0x0001, 0x2d00, 0x6012, 0x2009, 0x0043,
+ 0x080c, 0x80a7, 0xa085, 0x0001, 0x012e, 0x00ce, 0x0005, 0xa006,
+ 0x0cd8, 0x00d6, 0x00e6, 0x00f6, 0x2071, 0xad00, 0xa186, 0x0015,
+ 0x11c0, 0x7080, 0xa086, 0x0004, 0x11a0, 0x6010, 0xa0e8, 0x000f,
+ 0x2c78, 0x080c, 0x6e05, 0x01a8, 0x706c, 0x6a08, 0xa206, 0x1130,
+ 0x7070, 0x6a0c, 0xa206, 0x1110, 0x080c, 0x2ad9, 0x080c, 0x81f6,
+ 0x0020, 0x080c, 0x85f3, 0x080c, 0x8078, 0x00fe, 0x00ee, 0x00de,
+ 0x0005, 0x7050, 0x6a0c, 0xa206, 0x0d78, 0x0c80, 0x0016, 0x0026,
+ 0x684c, 0xd0ac, 0x0178, 0x6914, 0x6a10, 0x2100, 0xa205, 0x0150,
+ 0x6860, 0xa106, 0x1118, 0x685c, 0xa206, 0x0120, 0x6962, 0x6a5e,
+ 0xa085, 0x0001, 0x002e, 0x001e, 0x0005, 0x00d6, 0x0036, 0x6310,
+ 0x2368, 0x684a, 0x6952, 0xa29e, 0x4000, 0x1188, 0x00c6, 0x6318,
+ 0x2360, 0x2009, 0x0000, 0x080c, 0x4f6e, 0x1108, 0xc185, 0x6000,
+ 0xd0bc, 0x0108, 0xc18d, 0x6a66, 0x696a, 0x00ce, 0x0080, 0x6a66,
+ 0x3918, 0xa398, 0x0006, 0x231c, 0x686b, 0x0004, 0x6b72, 0x00c6,
+ 0x6318, 0x2360, 0x6004, 0xa084, 0x00ff, 0x686e, 0x00ce, 0x080c,
+ 0x510c, 0x003e, 0x00de, 0x0005, 0x00c6, 0x0026, 0x0016, 0xa186,
+ 0x0035, 0x0110, 0x6a34, 0x0008, 0x6a28, 0x080c, 0x9586, 0x01f0,
+ 0x2260, 0x611c, 0xa186, 0x0003, 0x0118, 0xa186, 0x0006, 0x1190,
+ 0x6834, 0xa206, 0x0140, 0x6838, 0xa206, 0x1160, 0x6108, 0x6834,
+ 0xa106, 0x1140, 0x0020, 0x6008, 0x6938, 0xa106, 0x1118, 0x6018,
+ 0x6918, 0xa106, 0x001e, 0x002e, 0x00ce, 0x0005, 0xa085, 0x0001,
+ 0x0cc8, 0x0066, 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013,
+ 0x006e, 0x0005, 0x9a7a, 0x9eff, 0xa027, 0x9a7a, 0x9a7a, 0x9a7a,
+ 0x9a7a, 0x9a7a, 0x9ab2, 0xa0a3, 0x9a7a, 0x9a7a, 0x9a7a, 0x9a7a,
+ 0x9a7a, 0x9a7a, 0x080c, 0x14f6, 0x0066, 0x6000, 0xa0b2, 0x0010,
+ 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005, 0x9a95, 0xa4fd, 0x9a95,
+ 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0x9a95, 0xa4c1, 0xa545, 0x9a95,
+ 0xaaea, 0xab1a, 0xaaea, 0xab1a, 0x9a95, 0x080c, 0x14f6, 0x0066,
+ 0x6000, 0xa0b2, 0x0010, 0x1a0c, 0x14f6, 0x0013, 0x006e, 0x0005,
+ 0x9ab0, 0xa1d8, 0xa295, 0xa2c2, 0xa346, 0x9ab0, 0xa433, 0xa3de,
+ 0xa0af, 0xa497, 0xa4ac, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0, 0x9ab0,
+ 0x080c, 0x14f6, 0xa1b2, 0x0080, 0x1a0c, 0x14f6, 0x2100, 0xa1b2,
+ 0x0040, 0x1a04, 0x9e79, 0x0002, 0x9afc, 0x9cab, 0x9afc, 0x9afc,
+ 0x9afc, 0x9cb2, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+ 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc,
+ 0x9afc, 0x9afc, 0x9afc, 0x9afe, 0x9b5a, 0x9b65, 0x9ba6, 0x9bc0,
+ 0x9c3e, 0x9c9c, 0x9afc, 0x9afc, 0x9cb5, 0x9afc, 0x9afc, 0x9cc4,
+ 0x9ccb, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9afc, 0x9d42, 0x9afc,
+ 0x9afc, 0x9d4d, 0x9afc, 0x9afc, 0x9d18, 0x9afc, 0x9afc, 0x9afc,
+ 0x9d61, 0x9afc, 0x9afc, 0x9afc, 0x9dd5, 0x9afc, 0x9afc, 0x9afc,
+ 0x9afc, 0x9afc, 0x9afc, 0x9e40, 0x080c, 0x14f6, 0x080c, 0x502d,
+ 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+ 0x1140, 0x6007, 0x0009, 0x602b, 0x0009, 0x6013, 0x0000, 0x0804,
+ 0x9ca6, 0x080c, 0x501d, 0x00e6, 0x00c6, 0x0036, 0x0026, 0x0016,
+ 0x6218, 0x2270, 0x72a0, 0x0026, 0x2019, 0x0029, 0x080c, 0x68e7,
+ 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712,
+ 0x007e, 0x001e, 0x2e60, 0x080c, 0x4ecf, 0x001e, 0x002e, 0x003e,
+ 0x00ce, 0x00ee, 0x6618, 0x00c6, 0x2660, 0x080c, 0x4ceb, 0x00ce,
+ 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x0278,
+ 0x080c, 0xa656, 0x1904, 0x9ba0, 0x080c, 0xa5f6, 0x1120, 0x6007,
+ 0x0008, 0x0804, 0x9ca6, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c,
+ 0xa801, 0x0128, 0x080c, 0xa656, 0x0d78, 0x0804, 0x9ba0, 0x6013,
+ 0x1900, 0x0c88, 0x6106, 0x080c, 0xa5a6, 0x6007, 0x0006, 0x0804,
+ 0x9ca6, 0x6007, 0x0007, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+ 0x9e76, 0x00d6, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+ 0xa686, 0x0006, 0x0188, 0xa686, 0x0004, 0x0170, 0x6e04, 0xa6b4,
+ 0x00ff, 0xa686, 0x0006, 0x0140, 0xa686, 0x0004, 0x0128, 0xa686,
+ 0x0005, 0x0110, 0x00de, 0x00e0, 0x080c, 0xa6b4, 0x11a0, 0xa686,
+ 0x0006, 0x1150, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+ 0x0000, 0x080c, 0x2b1e, 0x002e, 0x080c, 0x4d72, 0x6007, 0x000a,
+ 0x00de, 0x0804, 0x9ca6, 0x6007, 0x000b, 0x00de, 0x0804, 0x9ca6,
+ 0x080c, 0x2ad9, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x080c, 0xab4e,
+ 0x1904, 0x9e76, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa686,
+ 0x0707, 0x0d70, 0x0026, 0x6218, 0xa290, 0x0028, 0x2214, 0x2009,
+ 0x0000, 0x080c, 0x2b1e, 0x002e, 0x6007, 0x000c, 0x0804, 0x9ca6,
+ 0x080c, 0x502d, 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009,
+ 0xa086, 0x0008, 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618,
+ 0xa6b0, 0x0001, 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06e8,
+ 0x1138, 0x0026, 0x2001, 0x0006, 0x080c, 0x4c5d, 0x002e, 0x0050,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006,
+ 0x1904, 0x9ba0, 0x080c, 0xa6c1, 0x1120, 0x6007, 0x000e, 0x0804,
+ 0x9ca6, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+ 0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+ 0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+ 0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+ 0x004e, 0x6007, 0x0001, 0x0804, 0x9ca6, 0x2001, 0x0001, 0x080c,
+ 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036, 0x20a9, 0x0004, 0x2019,
+ 0xad05, 0x2011, 0xb290, 0x080c, 0x8a7c, 0x003e, 0x002e, 0x001e,
+ 0x015e, 0xa005, 0x0168, 0xa6b4, 0xff00, 0x8637, 0xa682, 0x0004,
+ 0x0a04, 0x9ba0, 0xa682, 0x0007, 0x0a04, 0x9bea, 0x0804, 0x9ba0,
+ 0x6013, 0x1900, 0x6007, 0x0009, 0x0804, 0x9ca6, 0x080c, 0x502d,
+ 0x1140, 0x2001, 0xad34, 0x2004, 0xa084, 0x0009, 0xa086, 0x0008,
+ 0x1110, 0x0804, 0x9b09, 0x080c, 0x501d, 0x6618, 0xa6b0, 0x0001,
+ 0x2634, 0xa684, 0x00ff, 0xa082, 0x0006, 0x06b0, 0xa6b4, 0xff00,
+ 0x8637, 0xa686, 0x0004, 0x0120, 0xa686, 0x0006, 0x1904, 0x9ba0,
+ 0x080c, 0xa6e9, 0x1130, 0x080c, 0xa5f6, 0x1118, 0x6007, 0x0010,
+ 0x04e8, 0x0046, 0x6418, 0xa4a0, 0x0028, 0x2424, 0xa4a4, 0x00ff,
+ 0x8427, 0x0046, 0x080c, 0x2ad9, 0x004e, 0x0016, 0xa006, 0x2009,
+ 0xad52, 0x210c, 0xd1a4, 0x0158, 0x2009, 0x0029, 0x080c, 0xa96c,
+ 0x6018, 0x00d6, 0x2068, 0x6800, 0xc0e5, 0x6802, 0x00de, 0x001e,
+ 0x004e, 0x6007, 0x0001, 0x00d0, 0x080c, 0xa801, 0x0140, 0xa6b4,
+ 0xff00, 0x8637, 0xa686, 0x0006, 0x0958, 0x0804, 0x9ba0, 0x6013,
+ 0x1900, 0x6007, 0x0009, 0x0050, 0x080c, 0xab4e, 0x1904, 0x9e76,
+ 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0012, 0x6003, 0x0001,
+ 0x080c, 0x67ee, 0x0005, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c,
+ 0x67ee, 0x0cc0, 0x6007, 0x0005, 0x0cc0, 0x080c, 0xab4e, 0x1904,
+ 0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6007, 0x0020, 0x6003,
+ 0x0001, 0x080c, 0x67ee, 0x0005, 0x6007, 0x0023, 0x6003, 0x0001,
+ 0x080c, 0x67ee, 0x0005, 0x080c, 0xab4e, 0x1904, 0x9e76, 0x080c,
+ 0x9e98, 0x1904, 0x9ba0, 0x0016, 0x0026, 0x2011, 0xb291, 0x2214,
+ 0xa286, 0xffff, 0x0190, 0x2c08, 0x080c, 0x9586, 0x01d8, 0x2260,
+ 0x2011, 0xb290, 0x2214, 0x6008, 0xa206, 0x11a0, 0x6018, 0xa190,
+ 0x0006, 0x2214, 0xa206, 0x01e0, 0x0068, 0x2011, 0xb290, 0x2214,
+ 0x2c08, 0x080c, 0xa940, 0x11a0, 0x2011, 0xb291, 0x2214, 0xa286,
+ 0xffff, 0x01a0, 0x2160, 0x6007, 0x0026, 0x6013, 0x1700, 0x2011,
+ 0xb289, 0x2214, 0xa296, 0xffff, 0x1160, 0x6007, 0x0025, 0x0048,
+ 0x601c, 0xa086, 0x0007, 0x1d70, 0x080c, 0x8078, 0x2160, 0x6007,
+ 0x0025, 0x6003, 0x0001, 0x080c, 0x67ee, 0x002e, 0x001e, 0x0005,
+ 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026, 0x0036,
+ 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c, 0x8a7c,
+ 0x003e, 0x002e, 0x001e, 0x015e, 0x0120, 0x6007, 0x0031, 0x0804,
+ 0x9ca6, 0x080c, 0x87bd, 0x080c, 0x574f, 0x1158, 0x0006, 0x0026,
+ 0x0036, 0x080c, 0x576b, 0x0110, 0x080c, 0x5726, 0x003e, 0x002e,
+ 0x000e, 0x0005, 0x6106, 0x080c, 0x9eb4, 0x6007, 0x002b, 0x0804,
+ 0x9ca6, 0x6007, 0x002c, 0x0804, 0x9ca6, 0x080c, 0xab4e, 0x1904,
+ 0x9e76, 0x080c, 0x9e98, 0x1904, 0x9ba0, 0x6106, 0x080c, 0x9eb8,
+ 0x1120, 0x6007, 0x002e, 0x0804, 0x9ca6, 0x6007, 0x002f, 0x0804,
+ 0x9ca6, 0x00e6, 0x00d6, 0x00c6, 0x6018, 0xa080, 0x0001, 0x200c,
+ 0xa184, 0x00ff, 0xa086, 0x0006, 0x0158, 0xa184, 0xff00, 0x8007,
+ 0xa086, 0x0006, 0x0128, 0x00ce, 0x00de, 0x00ee, 0x0804, 0x9cab,
+ 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904, 0x9dd2, 0x2071, 0xb28c,
+ 0x7010, 0x6036, 0x7014, 0x603a, 0x7108, 0x720c, 0x2001, 0xad52,
+ 0x2004, 0xd0a4, 0x0140, 0x6018, 0x2068, 0x6810, 0xa106, 0x1118,
+ 0x6814, 0xa206, 0x01f8, 0x2001, 0xad52, 0x2004, 0xd0ac, 0x1580,
+ 0x2069, 0xad00, 0x6870, 0xa206, 0x1558, 0x686c, 0xa106, 0x1540,
+ 0x7210, 0x080c, 0x9586, 0x0548, 0x080c, 0xa9d4, 0x0530, 0x622a,
+ 0x6007, 0x0036, 0x6003, 0x0001, 0x080c, 0x67a8, 0x00ce, 0x00de,
+ 0x00ee, 0x0005, 0x7214, 0xa286, 0xffff, 0x0150, 0x080c, 0x9586,
+ 0x01a0, 0xa280, 0x0002, 0x2004, 0x7110, 0xa106, 0x1170, 0x0c08,
+ 0x7210, 0x2c08, 0x080c, 0xa940, 0x2c10, 0x2160, 0x0130, 0x08c8,
+ 0x6007, 0x0037, 0x6013, 0x1500, 0x08e8, 0x6007, 0x0037, 0x6013,
+ 0x1700, 0x08c0, 0x6007, 0x0012, 0x08a8, 0x6018, 0xa080, 0x0001,
+ 0x2004, 0xa084, 0xff00, 0x8007, 0xa086, 0x0006, 0x1904, 0x9cab,
+ 0x00e6, 0x00d6, 0x00c6, 0x2001, 0xad71, 0x2004, 0xd0e4, 0x0904,
+ 0x9e38, 0x2069, 0xad00, 0x2071, 0xb28c, 0x7008, 0x6036, 0x720c,
+ 0x623a, 0xa286, 0xffff, 0x1140, 0x7208, 0x00c6, 0x2c08, 0x080c,
+ 0xa940, 0x2c10, 0x00ce, 0x0588, 0x080c, 0x9586, 0x0570, 0x00c6,
+ 0x0026, 0x2260, 0x080c, 0x928f, 0x002e, 0x00ce, 0x7118, 0xa18c,
+ 0xff00, 0x810f, 0xa186, 0x0001, 0x0158, 0xa186, 0x0005, 0x0118,
+ 0xa186, 0x0007, 0x1178, 0xa280, 0x0004, 0x2004, 0xa005, 0x0150,
+ 0x0056, 0x7510, 0x7614, 0x080c, 0xa9eb, 0x005e, 0x00ce, 0x00de,
+ 0x00ee, 0x0005, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+ 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c88, 0x6007, 0x003b, 0x602b,
+ 0x0009, 0x6013, 0x1700, 0x6003, 0x0001, 0x080c, 0x67a8, 0x0c30,
+ 0x6007, 0x003b, 0x602b, 0x000b, 0x6013, 0x0000, 0x0804, 0x9daa,
+ 0x00e6, 0x0026, 0x080c, 0x502d, 0x0558, 0x080c, 0x501d, 0x080c,
+ 0xabc5, 0x1520, 0x2071, 0xad00, 0x70d0, 0xc085, 0x70d2, 0x00f6,
+ 0x2079, 0x0100, 0x729c, 0xa284, 0x00ff, 0x706e, 0x78e6, 0xa284,
+ 0xff00, 0x7270, 0xa205, 0x7072, 0x78ea, 0x00fe, 0x70db, 0x0000,
+ 0x2001, 0xad52, 0x2004, 0xd0a4, 0x0120, 0x2011, 0xafe0, 0x2013,
+ 0x07d0, 0xd0ac, 0x1128, 0x080c, 0x28fa, 0x0010, 0x080c, 0xabf1,
+ 0x002e, 0x00ee, 0x080c, 0x8078, 0x0804, 0x9caa, 0x080c, 0x8078,
+ 0x0005, 0x2600, 0x0002, 0x9e81, 0x9e81, 0x9e81, 0x9e81, 0x9e81,
+ 0x9e83, 0x080c, 0x14f6, 0x080c, 0xab4e, 0x1d80, 0x0089, 0x1138,
+ 0x6007, 0x0045, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005, 0x080c,
+ 0x2ad9, 0x6007, 0x0001, 0x6003, 0x0001, 0x080c, 0x67ee, 0x0005,
+ 0x00d6, 0x0066, 0x6618, 0x2668, 0x6e04, 0xa6b4, 0xff00, 0x8637,
+ 0xa686, 0x0006, 0x0170, 0xa686, 0x0004, 0x0158, 0x6e04, 0xa6b4,
+ 0x00ff, 0xa686, 0x0006, 0x0128, 0xa686, 0x0004, 0x0110, 0xa085,
+ 0x0001, 0x006e, 0x00de, 0x0005, 0x00d6, 0x0449, 0x00de, 0x0005,
+ 0x00d6, 0x0491, 0x11f0, 0x680c, 0xa08c, 0xff00, 0x6820, 0xa084,
+ 0x00ff, 0xa115, 0x6212, 0x6824, 0x602a, 0xd1e4, 0x0118, 0x2009,
+ 0x0001, 0x0060, 0xd1ec, 0x0168, 0x6920, 0xa18c, 0x00ff, 0x6824,
+ 0x080c, 0x2676, 0x1130, 0x2110, 0x2009, 0x0000, 0x080c, 0x2b1e,
+ 0x0018, 0xa085, 0x0001, 0x0008, 0xa006, 0x00de, 0x0005, 0x2069,
+ 0xb28d, 0x6800, 0xa082, 0x0010, 0x1228, 0x6013, 0x0000, 0xa085,
+ 0x0001, 0x0008, 0xa006, 0x0005, 0x6013, 0x0000, 0x2069, 0xb28c,
+ 0x6808, 0xa084, 0xff00, 0xa086, 0x0800, 0x1140, 0x6800, 0xa084,
+ 0x00ff, 0xa08e, 0x0014, 0x0110, 0xa08e, 0x0010, 0x0005, 0x6004,
+ 0xa0b2, 0x0080, 0x1a0c, 0x14f6, 0xa1b6, 0x0013, 0x1130, 0x2008,
+ 0xa1b2, 0x0040, 0x1a04, 0x9ffb, 0x0092, 0xa1b6, 0x0027, 0x0120,
+ 0xa1b6, 0x0014, 0x190c, 0x14f6, 0x2001, 0x0007, 0x080c, 0x4c5d,
+ 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0x9f5f,
+ 0x9f61, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f6f, 0x9ff4, 0x9fbf,
+ 0x9ff4, 0x9fd0, 0x9ff4, 0x9f6f, 0x9ff4, 0x9fec, 0x9ff4, 0x9fec,
+ 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f,
+ 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f61, 0x9f5f, 0x9ff4,
+ 0x9f5f, 0x9f5f, 0x9ff4, 0x9f5f, 0x9ff1, 0x9ff4, 0x9f5f, 0x9f5f,
+ 0x9f5f, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f,
+ 0x9f69, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x9ff0, 0x9ff4, 0x9f5f,
+ 0x9f5f, 0x9ff4, 0x9ff4, 0x9f5f, 0x9f5f, 0x9f5f, 0x9f5f, 0x080c,
+ 0x14f6, 0x080c, 0x6b73, 0x6003, 0x0002, 0x080c, 0x6c50, 0x0804,
+ 0x9ffa, 0x2001, 0x0000, 0x080c, 0x4c1e, 0x0804, 0x9ff4, 0x00f6,
+ 0x2079, 0xad51, 0x7804, 0x00fe, 0xd0ac, 0x1904, 0x9ff4, 0x2001,
+ 0x0000, 0x080c, 0x4c1e, 0x6018, 0xa080, 0x0004, 0x2004, 0xa086,
+ 0x00ff, 0x1140, 0x00f6, 0x2079, 0xad00, 0x7894, 0x8000, 0x7896,
+ 0x00fe, 0x00e0, 0x00c6, 0x6018, 0x2060, 0x6000, 0xd0f4, 0x1140,
+ 0x6010, 0xa005, 0x0128, 0x00ce, 0x080c, 0x3cce, 0x0804, 0x9ff4,
+ 0x00ce, 0x2001, 0xad00, 0x2004, 0xa086, 0x0002, 0x1138, 0x00f6,
+ 0x2079, 0xad00, 0x7894, 0x8000, 0x7896, 0x00fe, 0x2001, 0x0002,
+ 0x080c, 0x4c30, 0x080c, 0x6b73, 0x601f, 0x0001, 0x6003, 0x0001,
+ 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00c6, 0x6118,
+ 0x2160, 0x2009, 0x0001, 0x080c, 0x6519, 0x00ce, 0x04d8, 0x6618,
+ 0x00d6, 0x2668, 0x6e04, 0x00de, 0xa6b4, 0xff00, 0x8637, 0xa686,
+ 0x0006, 0x0550, 0xa686, 0x0004, 0x0538, 0x2001, 0x0004, 0x0410,
+ 0x2001, 0xad00, 0x2004, 0xa086, 0x0003, 0x1110, 0x080c, 0x3cce,
+ 0x2001, 0x0006, 0x0489, 0x6618, 0x00d6, 0x2668, 0x6e04, 0x00de,
+ 0xa6b4, 0xff00, 0x8637, 0xa686, 0x0006, 0x0170, 0x2001, 0x0006,
+ 0x0048, 0x2001, 0x0004, 0x0030, 0x2001, 0x0006, 0x00e9, 0x0020,
+ 0x0018, 0x0010, 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x8078,
+ 0x080c, 0x6c50, 0x0005, 0x2600, 0x0002, 0xa003, 0xa003, 0xa003,
+ 0xa003, 0xa003, 0xa005, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x080c,
+ 0x8078, 0x080c, 0x6c50, 0x0005, 0x0016, 0x00d6, 0x6118, 0x2168,
+ 0x6900, 0xd184, 0x0188, 0x6104, 0xa18e, 0x000a, 0x1128, 0x699c,
+ 0xd1a4, 0x1110, 0x2001, 0x0007, 0x080c, 0x4c30, 0x2001, 0x0000,
+ 0x080c, 0x4c1e, 0x080c, 0x2aff, 0x00de, 0x001e, 0x0005, 0x00d6,
+ 0x6618, 0x2668, 0x6804, 0xa084, 0xff00, 0x8007, 0x00de, 0xa0b2,
+ 0x000c, 0x1a0c, 0x14f6, 0xa1b6, 0x0015, 0x1110, 0x003b, 0x0028,
+ 0xa1b6, 0x0016, 0x190c, 0x14f6, 0x006b, 0x0005, 0x86b9, 0x86b9,
+ 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0xa08f, 0xa056, 0x86b9, 0x86b9,
+ 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x86b9,
+ 0xa08f, 0xa096, 0x86b9, 0x86b9, 0x86b9, 0x86b9, 0x00f6, 0x2079,
+ 0xad51, 0x7804, 0xd0ac, 0x11e0, 0x6018, 0xa07d, 0x01c8, 0x7800,
+ 0xd0f4, 0x1118, 0x7810, 0xa005, 0x1198, 0x2001, 0x0000, 0x080c,
+ 0x4c1e, 0x2001, 0x0002, 0x080c, 0x4c30, 0x601f, 0x0001, 0x6003,
+ 0x0001, 0x6007, 0x0002, 0x080c, 0x67ee, 0x080c, 0x6c50, 0x00a8,
+ 0x2011, 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x1168,
+ 0x00c6, 0x080c, 0x4cdc, 0x0120, 0x00ce, 0x080c, 0x8078, 0x0028,
+ 0x080c, 0x493a, 0x00ce, 0x080c, 0x8078, 0x00fe, 0x0005, 0x6604,
+ 0xa6b6, 0x001e, 0x1110, 0x080c, 0x8078, 0x0005, 0x080c, 0x8940,
+ 0x1138, 0x6003, 0x0001, 0x6007, 0x0001, 0x080c, 0x67ee, 0x0010,
+ 0x080c, 0x8078, 0x0005, 0x6004, 0xa08a, 0x0080, 0x1a0c, 0x14f6,
+ 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005, 0xa182,
+ 0x0040, 0x0002, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c7, 0xa0c5,
+ 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5,
+ 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0xa0c5, 0x080c, 0x14f6, 0x00d6,
+ 0x00e6, 0x00f6, 0x0156, 0x0046, 0x0026, 0x6218, 0xa280, 0x002b,
+ 0x2004, 0xa005, 0x0120, 0x2021, 0x0000, 0x080c, 0xab96, 0x6106,
+ 0x2071, 0xb280, 0x7444, 0xa4a4, 0xff00, 0x0904, 0xa129, 0xa486,
+ 0x2000, 0x1130, 0x2009, 0x0001, 0x2011, 0x0200, 0x080c, 0x663f,
+ 0x080c, 0x15d9, 0x090c, 0x14f6, 0x6003, 0x0007, 0x2d00, 0x6837,
+ 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x6c5a, 0x2c00, 0x685e,
+ 0x6008, 0x68b2, 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x694a,
+ 0x0016, 0xa084, 0xff00, 0x6846, 0x684f, 0x0000, 0x6857, 0x0036,
+ 0x080c, 0x510c, 0x001e, 0xa486, 0x2000, 0x1130, 0x2019, 0x0017,
+ 0x080c, 0xa8eb, 0x0804, 0xa186, 0xa486, 0x0400, 0x1130, 0x2019,
+ 0x0002, 0x080c, 0xa89d, 0x0804, 0xa186, 0xa486, 0x0200, 0x1110,
+ 0x080c, 0xa882, 0xa486, 0x1000, 0x1110, 0x080c, 0xa8d0, 0x0804,
+ 0xa186, 0x2069, 0xb048, 0x6a00, 0xd284, 0x0904, 0xa1d5, 0xa284,
+ 0x0300, 0x1904, 0xa1cf, 0x6804, 0xa005, 0x0904, 0xa1c0, 0x2d78,
+ 0x6003, 0x0007, 0x080c, 0x15c0, 0x0904, 0xa18d, 0x7800, 0xd08c,
+ 0x1118, 0x7804, 0x8001, 0x7806, 0x6013, 0x0000, 0x6803, 0x0000,
+ 0x6837, 0x0116, 0x683b, 0x0000, 0x6008, 0x68b2, 0x2c00, 0x684a,
+ 0x6018, 0x2078, 0x78a0, 0x8007, 0x7130, 0x6986, 0x6846, 0x7928,
+ 0x698a, 0x792c, 0x698e, 0x7930, 0x6992, 0x7934, 0x6996, 0x6853,
+ 0x003d, 0x7244, 0xa294, 0x0003, 0xa286, 0x0002, 0x1118, 0x684f,
+ 0x0040, 0x0040, 0xa286, 0x0001, 0x1118, 0x684f, 0x0080, 0x0010,
+ 0x684f, 0x0000, 0x20a9, 0x000a, 0x2001, 0xb290, 0xad90, 0x0015,
+ 0x200c, 0x810f, 0x2112, 0x8000, 0x8210, 0x1f04, 0xa178, 0x200c,
+ 0x6982, 0x8000, 0x200c, 0x697e, 0x080c, 0x510c, 0x002e, 0x004e,
+ 0x015e, 0x00fe, 0x00ee, 0x00de, 0x0005, 0x6013, 0x0100, 0x6003,
+ 0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0c70,
+ 0x2069, 0xb292, 0x2d04, 0xa084, 0xff00, 0xa086, 0x1200, 0x11a8,
+ 0x2069, 0xb280, 0x686c, 0xa084, 0x00ff, 0x0016, 0x6110, 0xa18c,
+ 0x0700, 0xa10d, 0x6112, 0x001e, 0x6003, 0x0001, 0x6007, 0x0043,
+ 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0888, 0x6013, 0x0200, 0x6003,
+ 0x0001, 0x6007, 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0830,
+ 0x6013, 0x0300, 0x0010, 0x6013, 0x0100, 0x6003, 0x0001, 0x6007,
+ 0x0041, 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0804, 0xa186, 0x6013,
+ 0x0500, 0x0c98, 0x6013, 0x0600, 0x0818, 0x6013, 0x0200, 0x0800,
+ 0xa186, 0x0013, 0x1170, 0x6004, 0xa08a, 0x0040, 0x0a0c, 0x14f6,
+ 0xa08a, 0x0053, 0x1a0c, 0x14f6, 0xa082, 0x0040, 0x2008, 0x0804,
+ 0xa252, 0xa186, 0x0051, 0x0138, 0xa186, 0x0047, 0x11d8, 0x6004,
+ 0xa086, 0x0041, 0x0518, 0x2001, 0x0109, 0x2004, 0xd084, 0x01f0,
+ 0x0126, 0x2091, 0x2800, 0x0006, 0x0016, 0x0026, 0x080c, 0x6699,
+ 0x002e, 0x001e, 0x000e, 0x012e, 0x6000, 0xa086, 0x0002, 0x1170,
+ 0x0804, 0xa295, 0xa186, 0x0027, 0x0120, 0xa186, 0x0014, 0x190c,
+ 0x14f6, 0x6004, 0xa082, 0x0040, 0x2008, 0x001a, 0x080c, 0x80be,
+ 0x0005, 0xa22c, 0xa22e, 0xa22e, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+ 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0xa22c,
+ 0xa22c, 0xa22c, 0xa22c, 0xa22c, 0x080c, 0x14f6, 0x080c, 0x6b73,
+ 0x080c, 0x6c50, 0x0036, 0x00d6, 0x6010, 0xa06d, 0x01c0, 0xad84,
+ 0xf000, 0x01a8, 0x6003, 0x0002, 0x6018, 0x2004, 0xd0bc, 0x1178,
+ 0x2019, 0x0004, 0x080c, 0xa91f, 0x6013, 0x0000, 0x6014, 0xa005,
+ 0x1120, 0x2001, 0xafa4, 0x2004, 0x6016, 0x6003, 0x0007, 0x00de,
+ 0x003e, 0x0005, 0x0002, 0xa266, 0xa283, 0xa26f, 0xa28f, 0xa266,
+ 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266,
+ 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0xa266, 0x080c, 0x14f6,
+ 0x6010, 0xa088, 0x0013, 0x2104, 0xa085, 0x0400, 0x200a, 0x080c,
+ 0x6b73, 0x6010, 0xa080, 0x0013, 0x2004, 0xd0b4, 0x0138, 0x6003,
+ 0x0007, 0x2009, 0x0043, 0x080c, 0x80a7, 0x0010, 0x6003, 0x0002,
+ 0x080c, 0x6c50, 0x0005, 0x080c, 0x6b73, 0x080c, 0xab55, 0x1120,
+ 0x080c, 0x6618, 0x080c, 0x8078, 0x080c, 0x6c50, 0x0005, 0x080c,
+ 0x6b73, 0x2009, 0x0041, 0x0804, 0xa3de, 0xa182, 0x0040, 0x0002,
+ 0xa2ab, 0xa2ad, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ae,
+ 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab, 0xa2ab,
+ 0xa2ab, 0xa2b9, 0xa2ab, 0x080c, 0x14f6, 0x0005, 0x6003, 0x0004,
+ 0x6110, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10, 0x080c, 0x1824,
+ 0x0005, 0x00d6, 0x080c, 0x6618, 0x00de, 0x080c, 0xabb4, 0x080c,
+ 0x8078, 0x0005, 0xa182, 0x0040, 0x0002, 0xa2d8, 0xa2d8, 0xa2d8,
+ 0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa2da, 0xa2d8, 0xa2dd, 0xa316,
+ 0xa2d8, 0xa2d8, 0xa2d8, 0xa2d8, 0xa316, 0xa2d8, 0xa2d8, 0xa2d8,
+ 0x080c, 0x14f6, 0x080c, 0x80be, 0x0005, 0x2001, 0xad71, 0x2004,
+ 0xd0e4, 0x0158, 0x2001, 0x0100, 0x2004, 0xa082, 0x0005, 0x0228,
+ 0x2001, 0x011f, 0x2004, 0x6036, 0x0010, 0x6037, 0x0000, 0x080c,
+ 0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x684c, 0xd0fc,
+ 0x0150, 0xa08c, 0x0003, 0xa18e, 0x0002, 0x0168, 0x2009, 0x0041,
+ 0x00de, 0x0804, 0xa3de, 0x6003, 0x0007, 0x6017, 0x0000, 0x080c,
+ 0x6618, 0x00de, 0x0005, 0x080c, 0xab55, 0x0110, 0x00de, 0x0005,
+ 0x080c, 0x6618, 0x080c, 0x8078, 0x00de, 0x0ca0, 0x0036, 0x080c,
+ 0x6c05, 0x080c, 0x6d0d, 0x6010, 0x00d6, 0x2068, 0x6018, 0x2004,
+ 0xd0bc, 0x0188, 0x684c, 0xa084, 0x0003, 0xa086, 0x0002, 0x0140,
+ 0x687c, 0x632c, 0xa31a, 0x632e, 0x6880, 0x6328, 0xa31b, 0x632a,
+ 0x6003, 0x0002, 0x0080, 0x2019, 0x0004, 0x080c, 0xa91f, 0x6014,
+ 0xa005, 0x1128, 0x2001, 0xafa4, 0x2004, 0x8003, 0x6016, 0x6013,
+ 0x0000, 0x6003, 0x0007, 0x00de, 0x003e, 0x0005, 0xa186, 0x0013,
+ 0x1150, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x080c, 0x6b73,
+ 0x080c, 0x6c50, 0x0005, 0xa186, 0x0027, 0x0118, 0xa186, 0x0014,
+ 0x1180, 0x6004, 0xa086, 0x0042, 0x190c, 0x14f6, 0x2001, 0x0007,
+ 0x080c, 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50,
+ 0x0005, 0xa182, 0x0040, 0x0002, 0xa37f, 0xa37f, 0xa37f, 0xa37f,
+ 0xa37f, 0xa37f, 0xa37f, 0xa381, 0xa38d, 0xa37f, 0xa37f, 0xa37f,
+ 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0xa37f, 0x080c,
+ 0x14f6, 0x0036, 0x0046, 0x20e1, 0x0005, 0x3d18, 0x3e20, 0x2c10,
+ 0x080c, 0x1824, 0x004e, 0x003e, 0x0005, 0x6010, 0x00d6, 0x2068,
+ 0x6810, 0x6a14, 0x0006, 0x0046, 0x0056, 0x6c7c, 0xa422, 0x6d80,
+ 0x2200, 0xa52b, 0x602c, 0xa420, 0x642e, 0x6028, 0xa529, 0x652a,
+ 0x005e, 0x004e, 0x000e, 0xa20d, 0x1178, 0x684c, 0xd0fc, 0x0120,
+ 0x2009, 0x0041, 0x00de, 0x0490, 0x6003, 0x0007, 0x6017, 0x0000,
+ 0x080c, 0x6618, 0x00de, 0x0005, 0x0006, 0x00f6, 0x2c78, 0x080c,
+ 0x5029, 0x00fe, 0x000e, 0x0120, 0x6003, 0x0002, 0x00de, 0x0005,
+ 0x2009, 0xad0d, 0x210c, 0xd19c, 0x0118, 0x6003, 0x0007, 0x0010,
+ 0x6003, 0x0006, 0x0021, 0x080c, 0x661a, 0x00de, 0x0005, 0xd2fc,
+ 0x0140, 0x8002, 0x8000, 0x8212, 0xa291, 0x0000, 0x2009, 0x0009,
+ 0x0010, 0x2009, 0x0015, 0x6a6a, 0x6866, 0x0005, 0xa182, 0x0040,
+ 0x0208, 0x0062, 0xa186, 0x0013, 0x0120, 0xa186, 0x0014, 0x190c,
+ 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005, 0xa401, 0xa408,
+ 0xa414, 0xa420, 0xa401, 0xa401, 0xa401, 0xa42f, 0xa401, 0xa403,
+ 0xa403, 0xa401, 0xa401, 0xa401, 0xa401, 0xa403, 0xa401, 0xa403,
+ 0xa401, 0x080c, 0x14f6, 0x6020, 0xd0dc, 0x090c, 0x14f6, 0x0005,
+ 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000,
+ 0x080c, 0x6c50, 0x012e, 0x0005, 0x6003, 0x0001, 0x6106, 0x080c,
+ 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e, 0x0005,
+ 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x0126, 0x2091,
+ 0x8000, 0x080c, 0x680b, 0x080c, 0x6d0d, 0x012e, 0x0005, 0xa016,
+ 0x080c, 0x1824, 0x0005, 0x0126, 0x2091, 0x8000, 0x0036, 0x00d6,
+ 0xa182, 0x0040, 0x0023, 0x00de, 0x003e, 0x012e, 0x0005, 0xa44f,
+ 0xa451, 0xa463, 0xa47e, 0xa44f, 0xa44f, 0xa44f, 0xa493, 0xa44f,
+ 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0xa44f, 0x080c,
+ 0x14f6, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x01f8, 0xa09c, 0x0003,
+ 0xa39e, 0x0003, 0x01d0, 0x6003, 0x0001, 0x6106, 0x080c, 0x67a8,
+ 0x080c, 0x6c50, 0x0498, 0x6010, 0x2068, 0x684c, 0xd0fc, 0x0168,
+ 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0140, 0x6003, 0x0001, 0x6106,
+ 0x080c, 0x67a8, 0x080c, 0x6c50, 0x0408, 0x6013, 0x0000, 0x6017,
+ 0x0000, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00c0, 0x6010, 0x2068,
+ 0x684c, 0xd0fc, 0x0d90, 0xa09c, 0x0003, 0xa39e, 0x0003, 0x0d68,
+ 0x6003, 0x0003, 0x6106, 0x2c10, 0x080c, 0x1e6e, 0x080c, 0x680b,
+ 0x080c, 0x6d0d, 0x0018, 0xa016, 0x080c, 0x1824, 0x0005, 0x080c,
+ 0x6b73, 0x6110, 0x81ff, 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa,
+ 0x0036, 0x2019, 0x0029, 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c,
+ 0x974e, 0x080c, 0x6c50, 0x0005, 0x080c, 0x6c05, 0x6110, 0x81ff,
+ 0x0158, 0x00d6, 0x2168, 0x080c, 0xabfa, 0x0036, 0x2019, 0x0029,
+ 0x080c, 0xa91f, 0x003e, 0x00de, 0x080c, 0x974e, 0x080c, 0x6d0d,
+ 0x0005, 0xa182, 0x0085, 0x0002, 0xa4cd, 0xa4cb, 0xa4cb, 0xa4d9,
+ 0xa4cb, 0xa4cb, 0xa4cb, 0x080c, 0x14f6, 0x6003, 0x000b, 0x6106,
+ 0x080c, 0x67a8, 0x0126, 0x2091, 0x8000, 0x080c, 0x6c50, 0x012e,
+ 0x0005, 0x0026, 0x00e6, 0x080c, 0xab4e, 0x0118, 0x080c, 0x8078,
+ 0x00c8, 0x2071, 0xb280, 0x7224, 0x6212, 0x7220, 0x080c, 0xa7ce,
+ 0x0118, 0x6007, 0x0086, 0x0040, 0x6007, 0x0087, 0x7224, 0xa296,
+ 0xffff, 0x1110, 0x6007, 0x0086, 0x6003, 0x0001, 0x080c, 0x67a8,
+ 0x080c, 0x6c50, 0x00ee, 0x002e, 0x0005, 0xa186, 0x0013, 0x1160,
+ 0x6004, 0xa08a, 0x0085, 0x0a0c, 0x14f6, 0xa08a, 0x008c, 0x1a0c,
+ 0x14f6, 0xa082, 0x0085, 0x00a2, 0xa186, 0x0027, 0x0130, 0xa186,
+ 0x0014, 0x0118, 0x080c, 0x80be, 0x0050, 0x2001, 0x0007, 0x080c,
+ 0x4c5d, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+ 0xa527, 0xa529, 0xa529, 0xa527, 0xa527, 0xa527, 0xa527, 0x080c,
+ 0x14f6, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+ 0xa182, 0x0085, 0x0a0c, 0x14f6, 0xa182, 0x008c, 0x1a0c, 0x14f6,
+ 0xa182, 0x0085, 0x0002, 0xa542, 0xa542, 0xa542, 0xa544, 0xa542,
+ 0xa542, 0xa542, 0x080c, 0x14f6, 0x0005, 0xa186, 0x0013, 0x0148,
+ 0xa186, 0x0014, 0x0130, 0xa186, 0x0027, 0x0118, 0x080c, 0x80be,
+ 0x0030, 0x080c, 0x6b73, 0x080c, 0x974e, 0x080c, 0x6c50, 0x0005,
+ 0x0036, 0x080c, 0xabb4, 0x603f, 0x0000, 0x2019, 0x000b, 0x0031,
+ 0x601f, 0x0006, 0x6003, 0x0007, 0x003e, 0x0005, 0x0126, 0x0036,
+ 0x2091, 0x8000, 0x0086, 0x2c40, 0x0096, 0x2049, 0x0000, 0x080c,
+ 0x7b9a, 0x009e, 0x008e, 0x1578, 0x0076, 0x2c38, 0x080c, 0x7c34,
+ 0x007e, 0x1548, 0x6000, 0xa086, 0x0000, 0x0528, 0x601c, 0xa086,
+ 0x0007, 0x0508, 0x00d6, 0x6000, 0xa086, 0x0004, 0x1150, 0x080c,
+ 0xabb4, 0x601f, 0x0007, 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c,
+ 0x190b, 0x6010, 0x2068, 0x080c, 0x9596, 0x0110, 0x080c, 0xa91f,
+ 0x00de, 0x6013, 0x0000, 0x080c, 0xabb4, 0x601f, 0x0007, 0x2001,
+ 0xafa3, 0x2004, 0x6016, 0x003e, 0x012e, 0x0005, 0x00f6, 0x00c6,
+ 0x0036, 0x0156, 0x2079, 0xb280, 0x7938, 0x783c, 0x080c, 0x2676,
+ 0x1904, 0xa5f1, 0x0016, 0x00c6, 0x080c, 0x4cdc, 0x15c0, 0x2011,
+ 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1578,
+ 0x001e, 0x002e, 0x0026, 0x0016, 0x2019, 0x0029, 0x080c, 0x7cf4,
+ 0x080c, 0x68e7, 0x0076, 0x2039, 0x0000, 0x080c, 0x681d, 0x007e,
+ 0x001e, 0x0076, 0x2039, 0x0000, 0x080c, 0xa712, 0x007e, 0x080c,
+ 0x4ecf, 0x0026, 0x6204, 0xa294, 0xff00, 0x8217, 0xa286, 0x0006,
+ 0x0118, 0xa286, 0x0004, 0x1118, 0x62a0, 0x080c, 0x2b87, 0x002e,
+ 0x001e, 0x080c, 0x493a, 0x6612, 0x6516, 0xa006, 0x0010, 0x00ce,
+ 0x001e, 0x015e, 0x003e, 0x00ce, 0x00fe, 0x0005, 0x00c6, 0x00d6,
+ 0x00e6, 0x0016, 0x2009, 0xad20, 0x2104, 0xa086, 0x0074, 0x1904,
+ 0xa64b, 0x2069, 0xb28e, 0x690c, 0xa182, 0x0100, 0x06c0, 0x6908,
+ 0xa184, 0x8000, 0x05e8, 0x2001, 0xaf9d, 0x2004, 0xa005, 0x1160,
+ 0x6018, 0x2070, 0x7010, 0xa084, 0x00ff, 0x0118, 0x7000, 0xd0f4,
+ 0x0118, 0xa184, 0x0800, 0x0560, 0x6910, 0xa18a, 0x0001, 0x0610,
+ 0x6914, 0x2069, 0xb2ae, 0x6904, 0x81ff, 0x1198, 0x690c, 0xa182,
+ 0x0100, 0x02a8, 0x6908, 0x81ff, 0x1178, 0x6910, 0xa18a, 0x0001,
+ 0x0288, 0x6918, 0xa18a, 0x0001, 0x0298, 0x00d0, 0x6013, 0x0100,
+ 0x00a0, 0x6013, 0x0300, 0x0088, 0x6013, 0x0500, 0x0070, 0x6013,
+ 0x0700, 0x0058, 0x6013, 0x0900, 0x0040, 0x6013, 0x0b00, 0x0028,
+ 0x6013, 0x0f00, 0x0010, 0x6013, 0x2d00, 0xa085, 0x0001, 0x0008,
+ 0xa006, 0x001e, 0x00ee, 0x00de, 0x00ce, 0x0005, 0x00c6, 0x00d6,
+ 0x0026, 0x0036, 0x0156, 0x6218, 0x2268, 0x6b04, 0xa394, 0x00ff,
+ 0xa286, 0x0006, 0x0190, 0xa286, 0x0004, 0x0178, 0xa394, 0xff00,
+ 0x8217, 0xa286, 0x0006, 0x0148, 0xa286, 0x0004, 0x0130, 0x00c6,
+ 0x2d60, 0x080c, 0x4ceb, 0x00ce, 0x04c0, 0x2011, 0xb296, 0xad98,
+ 0x000a, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1580, 0x2011, 0xb29a,
+ 0xad98, 0x0006, 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1538, 0x0046,
+ 0x0016, 0x6aa0, 0xa294, 0x00ff, 0x8227, 0xa006, 0x2009, 0xad52,
+ 0x210c, 0xd1a4, 0x0138, 0x2009, 0x0029, 0x080c, 0xa96c, 0x6800,
+ 0xc0e5, 0x6802, 0x2019, 0x0029, 0x080c, 0x68e7, 0x0076, 0x2039,
+ 0x0000, 0x080c, 0x681d, 0x2c08, 0x080c, 0xa712, 0x007e, 0x2001,
+ 0x0007, 0x080c, 0x4c5d, 0x001e, 0x004e, 0xa006, 0x015e, 0x003e,
+ 0x002e, 0x00de, 0x00ce, 0x0005, 0x00d6, 0x2069, 0xb28e, 0x6800,
+ 0xa086, 0x0800, 0x0118, 0x6013, 0x0000, 0x0008, 0xa006, 0x00de,
+ 0x0005, 0x00c6, 0x00f6, 0x0016, 0x0026, 0x0036, 0x0156, 0x2079,
+ 0xb28c, 0x7930, 0x7834, 0x080c, 0x2676, 0x11a0, 0x080c, 0x4cdc,
+ 0x1188, 0x2011, 0xb290, 0xac98, 0x000a, 0x20a9, 0x0004, 0x080c,
+ 0x8a7c, 0x1140, 0x2011, 0xb294, 0xac98, 0x0006, 0x20a9, 0x0004,
+ 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x00fe, 0x00ce,
+ 0x0005, 0x00c6, 0x0006, 0x0016, 0x0026, 0x0036, 0x0156, 0x2011,
+ 0xb283, 0x2204, 0x8211, 0x220c, 0x080c, 0x2676, 0x11a0, 0x080c,
+ 0x4cdc, 0x1188, 0x2011, 0xb296, 0xac98, 0x000a, 0x20a9, 0x0004,
+ 0x080c, 0x8a7c, 0x1140, 0x2011, 0xb29a, 0xac98, 0x0006, 0x20a9,
+ 0x0004, 0x080c, 0x8a7c, 0x015e, 0x003e, 0x002e, 0x001e, 0x000e,
+ 0x00ce, 0x0005, 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0056,
+ 0x0046, 0x0026, 0x0126, 0x2091, 0x8000, 0x2740, 0x2029, 0xafd0,
+ 0x252c, 0x2021, 0xafd6, 0x2424, 0x2061, 0xb400, 0x2071, 0xad00,
+ 0x7644, 0x7064, 0x81ff, 0x0128, 0x8001, 0xa602, 0x1a04, 0xa78e,
+ 0x0018, 0xa606, 0x0904, 0xa78e, 0x2100, 0xac06, 0x0904, 0xa785,
+ 0x080c, 0xa990, 0x0904, 0xa785, 0x671c, 0xa786, 0x0001, 0x0904,
+ 0xa7a5, 0xa786, 0x0004, 0x0904, 0xa7a5, 0xa786, 0x0007, 0x05e8,
+ 0x2500, 0xac06, 0x05d0, 0x2400, 0xac06, 0x05b8, 0x080c, 0xa9a0,
+ 0x15a0, 0x88ff, 0x0118, 0x6050, 0xa906, 0x1578, 0x00d6, 0x6000,
+ 0xa086, 0x0004, 0x1120, 0x0016, 0x080c, 0x190b, 0x001e, 0xa786,
+ 0x0008, 0x1148, 0x080c, 0x9789, 0x1130, 0x080c, 0x85f3, 0x00de,
+ 0x080c, 0x974e, 0x00d0, 0x6010, 0x2068, 0x080c, 0x9596, 0x0190,
+ 0xa786, 0x0003, 0x1528, 0x6837, 0x0103, 0x6b4a, 0x6847, 0x0000,
+ 0x080c, 0xabfa, 0x0016, 0x080c, 0x97fd, 0x080c, 0x510c, 0x001e,
+ 0x080c, 0x9742, 0x00de, 0x080c, 0x974e, 0xace0, 0x0018, 0x2001,
+ 0xad16, 0x2004, 0xac02, 0x1210, 0x0804, 0xa726, 0x012e, 0x002e,
+ 0x004e, 0x005e, 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x0005,
+ 0xa786, 0x0006, 0x19c0, 0xa386, 0x0005, 0x0128, 0x080c, 0xabfa,
+ 0x080c, 0xa91f, 0x08f8, 0x00de, 0x0c00, 0x080c, 0xa9a0, 0x19e8,
+ 0x81ff, 0x09d8, 0xa180, 0x0001, 0x2004, 0xa086, 0x0018, 0x0130,
+ 0xa180, 0x0001, 0x2004, 0xa086, 0x002d, 0x1978, 0x6000, 0xa086,
+ 0x0002, 0x1958, 0x080c, 0x9778, 0x0130, 0x080c, 0x9789, 0x1928,
+ 0x080c, 0x85f3, 0x0038, 0x080c, 0x2aff, 0x080c, 0x9789, 0x1110,
+ 0x080c, 0x85f3, 0x080c, 0x974e, 0x0804, 0xa785, 0x00c6, 0x00e6,
+ 0x0016, 0x2c08, 0x2170, 0x080c, 0xa940, 0x001e, 0x0120, 0x601c,
+ 0xa084, 0x000f, 0x001b, 0x00ee, 0x00ce, 0x0005, 0xa7e6, 0xa7e6,
+ 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e6, 0xa7e8, 0xa7e6, 0xa006, 0x0005,
+ 0x0046, 0x0016, 0x7018, 0xa080, 0x0028, 0x2024, 0xa4a4, 0x00ff,
+ 0x8427, 0x2c00, 0x2009, 0x0020, 0x080c, 0xa96c, 0x001e, 0x004e,
+ 0x0036, 0x2019, 0x0002, 0x080c, 0xa566, 0x003e, 0xa085, 0x0001,
+ 0x0005, 0x2001, 0x0001, 0x080c, 0x4c1e, 0x0156, 0x0016, 0x0026,
+ 0x0036, 0x20a9, 0x0004, 0x2019, 0xad05, 0x2011, 0xb296, 0x080c,
+ 0x8a7c, 0x003e, 0x002e, 0x001e, 0x015e, 0xa005, 0x0005, 0x00f6,
+ 0x00e6, 0x00c6, 0x0086, 0x0076, 0x0066, 0x0026, 0x0126, 0x2091,
+ 0x8000, 0x2740, 0x2061, 0xb400, 0x2079, 0x0001, 0x8fff, 0x0904,
+ 0xa875, 0x2071, 0xad00, 0x7644, 0x7064, 0x8001, 0xa602, 0x1a04,
+ 0xa875, 0x88ff, 0x0128, 0x2800, 0xac06, 0x15b0, 0x2079, 0x0000,
+ 0x080c, 0xa990, 0x0588, 0x2400, 0xac06, 0x0570, 0x671c, 0xa786,
+ 0x0006, 0x1550, 0xa786, 0x0007, 0x0538, 0x88ff, 0x1140, 0x6018,
+ 0xa206, 0x1510, 0x85ff, 0x0118, 0x6050, 0xa106, 0x11e8, 0x00d6,
+ 0x6000, 0xa086, 0x0004, 0x1150, 0x080c, 0xabb4, 0x601f, 0x0007,
+ 0x2001, 0xafa3, 0x2004, 0x6016, 0x080c, 0x190b, 0x6010, 0x2068,
+ 0x080c, 0x9596, 0x0120, 0x0046, 0x080c, 0xa91f, 0x004e, 0x00de,
+ 0x080c, 0x974e, 0x88ff, 0x1198, 0xace0, 0x0018, 0x2001, 0xad16,
+ 0x2004, 0xac02, 0x1210, 0x0804, 0xa826, 0xa006, 0x012e, 0x002e,
+ 0x006e, 0x007e, 0x008e, 0x00ce, 0x00ee, 0x00fe, 0x0005, 0xa8c5,
+ 0x0001, 0x0ca0, 0x0076, 0x0056, 0x0086, 0x2041, 0x0000, 0x2029,
+ 0x0001, 0x2c20, 0x2019, 0x0002, 0x6218, 0x0096, 0x2049, 0x0000,
+ 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34,
+ 0x080c, 0xa817, 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056,
+ 0x0076, 0x00c6, 0x0156, 0x2c20, 0x2128, 0x20a9, 0x007f, 0x2009,
+ 0x0000, 0x0016, 0x0036, 0x080c, 0x4cdc, 0x11b0, 0x2c10, 0x0056,
+ 0x0086, 0x2041, 0x0000, 0x2508, 0x2029, 0x0001, 0x0096, 0x2049,
+ 0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+ 0x7c34, 0x080c, 0xa817, 0x005e, 0x003e, 0x001e, 0x8108, 0x1f04,
+ 0xa8a9, 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005,
+ 0x0076, 0x0056, 0x6218, 0x0086, 0x2041, 0x0000, 0x2029, 0x0001,
+ 0x2019, 0x0048, 0x0096, 0x2049, 0x0000, 0x080c, 0x7b9a, 0x009e,
+ 0x008e, 0x2039, 0x0000, 0x080c, 0x7c34, 0x2c20, 0x080c, 0xa817,
+ 0x005e, 0x007e, 0x0005, 0x0026, 0x0046, 0x0056, 0x0076, 0x00c6,
+ 0x0156, 0x2c20, 0x20a9, 0x007f, 0x2009, 0x0000, 0x0016, 0x0036,
+ 0x080c, 0x4cdc, 0x11c0, 0x2c10, 0x0086, 0x2041, 0x0000, 0x2828,
+ 0x0046, 0x2021, 0x0001, 0x080c, 0xab96, 0x004e, 0x0096, 0x2049,
+ 0x0000, 0x080c, 0x7b9a, 0x009e, 0x008e, 0x2039, 0x0000, 0x080c,
+ 0x7c34, 0x080c, 0xa817, 0x003e, 0x001e, 0x8108, 0x1f04, 0xa8f6,
+ 0x015e, 0x00ce, 0x007e, 0x005e, 0x004e, 0x002e, 0x0005, 0x0016,
+ 0x00f6, 0x3800, 0xd08c, 0x0130, 0xad82, 0x1000, 0x02b0, 0xad82,
+ 0xad00, 0x0230, 0xad82, 0xe400, 0x0280, 0xad82, 0xffff, 0x1268,
+ 0x6800, 0xa07d, 0x0138, 0x6803, 0x0000, 0x6b52, 0x080c, 0x510c,
+ 0x2f68, 0x0cb0, 0x6b52, 0x080c, 0x510c, 0x00fe, 0x001e, 0x0005,
+ 0x00e6, 0x0046, 0x0036, 0x2061, 0xb400, 0x2071, 0xad00, 0x7444,
+ 0x7064, 0x8001, 0xa402, 0x12d8, 0x2100, 0xac06, 0x0168, 0x6000,
+ 0xa086, 0x0000, 0x0148, 0x6008, 0xa206, 0x1130, 0x6018, 0xa1a0,
+ 0x0006, 0x2424, 0xa406, 0x0140, 0xace0, 0x0018, 0x2001, 0xad16,
+ 0x2004, 0xac02, 0x1220, 0x0c08, 0xa085, 0x0001, 0x0008, 0xa006,
+ 0x003e, 0x004e, 0x00ee, 0x0005, 0x00d6, 0x0006, 0x080c, 0x15d9,
+ 0x000e, 0x090c, 0x14f6, 0x6837, 0x010d, 0x685e, 0x0026, 0x2010,
+ 0x080c, 0x9586, 0x2001, 0x0000, 0x0120, 0x2200, 0xa080, 0x0014,
+ 0x2004, 0x002e, 0x684a, 0x6956, 0x6c46, 0x684f, 0x0000, 0xa006,
+ 0x68b2, 0x6802, 0x683a, 0x685a, 0x080c, 0x510c, 0x00de, 0x0005,
+ 0x6700, 0xa786, 0x0000, 0x0158, 0xa786, 0x0001, 0x0140, 0xa786,
+ 0x000a, 0x0128, 0xa786, 0x0009, 0x0110, 0xa085, 0x0001, 0x0005,
+ 0x00e6, 0x6018, 0x2070, 0x70a0, 0xa206, 0x00ee, 0x0005, 0x0016,
+ 0x6004, 0xa08e, 0x001e, 0x11a0, 0x8007, 0x6130, 0xa18c, 0x00ff,
+ 0xa105, 0x6032, 0x6007, 0x0085, 0x6003, 0x000b, 0x601f, 0x0005,
+ 0x2001, 0xafa4, 0x2004, 0x6016, 0x080c, 0x67a8, 0x080c, 0x6c50,
+ 0x001e, 0x0005, 0xe000, 0xe000, 0x0005, 0x6020, 0xd0e4, 0x0158,
+ 0xd0cc, 0x0118, 0x080c, 0x9866, 0x0030, 0x080c, 0xabb4, 0x080c,
+ 0x6618, 0x080c, 0x8078, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084,
+ 0x000f, 0x0002, 0xa9e3, 0xa9e3, 0xa9e3, 0xa9e8, 0xa9e3, 0xa9e5,
+ 0xa9e5, 0xa9e3, 0xa9e5, 0xa006, 0x0005, 0x00c6, 0x2260, 0x00ce,
+ 0xa085, 0x0001, 0x0005, 0xa280, 0x0007, 0x2004, 0xa084, 0x000f,
+ 0x0002, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xa9fa, 0xaa05,
+ 0xa9fa, 0xa9fa, 0x6007, 0x003b, 0x602b, 0x0009, 0x6013, 0x2a00,
+ 0x6003, 0x0001, 0x080c, 0x67a8, 0x0005, 0x00c6, 0x2260, 0x080c,
+ 0xabb4, 0x603f, 0x0000, 0x6020, 0xc0f4, 0xc0cc, 0x6022, 0x6037,
+ 0x0000, 0x00ce, 0x00d6, 0x2268, 0xa186, 0x0007, 0x1904, 0xaa60,
+ 0x6810, 0xa005, 0x0138, 0xa080, 0x0013, 0x2004, 0xd0fc, 0x1110,
+ 0x00de, 0x08c0, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c, 0x67a8,
+ 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002, 0x1904,
+ 0xaae7, 0x6010, 0xa005, 0x1138, 0x6000, 0xa086, 0x0007, 0x190c,
+ 0x14f6, 0x0804, 0xaae7, 0xa08c, 0xf000, 0x1130, 0x0028, 0x2068,
+ 0x6800, 0xa005, 0x1de0, 0x2d00, 0xa080, 0x0013, 0x2004, 0xa084,
+ 0x0003, 0xa086, 0x0002, 0x1180, 0x6010, 0x2068, 0x684c, 0xc0dc,
+ 0xc0f4, 0x684e, 0x6850, 0xc0f4, 0xc0fc, 0x6852, 0x2009, 0x0043,
+ 0x080c, 0xa3de, 0x0804, 0xaae7, 0x2009, 0x0041, 0x0804, 0xaae1,
+ 0xa186, 0x0005, 0x15f0, 0x6810, 0xa080, 0x0013, 0x2004, 0xd0bc,
+ 0x1118, 0x00de, 0x0804, 0xa9fa, 0xd0b4, 0x0128, 0xd0fc, 0x090c,
+ 0x14f6, 0x0804, 0xaa18, 0x6007, 0x003a, 0x6003, 0x0001, 0x080c,
+ 0x67a8, 0x080c, 0x6c50, 0x00c6, 0x2d60, 0x6100, 0xa186, 0x0002,
+ 0x0120, 0xa186, 0x0004, 0x1904, 0xaae7, 0x2071, 0xaffd, 0x7000,
+ 0xa086, 0x0003, 0x1128, 0x7004, 0xac06, 0x1110, 0x7003, 0x0000,
+ 0x6810, 0xa080, 0x0013, 0x200c, 0xc1f4, 0xc1dc, 0x2102, 0x8000,
+ 0x200c, 0xc1f4, 0xc1fc, 0xc1bc, 0x2102, 0x2009, 0x0042, 0x0804,
+ 0xaae1, 0x0036, 0x00d6, 0x00d6, 0x080c, 0x15d9, 0x003e, 0x090c,
+ 0x14f6, 0x6837, 0x010d, 0x6803, 0x0000, 0x683b, 0x0000, 0x685b,
+ 0x0000, 0x6b5e, 0x6857, 0x0045, 0x2c00, 0x6862, 0x6034, 0x6872,
+ 0x2360, 0x6020, 0xc0dd, 0x6022, 0x6018, 0xa080, 0x0028, 0x2004,
+ 0xa084, 0x00ff, 0x8007, 0x6350, 0x6b4a, 0x6846, 0x684f, 0x0000,
+ 0x6d6a, 0x6e66, 0x686f, 0x0001, 0x080c, 0x510c, 0x2019, 0x0045,
+ 0x6008, 0x2068, 0x080c, 0xa566, 0x2d00, 0x600a, 0x601f, 0x0006,
+ 0x6003, 0x0007, 0x6017, 0x0000, 0x603f, 0x0000, 0x00de, 0x003e,
+ 0x0038, 0x603f, 0x0000, 0x6003, 0x0007, 0x080c, 0xa3de, 0x00ce,
+ 0x00de, 0x0005, 0xa186, 0x0013, 0x1128, 0x6004, 0xa082, 0x0085,
+ 0x2008, 0x00c2, 0xa186, 0x0027, 0x1178, 0x080c, 0x6b73, 0x0036,
+ 0x00d6, 0x6010, 0x2068, 0x2019, 0x0004, 0x080c, 0xa91f, 0x00de,
+ 0x003e, 0x080c, 0x6c50, 0x0005, 0xa186, 0x0014, 0x0d70, 0x080c,
+ 0x80be, 0x0005, 0xab13, 0xab11, 0xab11, 0xab11, 0xab11, 0xab11,
+ 0xab13, 0x080c, 0x14f6, 0x080c, 0x6b73, 0x6003, 0x000c, 0x080c,
+ 0x6c50, 0x0005, 0xa182, 0x008c, 0x1220, 0xa182, 0x0085, 0x0208,
+ 0x001a, 0x080c, 0x80be, 0x0005, 0xab2b, 0xab2b, 0xab2b, 0xab2b,
+ 0xab2d, 0xab4b, 0xab2b, 0x080c, 0x14f6, 0x00d6, 0x2c68, 0x080c,
+ 0x8022, 0x01a0, 0x6003, 0x0001, 0x6007, 0x001e, 0x2009, 0xb28e,
+ 0x210c, 0x6136, 0x2009, 0xb28f, 0x210c, 0x613a, 0x600b, 0xffff,
+ 0x6918, 0x611a, 0x601f, 0x0004, 0x080c, 0x67a8, 0x2d60, 0x080c,
+ 0x8078, 0x00de, 0x0005, 0x080c, 0x8078, 0x0005, 0x00e6, 0x6018,
+ 0x2070, 0x7000, 0xd0ec, 0x00ee, 0x0005, 0x6010, 0xa080, 0x0013,
+ 0x200c, 0xd1ec, 0x05d0, 0x2001, 0xad71, 0x2004, 0xd0ec, 0x05a8,
+ 0x6003, 0x0002, 0x6020, 0xc0e5, 0x6022, 0xd1ac, 0x0180, 0x00f6,
+ 0x2c78, 0x080c, 0x5025, 0x00fe, 0x0150, 0x2001, 0xafa5, 0x2004,
+ 0x603e, 0x2009, 0xad71, 0x210c, 0xd1f4, 0x11e8, 0x0080, 0x2009,
+ 0xad71, 0x210c, 0xd1f4, 0x0128, 0x6020, 0xc0e4, 0x6022, 0xa006,
+ 0x00a0, 0x2001, 0xafa5, 0x200c, 0x8103, 0xa100, 0x603e, 0x6018,
+ 0xa088, 0x002b, 0x2104, 0xa005, 0x0118, 0xa088, 0x0003, 0x0cd0,
+ 0x2c0a, 0x600f, 0x0000, 0xa085, 0x0001, 0x0005, 0x0016, 0x00c6,
+ 0x00e6, 0x6150, 0xa2f0, 0x002b, 0x2e04, 0x2060, 0x8cff, 0x0180,
+ 0x84ff, 0x1118, 0x6050, 0xa106, 0x1138, 0x600c, 0x2072, 0x080c,
+ 0x6618, 0x080c, 0x8078, 0x0010, 0xacf0, 0x0003, 0x2e64, 0x0c70,
+ 0x00ee, 0x00ce, 0x001e, 0x0005, 0x00d6, 0x6018, 0xa0e8, 0x002b,
+ 0x2d04, 0xa005, 0x0140, 0xac06, 0x0120, 0x2d04, 0xa0e8, 0x0003,
+ 0x0cb8, 0x600c, 0x206a, 0x00de, 0x0005, 0x0026, 0x0036, 0x0156,
+ 0x2011, 0xad27, 0x2204, 0xa084, 0x00ff, 0x2019, 0xb28e, 0x2334,
+ 0xa636, 0x11d8, 0x8318, 0x2334, 0x2204, 0xa084, 0xff00, 0xa636,
+ 0x11a0, 0x2011, 0xb290, 0x6018, 0xa098, 0x000a, 0x20a9, 0x0004,
+ 0x080c, 0x8a7c, 0x1150, 0x2011, 0xb294, 0x6018, 0xa098, 0x0006,
+ 0x20a9, 0x0004, 0x080c, 0x8a7c, 0x1100, 0x015e, 0x003e, 0x002e,
+ 0x0005, 0x00e6, 0x2071, 0xad00, 0x080c, 0x48f5, 0x080c, 0x28fa,
+ 0x00ee, 0x0005, 0x00e6, 0x6018, 0x2070, 0x7000, 0xd0fc, 0x0108,
+ 0x0011, 0x00ee, 0x0005, 0x6850, 0xc0e5, 0x6852, 0x0005, 0x00e6,
+ 0x00c6, 0x0076, 0x0066, 0x0056, 0x0046, 0x0026, 0x0016, 0x0126,
+ 0x2091, 0x8000, 0x2029, 0xafd0, 0x252c, 0x2021, 0xafd6, 0x2424,
+ 0x2061, 0xb400, 0x2071, 0xad00, 0x7644, 0x7064, 0xa606, 0x0578,
+ 0x671c, 0xa786, 0x0001, 0x0118, 0xa786, 0x0008, 0x1500, 0x2500,
+ 0xac06, 0x01e8, 0x2400, 0xac06, 0x01d0, 0x080c, 0xa990, 0x01b8,
+ 0x080c, 0xa9a0, 0x11a0, 0x6000, 0xa086, 0x0004, 0x1120, 0x0016,
+ 0x080c, 0x190b, 0x001e, 0x080c, 0x9778, 0x1110, 0x080c, 0x2aff,
+ 0x080c, 0x9789, 0x1110, 0x080c, 0x85f3, 0x080c, 0x974e, 0xace0,
+ 0x0018, 0x2001, 0xad16, 0x2004, 0xac02, 0x1208, 0x0858, 0x012e,
+ 0x001e, 0x002e, 0x004e, 0x005e, 0x006e, 0x007e, 0x00ce, 0x00ee,
+ 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000, 0x2071, 0xad40,
+ 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4, 0x0118, 0x7030,
+ 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a, 0x0451, 0x00ee,
+ 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6, 0x2091, 0x8000,
+ 0x2071, 0xad40, 0xd5a4, 0x0118, 0x7034, 0x8000, 0x7036, 0xd5b4,
+ 0x0118, 0x7030, 0x8000, 0x7032, 0xd5ac, 0x0118, 0x2071, 0xad4a,
+ 0x0081, 0x00ee, 0x000e, 0x012e, 0x0005, 0x0126, 0x0006, 0x00e6,
+ 0x2091, 0x8000, 0x2071, 0xad42, 0x0021, 0x00ee, 0x000e, 0x012e,
+ 0x0005, 0x2e04, 0x8000, 0x2072, 0x1220, 0x8e70, 0x2e04, 0x8000,
+ 0x2072, 0x0005, 0x00e6, 0x2071, 0xad40, 0x0c99, 0x00ee, 0x0005,
+ 0x00e6, 0x2071, 0xad44, 0x0c69, 0x00ee, 0x0005, 0x0001, 0x0002,
+ 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,
+ 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000, 0x8529
+};
+
cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ?
((rscsi_disks[i].device->lun << 5) & 0xe0) : 0;
cmd[2] = 0x3f; /* Get all pages */
- cmd[4] = 8; /* But we only want the 8 byte header */
+ cmd[4] = 255; /* But we only want the 8 byte header */
SRpnt->sr_cmd_len = 0;
SRpnt->sr_sense_buffer[0] = 0;
SRpnt->sr_sense_buffer[2] = 0;
#define FAST
#endif
-#undef LINKED /* Linked commands are currently broken! */
+#undef LINKED /* Linked commands are currently broken! */
#if defined(OVERRIDE) && !defined(CONTROLLER)
#error Please use -DCONTROLLER=SEAGATE or -DCONTROLLER=FD to override controller type
STATUS
*/
#ifdef SWAPSTAT
- #define STAT_MSG 0x08
- #define STAT_CD 0x02
+#define STAT_MSG 0x08
+#define STAT_CD 0x02
#else
- #define STAT_MSG 0x02
- #define STAT_CD 0x08
+#define STAT_MSG 0x02
+#define STAT_CD 0x08
#endif
#define STAT_BSY 0x01
extern volatile int seagate_st0x_timeout;
#ifdef PARITY
- #define BASE_CMD CMD_EN_PARITY
+#define BASE_CMD CMD_EN_PARITY
#else
- #define BASE_CMD 0
+#define BASE_CMD 0
#endif
/*
#define PHASE_BUS_FREE 1
#define PHASE_ARBITRATION 2
#define PHASE_SELECTION 4
-#define PHASE_DATAIN 8
+#define PHASE_DATAIN 8
#define PHASE_DATAOUT 0x10
#define PHASE_CMDOUT 0x20
#define PHASE_MSGIN 0x40
#define ST0X_BUS_FREE_DELAY 25
#define ST0X_SELECTION_DELAY 25
-#define SEAGATE 1 /* these determine the type of the controller */
+#define SEAGATE 1 /* these determine the type of the controller */
#define FD 2
#define ST0X_ID_STR "Seagate ST-01/ST-02"
#define FD_ID_STR "TMC-8XX/TMC-950"
-
static int internal_command (unsigned char target, unsigned char lun,
- const void *cmnd,
- void *buff, int bufflen, int reselect);
+ const void *cmnd,
+ void *buff, int bufflen, int reselect);
-static int incommand; /* set if arbitration has finished
- and we are in some command phase. */
+static int incommand; /* set if arbitration has finished
+ and we are in some command phase. */
-static unsigned int base_address = 0; /* Where the card ROM starts, used to
- calculate memory mapped register
- location. */
+static unsigned int base_address = 0; /* Where the card ROM starts, used to
+ calculate memory mapped register
+ location. */
-static unsigned long st0x_cr_sr; /* control register write, status
- register read. 256 bytes in
- length.
- Read is status of SCSI BUS, as per
- STAT masks. */
+static unsigned long st0x_cr_sr; /* control register write, status
+ register read. 256 bytes in
+ length.
+ Read is status of SCSI BUS, as per
+ STAT masks. */
-static unsigned long st0x_dr; /* data register, read write 256
- bytes in length. */
+static unsigned long st0x_dr; /* data register, read write 256
+ bytes in length. */
-static volatile int st0x_aborted = 0; /* set when we are aborted, ie by a
- time out, etc. */
+static volatile int st0x_aborted = 0; /* set when we are aborted, ie by a
+ time out, etc. */
-static unsigned char controller_type = 0; /* set to SEAGATE for ST0x
- boards or FD for TMC-8xx
- boards */
+static unsigned char controller_type = 0; /* set to SEAGATE for ST0x
+ boards or FD for TMC-8xx
+ boards */
static int irq = IRQ;
-MODULE_PARM(base_address, "i");
-MODULE_PARM(controller_type, "b");
-MODULE_PARM(irq, "i");
+MODULE_PARM (base_address, "i");
+MODULE_PARM (controller_type, "b");
+MODULE_PARM (irq, "i");
#define retcode(result) (((result) << 16) | (message << 8) | status)
#define STATUS ((u8) isa_readb(st0x_cr_sr))
#define WRITE_CONTROL(d) { isa_writeb((d), st0x_cr_sr); }
#define WRITE_DATA(d) { isa_writeb((d), st0x_dr); }
-void st0x_setup (char *str, int *ints)
+void
+st0x_setup (char *str, int *ints)
{
- controller_type = SEAGATE;
- base_address = ints[1];
- irq = ints[2];
+ controller_type = SEAGATE;
+ base_address = ints[1];
+ irq = ints[2];
}
-void tmc8xx_setup (char *str, int *ints)
+void
+tmc8xx_setup (char *str, int *ints)
{
- controller_type = FD;
- base_address = ints[1];
- irq = ints[2];
+ controller_type = FD;
+ base_address = ints[1];
+ irq = ints[2];
}
#ifndef OVERRIDE
-static unsigned int seagate_bases[] =
-{
- 0xc8000, 0xca000, 0xcc000,
- 0xce000, 0xdc000, 0xde000
+static unsigned int seagate_bases[] = {
+ 0xc8000, 0xca000, 0xcc000,
+ 0xce000, 0xdc000, 0xde000
};
-typedef struct
-{
- const unsigned char *signature;
- unsigned offset;
- unsigned length;
- unsigned char type;
-}
-Signature;
+typedef struct {
+ const unsigned char *signature;
+ unsigned offset;
+ unsigned length;
+ unsigned char type;
+} Signature;
-static const Signature __initdata signatures[] =
-{
- {"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
- {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
+static Signature __initdata signatures[] = {
+ {"ST01 v1.7 (C) Copyright 1987 Seagate", 15, 37, SEAGATE},
+ {"SCSI BIOS 2.00 (C) Copyright 1987 Seagate", 15, 40, SEAGATE},
/*
* The following two lines are NOT mistakes. One detects ROM revision
* are probably "good enough"
*/
- {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
- {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
+ {"SEAGATE SCSI BIOS ", 16, 17, SEAGATE},
+ {"SEAGATE SCSI BIOS ", 17, 17, SEAGATE},
/*
* However, future domain makes several incompatible SCSI boards, so specific
* signatures must be used.
*/
- {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
- {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
- {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD},
- {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD},
- {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
- {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
- {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
- {"FUTURE DOMAIN TMC-950", 5, 21, FD},
- /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
- {"IBM F1 V1.2009/22/93", 5, 25, FD},
+ {"FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89", 5, 46, FD},
+ {"FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89", 5, 46, FD},
+ {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90", 5, 47, FD},
+ {"FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90", 5, 47, FD},
+ {"FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90", 5, 46, FD},
+ {"FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92", 5, 44, FD},
+ {"IBM F1 BIOS V1.1004/30/92", 5, 25, FD},
+ {"FUTURE DOMAIN TMC-950", 5, 21, FD},
+ /* Added for 2.2.16 by Matthias_Heidbrink@b.maus.de */
+ {"IBM F1 V1.2009/22/93", 5, 25, FD},
};
#define NUM_SIGNATURES (sizeof(signatures) / sizeof(Signature))
-#endif /* n OVERRIDE */
+#endif /* n OVERRIDE */
/*
* hostno stores the hostnumber, as told to us by the init routine.
*/
static int borken_calibration = 0;
+
static void __init borken_init (void)
{
- register int count = 0, start = jiffies + 1, stop = start + 25;
+ register int count = 0, start = jiffies + 1, stop = start + 25;
- while (time_before(jiffies, start)) ;
- for (; time_before(jiffies, stop); ++count) ;
+ while (time_before (jiffies, start)) ;
+ for (; time_before (jiffies, stop); ++count) ;
/*
* Ok, we now have a count for .25 seconds. Convert to a
* count per second and divide by transfer rate in K. */
- borken_calibration = (count * 4) / (SLOW_RATE * 1024);
+ borken_calibration = (count * 4) / (SLOW_RATE * 1024);
- if (borken_calibration < 1)
- borken_calibration = 1;
+ if (borken_calibration < 1)
+ borken_calibration = 1;
}
static inline void borken_wait (void)
{
- register int count;
+ register int count;
- for (count = borken_calibration; count && (STATUS & STAT_REQ); --count) ;
+ for (count = borken_calibration; count && (STATUS & STAT_REQ);
+ --count) ;
#if (DEBUG & DEBUG_BORKEN)
- if (count)
- printk ("scsi%d : borken timeout\n", hostno);
+ if (count)
+ printk ("scsi%d : borken timeout\n", hostno);
#endif
}
-#endif /* def SLOW_RATE */
+#endif /* def SLOW_RATE */
/* These beasts only live on ISA, and ISA means 8MHz. Each ULOOP()
* contains at least one ISA access, which takes more than 0.125
int __init seagate_st0x_detect (Scsi_Host_Template * tpnt)
{
- struct Scsi_Host *instance;
- int i, j;
+ struct Scsi_Host *instance;
+ int i, j;
- tpnt->proc_name = "seagate";
+ tpnt->proc_name = "seagate";
/*
- * First, we try for the manual override. */
- DANY ("Autodetecting ST0x / TMC-8xx\n");
+ * First, we try for the manual override.
+ */
+ DANY ("Autodetecting ST0x / TMC-8xx\n");
- if (hostno != -1) {
- printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
- return 0;
- }
+ if (hostno != -1) {
+ printk (KERN_ERR "seagate_st0x_detect() called twice?!\n");
+ return 0;
+ }
/* If the user specified the controller type from the command line,
controller_type will be non-zero, so don't try to detect one */
- if (!controller_type)
- {
+ if (!controller_type) {
#ifdef OVERRIDE
- base_address = OVERRIDE;
- controller_type = CONTROLLER;
+ base_address = OVERRIDE;
+ controller_type = CONTROLLER;
- DANY("Base address overridden to %x, controller type is %s\n",
- base_address, controller_type == SEAGATE ? "SEAGATE" : "FD");
-#else /* OVERRIDE */
+ DANY ("Base address overridden to %x, controller type is %s\n",
+ base_address,
+ controller_type == SEAGATE ? "SEAGATE" : "FD");
+#else /* OVERRIDE */
/*
- * To detect this card, we simply look for the signature
+ * To detect this card, we simply look for the signature
* from the BIOS version notice in all the possible locations
* of the ROM's. This has a nice side effect of not trashing
* any register locations that might be used by something else.
* space for the on-board RAM instead.
*/
- for (i = 0; i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
-
- for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
- if (isa_check_signature (seagate_bases[i] + signatures[j].offset,
- signatures[j].signature, signatures[j].length))
- {
- base_address = seagate_bases[i];
- controller_type = signatures[j].type;
- }
-#endif /* OVERRIDE */
- } /* (! controller_type) */
-
- tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
- tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
+ for (i = 0;
+ i < (sizeof (seagate_bases) / sizeof (unsigned int)); ++i)
+
+ for (j = 0; !base_address && j < NUM_SIGNATURES; ++j)
+ if (isa_check_signature
+ (seagate_bases[i] + signatures[j].offset,
+ signatures[j].signature,
+ signatures[j].length)) {
+ base_address = seagate_bases[i];
+ controller_type = signatures[j].type;
+ }
+#endif /* OVERRIDE */
+ }
+ /* (! controller_type) */
+ tpnt->this_id = (controller_type == SEAGATE) ? 7 : 6;
+ tpnt->name = (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR;
- if (!base_address) {
- DANY ("ST0x / TMC-8xx not detected.\n");
- return 0;
- }
+ if (!base_address) {
+ DANY ("ST0x / TMC-8xx not detected.\n");
+ return 0;
+ }
- st0x_cr_sr = base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
- st0x_dr = st0x_cr_sr + 0x200;
+ st0x_cr_sr =
+ base_address + (controller_type == SEAGATE ? 0x1a00 : 0x1c00);
+ st0x_dr = st0x_cr_sr + 0x200;
- DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
- tpnt->name, base_address, st0x_cr_sr, st0x_dr);
+ DANY ("%s detected. Base address = %x, cr = %x, dr = %x\n",
+ tpnt->name, base_address, st0x_cr_sr, st0x_dr);
/*
- * At all times, we will use IRQ 5. Should also check for IRQ3 if we
+ * At all times, we will use IRQ 5. Should also check for IRQ3 if we
* loose our first interrupt.
*/
- instance = scsi_register (tpnt, 0);
- if(instance == NULL)
- return 0;
-
- hostno = instance->host_no;
- if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
- (controller_type == SEAGATE) ? "seagate" : "tmc-8xx", NULL)) {
- printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
- return 0;
- }
- instance->irq = irq;
- instance->io_port = base_address;
+ instance = scsi_register (tpnt, 0);
+ if (instance == NULL)
+ return 0;
+
+ hostno = instance->host_no;
+ if (request_irq (irq, do_seagate_reconnect_intr, SA_INTERRUPT,
+ (controller_type == SEAGATE) ? "seagate" : "tmc-8xx",
+ NULL)) {
+ printk ("scsi%d : unable to allocate IRQ%d\n", hostno, irq);
+ return 0;
+ }
+ instance->irq = irq;
+ instance->io_port = base_address;
#ifdef SLOW_RATE
- printk( "Calibrating borken timer... " );
- borken_init ();
- printk( " %d cycles per transfer\n", borken_calibration );
+ printk (KERN_INFO "Calibrating borken timer... ");
+ borken_init ();
+ printk (" %d cycles per transfer\n", borken_calibration);
#endif
- printk( "This is one second... " );
- {
- int clock;
- ULOOP( 1*1000*1000 ) {
- STATUS;
- if (TIMEOUT) break;
- }
- }
+ printk (KERN_INFO "This is one second... ");
+ {
+ int clock;
+ ULOOP (1 * 1000 * 1000) {
+ STATUS;
+ if (TIMEOUT)
+ break;
+ }
+ }
- printk ("done, %s options:"
+ printk ("done, %s options:"
#ifdef ARBITRATE
- " ARBITRATE"
+ " ARBITRATE"
#endif
#ifdef DEBUG
- " DEBUG"
+ " DEBUG"
#endif
#ifdef FAST
- " FAST"
+ " FAST"
#ifdef FAST32
- "32"
+ "32"
#endif
#endif
#ifdef LINKED
- " LINKED"
+ " LINKED"
#endif
#ifdef PARITY
- " PARITY"
+ " PARITY"
#endif
#ifdef SEAGATE_USE_ASM
- " SEAGATE_USE_ASM"
+ " SEAGATE_USE_ASM"
#endif
#ifdef SLOW_RATE
- " SLOW_RATE"
+ " SLOW_RATE"
#endif
#ifdef SWAPSTAT
- " SWAPSTAT"
+ " SWAPSTAT"
#endif
#ifdef SWAPCNTDATA
- " SWAPCNTDATA"
+ " SWAPCNTDATA"
#endif
- "\n", tpnt->name);
- return 1;
+ "\n", tpnt->name);
+ return 1;
}
-const char *seagate_st0x_info (struct Scsi_Host *shpnt)
+const char *
+seagate_st0x_info (struct Scsi_Host *shpnt)
{
- static char buffer[64];
+ static char buffer[64];
- sprintf (buffer, "%s at irq %d, address 0x%05X",
- (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
- irq, base_address);
- return buffer;
+ sprintf (buffer, "%s at irq %d, address 0x%05X",
+ (controller_type == SEAGATE) ? ST0X_ID_STR : FD_ID_STR,
+ irq, base_address);
+ return buffer;
}
/*
static void do_seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
{
- unsigned long flags;
+ unsigned long flags;
- spin_lock_irqsave(&io_request_lock, flags);
- seagate_reconnect_intr(irq, dev_id, regs);
- spin_unlock_irqrestore(&io_request_lock, flags);
+ spin_lock_irqsave (&io_request_lock, flags);
+ seagate_reconnect_intr (irq, dev_id, regs);
+ spin_unlock_irqrestore (&io_request_lock, flags);
}
static void seagate_reconnect_intr (int irq, void *dev_id, struct pt_regs *regs)
{
- int temp;
- Scsi_Cmnd *SCtmp;
-
- DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n", hostno);
-
- if (!should_reconnect)
- printk ("scsi%d: unexpected interrupt.\n", hostno);
- else
- {
- should_reconnect = 0;
-
- DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
- "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
- current_target, current_data, current_bufflen);
-
- temp = internal_command (current_target, current_lun, current_cmnd,
- current_data, current_bufflen, RECONNECT_NOW);
-
- if (msg_byte (temp) != DISCONNECT)
- {
- if (done_fn)
- {
- DPRINTK (PHASE_RESELECT, "scsi%d : done_fn(%d,%08x)", hostno,
- hostno, temp);
- if (!SCint)
- panic ("SCint == NULL in seagate");
- SCtmp = SCint;
- SCint = NULL;
- SCtmp->result = temp;
- done_fn (SCtmp);
- }
- else
- printk ("done_fn() not defined.\n");
- }
- }
+ int temp;
+ Scsi_Cmnd *SCtmp;
+
+ DPRINTK (PHASE_RESELECT, "scsi%d : seagate_reconnect_intr() called\n",
+ hostno);
+
+ if (!should_reconnect)
+ printk ("scsi%d: unexpected interrupt.\n", hostno);
+ else {
+ should_reconnect = 0;
+
+ DPRINTK (PHASE_RESELECT, "scsi%d : internal_command("
+ "%d, %08x, %08x, RECONNECT_NOW\n", hostno,
+ current_target, current_data, current_bufflen);
+
+ temp =
+ internal_command (current_target, current_lun, current_cmnd,
+ current_data, current_bufflen,
+ RECONNECT_NOW);
+
+ if (msg_byte (temp) != DISCONNECT) {
+ if (done_fn) {
+ DPRINTK (PHASE_RESELECT,
+ "scsi%d : done_fn(%d,%08x)", hostno,
+ hostno, temp);
+ if (!SCint)
+ panic ("SCint == NULL in seagate");
+ SCtmp = SCint;
+ SCint = NULL;
+ SCtmp->result = temp;
+ done_fn (SCtmp);
+ } else
+ printk ("done_fn() not defined.\n");
+ }
+ }
}
/*
int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
{
- int result, reconnect;
- Scsi_Cmnd *SCtmp;
-
- DANY( "seagate: que_command" );
- done_fn = done;
- current_target = SCpnt->target;
- current_lun = SCpnt->lun;
- (const void *) current_cmnd = SCpnt->cmnd;
- current_data = (unsigned char *) SCpnt->request_buffer;
- current_bufflen = SCpnt->request_bufflen;
- SCint = SCpnt;
- if (recursion_depth) return 0;
- recursion_depth++;
- do
- {
+ int result, reconnect;
+ Scsi_Cmnd *SCtmp;
+
+ DANY ("seagate: que_command");
+ done_fn = done;
+ current_target = SCpnt->target;
+ current_lun = SCpnt->lun;
+ (const void *) current_cmnd = SCpnt->cmnd;
+ current_data = (unsigned char *) SCpnt->request_buffer;
+ current_bufflen = SCpnt->request_bufflen;
+ SCint = SCpnt;
+ if (recursion_depth)
+ return 0;
+ recursion_depth++;
+ do {
#ifdef LINKED
/*
* Set linked command bit in control field of SCSI command.
*/
- current_cmnd[SCpnt->cmd_len] |= 0x01;
- if (linked_connected)
- {
- DPRINTK (DEBUG_LINKED,
- "scsi%d : using linked commands, current I_T_L nexus is ", hostno);
- if ((linked_target == current_target) && (linked_lun == current_lun))
- {
- DPRINTK (DEBUG_LINKED, "correct\n");
- reconnect = LINKED_RIGHT;
- }
- else
- {
- DPRINTK (DEBUG_LINKED, "incorrect\n");
- reconnect = LINKED_WRONG;
- }
- }
- else
-#endif /* LINKED */
- reconnect = CAN_RECONNECT;
-
- result = internal_command (SCint->target, SCint->lun, SCint->cmnd,
- SCint->request_buffer, SCint->request_bufflen, reconnect);
- if (msg_byte (result) == DISCONNECT) break;
- SCtmp = SCint;
- SCint = NULL;
- SCtmp->result = result;
- done_fn (SCtmp);
- }
- while (SCint);
- recursion_depth--;
- return 0;
+ current_cmnd[SCpnt->cmd_len] |= 0x01;
+ if (linked_connected) {
+ DPRINTK (DEBUG_LINKED,
+ "scsi%d : using linked commands, current I_T_L nexus is ",
+ hostno);
+ if ((linked_target == current_target)
+ && (linked_lun == current_lun)) {
+ DPRINTK (DEBUG_LINKED, "correct\n");
+ reconnect = LINKED_RIGHT;
+ } else {
+ DPRINTK (DEBUG_LINKED, "incorrect\n");
+ reconnect = LINKED_WRONG;
+ }
+ } else
+#endif /* LINKED */
+ reconnect = CAN_RECONNECT;
+
+ result =
+ internal_command (SCint->target, SCint->lun, SCint->cmnd,
+ SCint->request_buffer,
+ SCint->request_bufflen, reconnect);
+ if (msg_byte (result) == DISCONNECT)
+ break;
+ SCtmp = SCint;
+ SCint = NULL;
+ SCtmp->result = result;
+ done_fn (SCtmp);
+ }
+ while (SCint);
+ recursion_depth--;
+ return 0;
}
int seagate_st0x_command (Scsi_Cmnd * SCpnt)
{
- return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
- SCpnt->request_buffer, SCpnt->request_bufflen,
- (int) NO_RECONNECT);
+ return internal_command (SCpnt->target, SCpnt->lun, SCpnt->cmnd,
+ SCpnt->request_buffer, SCpnt->request_bufflen,
+ (int) NO_RECONNECT);
}
-static int internal_command (unsigned char target, unsigned char lun,
- const void *cmnd, void *buff, int bufflen, int reselect)
+static int internal_command (unsigned char target, unsigned char lun,
+ const void *cmnd, void *buff, int bufflen, int reselect)
{
- unsigned char *data = NULL;
- struct scatterlist *buffer = NULL;
- int clock, temp, nobuffs = 0, done = 0, len = 0;
- unsigned long flags;
+ unsigned char *data = NULL;
+ struct scatterlist *buffer = NULL;
+ int clock, temp, nobuffs = 0, done = 0, len = 0;
+ unsigned long flags;
#ifdef DEBUG
- int transfered = 0, phase = 0, newphase;
+ int transfered = 0, phase = 0, newphase;
#endif
- register unsigned char status_read;
- unsigned char tmp_data, tmp_control, status = 0, message = 0;
+ register unsigned char status_read;
+ unsigned char tmp_data, tmp_control, status = 0, message = 0;
- unsigned transfersize = 0, underflow = 0;
+ unsigned transfersize = 0, underflow = 0;
#ifdef SLOW_RATE
- int borken = (int) SCint->device->borken; /* Does the current target require
- Very Slow I/O ? */
+ int borken = (int) SCint->device->borken; /* Does the current target require
+ Very Slow I/O ? */
#endif
- incommand = 0;
- st0x_aborted = 0;
+ incommand = 0;
+ st0x_aborted = 0;
#if (DEBUG & PRINT_COMMAND)
- printk ("scsi%d : target = %d, command = ", hostno, target);
- print_command ((unsigned char *) cmnd);
+ printk ("scsi%d : target = %d, command = ", hostno, target);
+ print_command ((unsigned char *) cmnd);
#endif
#if (DEBUG & PHASE_RESELECT)
- switch (reselect)
- {
- case RECONNECT_NOW:
- printk ("scsi%d : reconnecting\n", hostno);
- break;
+ switch (reselect) {
+ case RECONNECT_NOW:
+ printk ("scsi%d : reconnecting\n", hostno);
+ break;
#ifdef LINKED
- case LINKED_RIGHT:
- printk ("scsi%d : connected, can reconnect\n", hostno);
- break;
- case LINKED_WRONG:
- printk ("scsi%d : connected to wrong target, can reconnect\n", hostno);
- break;
+ case LINKED_RIGHT:
+ printk ("scsi%d : connected, can reconnect\n", hostno);
+ break;
+ case LINKED_WRONG:
+ printk ("scsi%d : connected to wrong target, can reconnect\n",
+ hostno);
+ break;
#endif
- case CAN_RECONNECT:
- printk ("scsi%d : allowed to reconnect\n", hostno);
- break;
- default:
- printk ("scsi%d : not allowed to reconnect\n", hostno);
- }
+ case CAN_RECONNECT:
+ printk ("scsi%d : allowed to reconnect\n", hostno);
+ break;
+ default:
+ printk ("scsi%d : not allowed to reconnect\n", hostno);
+ }
#endif
- if (target == (controller_type == SEAGATE ? 7 : 6))
- return DID_BAD_TARGET;
+ if (target == (controller_type == SEAGATE ? 7 : 6))
+ return DID_BAD_TARGET;
/*
- * We work it differently depending on if this is is "the first time,"
+ * We work it differently depending on if this is is "the first time,"
* or a reconnect. If this is a reselect phase, then SEL will
* be asserted, and we must skip selection / arbitration phases.
*/
- switch (reselect)
- {
- case RECONNECT_NOW:
- DPRINTK ( PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
+ switch (reselect) {
+ case RECONNECT_NOW:
+ DPRINTK (PHASE_RESELECT, "scsi%d : phase RESELECT \n", hostno);
/*
- * At this point, we should find the logical or of our ID and the original
+ * At this point, we should find the logical or of our ID and the original
* target's ID on the BUS, with BSY, SEL, and I/O signals asserted.
*
* After ARBITRATION phase is completed, only SEL, BSY, and the
* target ID are asserted. A valid initiator ID is not on the bus
* until IO is asserted, so we must wait for that.
*/
- ULOOP( 100*1000 ) {
- temp = STATUS;
- if ((temp & STAT_IO) && !(temp & STAT_BSY))
- break;
-
- if (TIMEOUT) {
- DPRINTK (PHASE_RESELECT,
- "scsi%d : RESELECT timed out while waiting for IO .\n", hostno);
- return (DID_BAD_INTR << 16);
- }
- }
+ ULOOP (100 * 1000) {
+ temp = STATUS;
+ if ((temp & STAT_IO) && !(temp & STAT_BSY))
+ break;
+
+ if (TIMEOUT) {
+ DPRINTK (PHASE_RESELECT,
+ "scsi%d : RESELECT timed out while waiting for IO .\n",
+ hostno);
+ return (DID_BAD_INTR << 16);
+ }
+ }
/*
- * After I/O is asserted by the target, we can read our ID and its
+ * After I/O is asserted by the target, we can read our ID and its
* ID off of the BUS.
*/
- if (!((temp = DATA) & (controller_type == SEAGATE ? 0x80 : 0x40)))
- {
- DPRINTK (PHASE_RESELECT,
- "scsi%d : detected reconnect request to different target.\n"
- "\tData bus = %d\n", hostno, temp);
- return (DID_BAD_INTR << 16);
- }
-
- if (!(temp & (1 << current_target)))
- {
- printk ("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
- hostno, temp);
- return (DID_BAD_INTR << 16);
- }
-
- buffer = current_buffer;
- cmnd = current_cmnd; /* WDE add */
- data = current_data; /* WDE add */
- len = current_bufflen; /* WDE add */
- nobuffs = current_nobuffs;
+ if (!
+ ((temp =
+ DATA) & (controller_type == SEAGATE ? 0x80 : 0x40))) {
+ DPRINTK (PHASE_RESELECT,
+ "scsi%d : detected reconnect request to different target.\n"
+ "\tData bus = %d\n", hostno, temp);
+ return (DID_BAD_INTR << 16);
+ }
+
+ if (!(temp & (1 << current_target))) {
+ printk
+ ("scsi%d : Unexpected reselect interrupt. Data bus = %d\n",
+ hostno, temp);
+ return (DID_BAD_INTR << 16);
+ }
+
+ buffer = current_buffer;
+ cmnd = current_cmnd; /* WDE add */
+ data = current_data; /* WDE add */
+ len = current_bufflen; /* WDE add */
+ nobuffs = current_nobuffs;
/*
- * We have determined that we have been selected. At this point,
+ * We have determined that we have been selected. At this point,
* we must respond to the reselection by asserting BSY ourselves
*/
#if 1
- WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
+ WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE | CMD_BSY);
#else
- WRITE_CONTROL (BASE_CMD | CMD_BSY);
+ WRITE_CONTROL (BASE_CMD | CMD_BSY);
#endif
/*
- * The target will drop SEL, and raise BSY, at which time we must drop
+ * The target will drop SEL, and raise BSY, at which time we must drop
* BSY.
*/
- ULOOP( 100*1000 ) {
- if (!(STATUS & STAT_SEL)) break;
- if (TIMEOUT) {
- WRITE_CONTROL (BASE_CMD | CMD_INTR);
- DPRINTK (PHASE_RESELECT,
- "scsi%d : RESELECT timed out while waiting for SEL.\n", hostno);
- return (DID_BAD_INTR << 16);
- }
- }
+ ULOOP (100 * 1000) {
+ if (!(STATUS & STAT_SEL))
+ break;
+ if (TIMEOUT) {
+ WRITE_CONTROL (BASE_CMD | CMD_INTR);
+ DPRINTK (PHASE_RESELECT,
+ "scsi%d : RESELECT timed out while waiting for SEL.\n",
+ hostno);
+ return (DID_BAD_INTR << 16);
+ }
+ }
- WRITE_CONTROL (BASE_CMD);
+ WRITE_CONTROL (BASE_CMD);
/*
- * At this point, we have connected with the target and can get
+ * At this point, we have connected with the target and can get
* on with our lives.
*/
- break;
- case CAN_RECONNECT:
+ break;
+ case CAN_RECONNECT:
#ifdef LINKED
/*
* message on MESSAGE OUT phase, and then loop back to here.
*/
- connect_loop:
+ connect_loop:
#endif
- DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n", hostno);
+ DPRINTK (PHASE_BUS_FREE, "scsi%d : phase = BUS FREE \n",
+ hostno);
/*
* BUS FREE PHASE
#ifndef ARBITRATE
#error FIXME: this is broken: we may not use jiffies here - we are under cli(). It will hardlock.
- clock = jiffies + ST0X_BUS_FREE_DELAY;
+ clock = jiffies + ST0X_BUS_FREE_DELAY;
- while (((STATUS | STATUS | STATUS) &
- (STAT_BSY | STAT_SEL)) &&
- (!st0x_aborted) && time_before(jiffies, clock));
+ while (((STATUS | STATUS | STATUS) &
+ (STAT_BSY | STAT_SEL)) &&
+ (!st0x_aborted) && time_before (jiffies, clock)) ;
- if (time_after(jiffies, clock))
- return retcode (DID_BUS_BUSY);
- else if (st0x_aborted)
- return retcode (st0x_aborted);
+ if (time_after (jiffies, clock))
+ return retcode (DID_BUS_BUSY);
+ else if (st0x_aborted)
+ return retcode (st0x_aborted);
#endif
- DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n", hostno);
+ DPRINTK (PHASE_SELECTION, "scsi%d : phase = SELECTION\n",
+ hostno);
- clock = jiffies + ST0X_SELECTION_DELAY;
+ clock = jiffies + ST0X_SELECTION_DELAY;
/*
* Arbitration/selection procedure :
*/
#ifdef ARBITRATE
- save_flags (flags);
- cli ();
- WRITE_CONTROL (0);
- WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
- WRITE_CONTROL (CMD_START_ARB);
- restore_flags (flags);
-
- ULOOP( ST0X_SELECTION_DELAY * 10000 ) {
- status_read = STATUS;
- if (status_read & STAT_ARB_CMPL) break;
- if (st0x_aborted) /* FIXME: What? We are going to do something even after abort? */
- break;
- if (TIMEOUT || (status_read & STAT_SEL)) {
- printk( "scsi%d : arbitration lost or timeout.\n", hostno );
- WRITE_CONTROL (BASE_CMD);
- return retcode (DID_NO_CONNECT);
- }
- }
-
- DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n", hostno);
+ save_flags (flags);
+ cli ();
+ WRITE_CONTROL (0);
+ WRITE_DATA ((controller_type == SEAGATE) ? 0x80 : 0x40);
+ WRITE_CONTROL (CMD_START_ARB);
+ restore_flags (flags);
+
+ ULOOP (ST0X_SELECTION_DELAY * 10000) {
+ status_read = STATUS;
+ if (status_read & STAT_ARB_CMPL)
+ break;
+ if (st0x_aborted) /* FIXME: What? We are going to do something even after abort? */
+ break;
+ if (TIMEOUT || (status_read & STAT_SEL)) {
+ printk
+ ("scsi%d : arbitration lost or timeout.\n",
+ hostno);
+ WRITE_CONTROL (BASE_CMD);
+ return retcode (DID_NO_CONNECT);
+ }
+ }
+
+ DPRINTK (PHASE_SELECTION, "scsi%d : arbitration complete\n",
+ hostno);
#endif
/*
* try this with a SCSI protocol or logic analyzer to see what is
* going on.
*/
- tmp_data = (unsigned char) ((1 << target) | (controller_type == SEAGATE ? 0x80 : 0x40));
- tmp_control = BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN : 0);
-
- save_flags(flags);
- cli();
+ tmp_data =
+ (unsigned char) ((1 << target) |
+ (controller_type ==
+ SEAGATE ? 0x80 : 0x40));
+ tmp_control =
+ BASE_CMD | CMD_DRVR_ENABLE | CMD_SEL | (reselect ? CMD_ATTN
+ : 0);
+
+ save_flags (flags);
+ cli ();
#ifdef OLDCNTDATASCEME
#ifdef SWAPCNTDATA
- WRITE_CONTROL (tmp_control);
- WRITE_DATA (tmp_data);
+ WRITE_CONTROL (tmp_control);
+ WRITE_DATA (tmp_data);
#else
- WRITE_DATA (tmp_data);
- WRITE_CONTROL (tmp_control);
+ WRITE_DATA (tmp_data);
+ WRITE_CONTROL (tmp_control);
#endif
#else
- tmp_control ^= CMD_BSY; /* This is guesswork. What used to be in driver */
- WRITE_CONTROL (tmp_control); /* could never work: it sent data into control */
- WRITE_DATA (tmp_data); /* register and control info into data. Hopefully */
- tmp_control ^= CMD_BSY; /* fixed, but order of first two may be wrong. */
- WRITE_CONTROL (tmp_control); /* -- pavel@ucw.cz */
-#endif
-
+ tmp_control ^= CMD_BSY; /* This is guesswork. What used to be in driver */
+ WRITE_CONTROL (tmp_control); /* could never work: it sent data into control */
+ WRITE_DATA (tmp_data); /* register and control info into data. Hopefully */
+ tmp_control ^= CMD_BSY; /* fixed, but order of first two may be wrong. */
+ WRITE_CONTROL (tmp_control); /* -- pavel@ucw.cz */
+#endif
- restore_flags (flags);
+ restore_flags (flags);
- ULOOP( 250*1000 ) {
- if (st0x_aborted) {
+ ULOOP (250 * 1000) {
+ if (st0x_aborted) {
/*
- * If we have been aborted, and we have a command in progress, IE the
+ * If we have been aborted, and we have a command in progress, IE the
* target still has BSY asserted, then we will reset the bus, and
* notify the midlevel driver to expect sense.
*/
- WRITE_CONTROL (BASE_CMD);
- if (STATUS & STAT_BSY) {
- printk ("scsi%d : BST asserted after we've been aborted.\n", hostno);
- seagate_st0x_reset (NULL, 0);
- return retcode (DID_RESET);
- }
- return retcode (st0x_aborted);
- }
- if (STATUS & STAT_BSY) break;
- if (TIMEOUT) {
- DPRINTK (PHASE_SELECTION, "scsi%d : NO CONNECT with target %d, stat = %x \n",
- hostno, target, STATUS);
- return retcode (DID_NO_CONNECT);
- }
- }
+ WRITE_CONTROL (BASE_CMD);
+ if (STATUS & STAT_BSY) {
+ printk
+ ("scsi%d : BST asserted after we've been aborted.\n",
+ hostno);
+ seagate_st0x_reset (NULL, 0);
+ return retcode (DID_RESET);
+ }
+ return retcode (st0x_aborted);
+ }
+ if (STATUS & STAT_BSY)
+ break;
+ if (TIMEOUT) {
+ DPRINTK (PHASE_SELECTION,
+ "scsi%d : NO CONNECT with target %d, stat = %x \n",
+ hostno, target, STATUS);
+ return retcode (DID_NO_CONNECT);
+ }
+ }
/* Establish current pointers. Take into account scatter / gather */
- if ((nobuffs = SCint->use_sg))
- {
+ if ((nobuffs = SCint->use_sg)) {
#if (DEBUG & DEBUG_SG)
- {
- int i;
-
- printk ("scsi%d : scatter gather requested, using %d buffers.\n",
- hostno, nobuffs);
- for (i = 0; i < nobuffs; ++i)
- printk ("scsi%d : buffer %d address = %08x length = %d\n",
- hostno, i, buffer[i].address, buffer[i].length);
- }
+ {
+ int i;
+
+ printk
+ ("scsi%d : scatter gather requested, using %d buffers.\n",
+ hostno, nobuffs);
+ for (i = 0; i < nobuffs; ++i)
+ printk
+ ("scsi%d : buffer %d address = %08x length = %d\n",
+ hostno, i, buffer[i].address,
+ buffer[i].length);
+ }
#endif
- buffer = (struct scatterlist *) SCint->buffer;
- len = buffer->length;
- data = (unsigned char *) buffer->address;
- }
- else
- {
- DPRINTK (DEBUG_SG, "scsi%d : scatter gather not requested.\n", hostno);
- buffer = NULL;
- len = SCint->request_bufflen;
- data = (unsigned char *) SCint->request_buffer;
- }
-
- DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n", hostno, len);
-
- break;
+ buffer = (struct scatterlist *) SCint->buffer;
+ len = buffer->length;
+ data = (unsigned char *) buffer->address;
+ } else {
+ DPRINTK (DEBUG_SG,
+ "scsi%d : scatter gather not requested.\n",
+ hostno);
+ buffer = NULL;
+ len = SCint->request_bufflen;
+ data = (unsigned char *) SCint->request_buffer;
+ }
+
+ DPRINTK (PHASE_DATAIN | PHASE_DATAOUT, "scsi%d : len = %d\n",
+ hostno, len);
+
+ break;
#ifdef LINKED
- case LINKED_RIGHT:
- break;
- case LINKED_WRONG:
- break;
+ case LINKED_RIGHT:
+ break;
+ case LINKED_WRONG:
+ break;
#endif
- } /* end of switch(reselect) */
+ } /* end of switch(reselect) */
/*
* There are several conditions under which we wish to send a message :
/* GCC does not like an ifdef inside a macro, so do it the hard way. */
#ifdef LINKED
- WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
- (((reselect == CAN_RECONNECT)
- || (reselect == LINKED_WRONG)
- )? CMD_ATTN : 0));
+ WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
+ (((reselect == CAN_RECONNECT)
+ || (reselect == LINKED_WRONG)
+ )? CMD_ATTN : 0));
#else
- WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
- (((reselect == CAN_RECONNECT)
- )? CMD_ATTN : 0));
+ WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE |
+ (((reselect == CAN_RECONNECT)
+ )? CMD_ATTN : 0));
#endif
/*
*
*/
- DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
+ DPRINTK (PHASE_ETC, "scsi%d : phase = INFORMATION TRANSFER\n", hostno);
- incommand = 1;
- transfersize = SCint->transfersize;
- underflow = SCint->underflow;
+ incommand = 1;
+ transfersize = SCint->transfersize;
+ underflow = SCint->underflow;
/*
- * Now, we poll the device for status information,
+ * Now, we poll the device for status information,
* and handle any requests it makes. Note that since we are unsure of
* how much data will be flowing across the system, etc and cannot
* make reasonable timeouts, that we will instead have the midlevel
* driver handle any timeouts that occur in this phase.
*/
- while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done)
- {
+ while (((status_read = STATUS) & STAT_BSY) && !st0x_aborted && !done) {
#ifdef PARITY
- if (status_read & STAT_PARITY)
- {
- printk ("scsi%d : got parity error\n", hostno);
- st0x_aborted = DID_PARITY;
- }
+ if (status_read & STAT_PARITY) {
+ printk ("scsi%d : got parity error\n", hostno);
+ st0x_aborted = DID_PARITY;
+ }
#endif
- if (status_read & STAT_REQ)
- {
+ if (status_read & STAT_REQ) {
#if ((DEBUG & PHASE_ETC) == PHASE_ETC)
- if ((newphase = (status_read & REQ_MASK)) != phase)
- {
- phase = newphase;
- switch (phase)
- {
- case REQ_DATAOUT:
- printk ("scsi%d : phase = DATA OUT\n", hostno);
- break;
- case REQ_DATAIN:
- printk ("scsi%d : phase = DATA IN\n", hostno);
- break;
- case REQ_CMDOUT:
- printk ("scsi%d : phase = COMMAND OUT\n", hostno);
- break;
- case REQ_STATIN:
- printk ("scsi%d : phase = STATUS IN\n", hostno);
- break;
- case REQ_MSGOUT:
- printk ("scsi%d : phase = MESSAGE OUT\n", hostno);
- break;
- case REQ_MSGIN:
- printk ("scsi%d : phase = MESSAGE IN\n", hostno);
- break;
- default:
- printk ("scsi%d : phase = UNKNOWN\n", hostno);
- st0x_aborted = DID_ERROR;
- }
- }
+ if ((newphase = (status_read & REQ_MASK)) != phase) {
+ phase = newphase;
+ switch (phase) {
+ case REQ_DATAOUT:
+ printk ("scsi%d : phase = DATA OUT\n",
+ hostno);
+ break;
+ case REQ_DATAIN:
+ printk ("scsi%d : phase = DATA IN\n",
+ hostno);
+ break;
+ case REQ_CMDOUT:
+ printk
+ ("scsi%d : phase = COMMAND OUT\n",
+ hostno);
+ break;
+ case REQ_STATIN:
+ printk ("scsi%d : phase = STATUS IN\n",
+ hostno);
+ break;
+ case REQ_MSGOUT:
+ printk
+ ("scsi%d : phase = MESSAGE OUT\n",
+ hostno);
+ break;
+ case REQ_MSGIN:
+ printk ("scsi%d : phase = MESSAGE IN\n",
+ hostno);
+ break;
+ default:
+ printk ("scsi%d : phase = UNKNOWN\n",
+ hostno);
+ st0x_aborted = DID_ERROR;
+ }
+ }
#endif
- switch (status_read & REQ_MASK)
- {
- case REQ_DATAOUT:
+ switch (status_read & REQ_MASK) {
+ case REQ_DATAOUT:
/*
* If we are in fast mode, then we simply splat the data out
* in word-sized chunks as fast as we can.
*/
- if (!len)
- {
+ if (!len) {
#if 0
- printk ("scsi%d: underflow to target %d lun %d \n", hostno, target, lun);
- st0x_aborted = DID_ERROR;
- fast = 0;
+ printk
+ ("scsi%d: underflow to target %d lun %d \n",
+ hostno, target, lun);
+ st0x_aborted = DID_ERROR;
+ fast = 0;
#endif
- break;
- }
+ break;
+ }
- if (fast && transfersize && !(len % transfersize)
- && (len >= transfersize)
+ if (fast && transfersize
+ && !(len % transfersize)
+ && (len >= transfersize)
#ifdef FAST32
- && !(transfersize % 4)
+ && !(transfersize % 4)
#endif
- )
- {
- DPRINTK (DEBUG_FAST,
- "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
- " len = %d, data = %08x\n",
- hostno, SCint->underflow, SCint->transfersize, len, data);
+ ) {
+ DPRINTK (DEBUG_FAST,
+ "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+ " len = %d, data = %08x\n",
+ hostno, SCint->underflow,
+ SCint->transfersize, len,
+ data);
/* SJT: Start. Fast Write */
#ifdef SEAGATE_USE_ASM
- __asm__(
- "cld\n\t"
+ __asm__ ("cld\n\t"
#ifdef FAST32
- "shr $2, %%ecx\n\t"
- "1:\t"
- "lodsl\n\t"
- "movl %%eax, (%%edi)\n\t"
+ "shr $2, %%ecx\n\t"
+ "1:\t"
+ "lodsl\n\t"
+ "movl %%eax, (%%edi)\n\t"
#else
- "1:\t"
- "lodsb\n\t"
- "movb %%al, (%%edi)\n\t"
+ "1:\t"
+ "lodsb\n\t"
+ "movb %%al, (%%edi)\n\t"
#endif
- "loop 1b;"
-/* output */ :
-/* input */ : "D" (phys_to_virt(st0x_dr)), "S" (data), "c" (SCint->transfersize)
-/* clobbered */ : "eax", "ecx", "esi" );
-#else /* SEAGATE_USE_ASM */
- {
+ "loop 1b;"
+ /* output */ :
+ /* input */ :"D" (phys_to_virt (st0x_dr)),
+ "S"
+ (data),
+ "c" (SCint->transfersize)
+/* clobbered */
+ : "eax", "ecx",
+ "esi");
+#else /* SEAGATE_USE_ASM */
+ {
#ifdef FAST32
- unsigned int *iop = phys_to_virt (st0x_dr);
- const unsigned int *dp = (unsigned int *) data;
- int xferlen = transfersize >> 2;
+ unsigned int *iop =
+ phys_to_virt (st0x_dr);
+ const unsigned int *dp =
+ (unsigned int *) data;
+ int xferlen = transfersize >> 2;
#else
- unsigned char *iop = phys_to_virt (st0x_dr);
- const unsigned char *dp = data;
- int xferlen = transfersize;
+ unsigned char *iop =
+ phys_to_virt (st0x_dr);
+ const unsigned char *dp = data;
+ int xferlen = transfersize;
#endif
- for (; xferlen; --xferlen)
- *iop = *dp++;
- }
-#endif /* SEAGATE_USE_ASM */
+ for (; xferlen; --xferlen)
+ *iop = *dp++;
+ }
+#endif /* SEAGATE_USE_ASM */
/* SJT: End */
- len -= transfersize;
- data += transfersize;
- DPRINTK (DEBUG_FAST,
- "scsi%d : FAST transfer complete len = %d data = %08x\n",
- hostno, len, data);
- }
- else
- {
+ len -= transfersize;
+ data += transfersize;
+ DPRINTK (DEBUG_FAST,
+ "scsi%d : FAST transfer complete len = %d data = %08x\n",
+ hostno, len, data);
+ } else {
/*
* We loop as long as we are in a data out phase, there is data to send,
* and BSY is still active.
/* SJT: Start. Slow Write. */
#ifdef SEAGATE_USE_ASM
-int __dummy_1,__dummy_2;
+ int __dummy_1, __dummy_2;
/*
* We loop as long as we are in a data out phase, there is data to send,
/* Local variables : len = ecx , data = esi,
st0x_cr_sr = ebx, st0x_dr = edi
*/
- __asm__ (
- /* Test for any data here at all. */
- "orl %%ecx, %%ecx\n\t"
- "jz 2f\n\t"
- "cld\n\t"
+ __asm__ (
+ /* Test for any data here at all. */
+ "orl %%ecx, %%ecx\n\t"
+ "jz 2f\n\t" "cld\n\t"
/* "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx\n\t" */
/* "movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi\n\t" */
- "1:\t"
- "movb (%%ebx), %%al\n\t"
- /* Test for BSY */
- "test $1, %%al\n\t"
- "jz 2f\n\t"
- /* Test for data out phase - STATUS & REQ_MASK should be
- REQ_DATAOUT, which is 0. */
- "test $0xe, %%al\n\t"
- "jnz 2f\n\t"
- /* Test for REQ */
- "test $0x10, %%al\n\t"
- "jz 1b\n\t"
- "lodsb\n\t"
- "movb %%al, (%%edi)\n\t"
- "loop 1b\n\t"
- "2:\n"
-/* output */ : "=S" (data), "=c" (len) ,"=b" (__dummy_1) ,"=D" (__dummy_2)
-/* input */ : "0" (data), "1" (len), "2" (phys_to_virt(st0x_cr_sr)), "3" (phys_to_virt(st0x_dr))
-/* clobbered */ : "eax");
-#else /* SEAGATE_USE_ASM */
- while (len)
- {
- unsigned char stat;
-
- stat = STATUS;
- if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAOUT))
- break;
- if (stat & STAT_REQ)
- {
- WRITE_DATA (*data++);
- --len;
- }
- }
-#endif /* SEAGATE_USE_ASM */
+ "1:\t"
+ "movb (%%ebx), %%al\n\t"
+ /* Test for BSY */
+ "test $1, %%al\n\t"
+ "jz 2f\n\t"
+ /* Test for data out phase - STATUS & REQ_MASK should be
+ REQ_DATAOUT, which is 0. */
+ "test $0xe, %%al\n\t"
+ "jnz 2f\n\t"
+ /* Test for REQ */
+ "test $0x10, %%al\n\t"
+ "jz 1b\n\t"
+ "lodsb\n\t"
+ "movb %%al, (%%edi)\n\t"
+ "loop 1b\n\t" "2:\n"
+ /* output */ :"=S" (data), "=c" (len),
+ "=b"
+ (__dummy_1),
+ "=D" (__dummy_2)
+/* input */
+ : "0" (data), "1" (len),
+ "2" (phys_to_virt
+ (st0x_cr_sr)),
+ "3" (phys_to_virt
+ (st0x_dr))
+/* clobbered */
+ : "eax");
+#else /* SEAGATE_USE_ASM */
+ while (len) {
+ unsigned char stat;
+
+ stat = STATUS;
+ if (!(stat & STAT_BSY)
+ || ((stat & REQ_MASK) !=
+ REQ_DATAOUT))
+ break;
+ if (stat & STAT_REQ) {
+ WRITE_DATA (*data++);
+ --len;
+ }
+ }
+#endif /* SEAGATE_USE_ASM */
/* SJT: End. */
- }
-
- if (!len && nobuffs)
- {
- --nobuffs;
- ++buffer;
- len = buffer->length;
- data = (unsigned char *) buffer->address;
- DPRINTK (DEBUG_SG,
- "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
- hostno, len, data);
- }
- break;
-
- case REQ_DATAIN:
+ }
+
+ if (!len && nobuffs) {
+ --nobuffs;
+ ++buffer;
+ len = buffer->length;
+ data =
+ (unsigned char *) buffer->address;
+ DPRINTK (DEBUG_SG,
+ "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+ hostno, len, data);
+ }
+ break;
+
+ case REQ_DATAIN:
#ifdef SLOW_RATE
- if (borken)
- {
+ if (borken) {
#if (DEBUG & (PHASE_DATAIN))
- transfered += len;
+ transfered += len;
#endif
- for (;
- len && (STATUS & (REQ_MASK | STAT_REQ)) == (REQ_DATAIN |
- STAT_REQ)
- ; --len)
- {
- *data++ = DATA;
- borken_wait ();
- }
+ for (;
+ len
+ && (STATUS & (REQ_MASK | STAT_REQ))
+ == (REQ_DATAIN | STAT_REQ);
+ --len) {
+ *data++ = DATA;
+ borken_wait ();
+ }
#if (DEBUG & (PHASE_DATAIN))
- transfered -= len;
+ transfered -= len;
#endif
- }
- else
+ } else
#endif
- if (fast && transfersize && !(len % transfersize) &&
- (len >= transfersize)
+ if (fast && transfersize
+ && !(len % transfersize)
+ && (len >= transfersize)
#ifdef FAST32
- && !(transfersize % 4)
+ && !(transfersize % 4)
#endif
- )
- {
- DPRINTK (DEBUG_FAST,
- "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
- " len = %d, data = %08x\n",
- hostno, SCint->underflow, SCint->transfersize, len, data);
+ ) {
+ DPRINTK (DEBUG_FAST,
+ "scsi%d : FAST transfer, underflow = %d, transfersize = %d\n"
+ " len = %d, data = %08x\n",
+ hostno, SCint->underflow,
+ SCint->transfersize, len,
+ data);
/* SJT: Start. Fast Read */
#ifdef SEAGATE_USE_ASM
- __asm__(
- "cld\n\t"
+ __asm__ ("cld\n\t"
#ifdef FAST32
- "shr $2, %%ecx\n\t"
- "1:\t"
- "movl (%%esi), %%eax\n\t"
- "stosl\n\t"
+ "shr $2, %%ecx\n\t"
+ "1:\t"
+ "movl (%%esi), %%eax\n\t"
+ "stosl\n\t"
#else
- "1:\t"
- "movb (%%esi), %%al\n\t"
- "stosb\n\t"
+ "1:\t"
+ "movb (%%esi), %%al\n\t"
+ "stosb\n\t"
#endif
- "loop 1b\n\t"
-/* output */ :
-/* input */ : "S" (phys_to_virt(st0x_dr)), "D" (data), "c" (SCint->transfersize)
-/* clobbered */ : "eax", "ecx", "edi");
-#else /* SEAGATE_USE_ASM */
- {
+ "loop 1b\n\t"
+ /* output */ :
+ /* input */ :"S" (phys_to_virt (st0x_dr)),
+ "D"
+ (data),
+ "c" (SCint->transfersize)
+/* clobbered */
+ : "eax", "ecx",
+ "edi");
+#else /* SEAGATE_USE_ASM */
+ {
#ifdef FAST32
- const unsigned int *iop = phys_to_virt (st0x_dr);
- unsigned int *dp = (unsigned int *) data;
- int xferlen = len >> 2;
+ const unsigned int *iop =
+ phys_to_virt (st0x_dr);
+ unsigned int *dp =
+ (unsigned int *) data;
+ int xferlen = len >> 2;
#else
- const unsigned char *iop = phys_to_virt (st0x_dr);
- unsigned char *dp = data;
- int xferlen = len;
+ const unsigned char *iop =
+ phys_to_virt (st0x_dr);
+ unsigned char *dp = data;
+ int xferlen = len;
#endif
- for (; xferlen; --xferlen)
- *dp++ = *iop;
- }
-#endif /* SEAGATE_USE_ASM */
+ for (; xferlen; --xferlen)
+ *dp++ = *iop;
+ }
+#endif /* SEAGATE_USE_ASM */
/* SJT: End */
- len -= transfersize;
- data += transfersize;
+ len -= transfersize;
+ data += transfersize;
#if (DEBUG & PHASE_DATAIN)
- printk ("scsi%d: transfered += %d\n", hostno, transfersize);
- transfered += transfersize;
+ printk ("scsi%d: transfered += %d\n",
+ hostno, transfersize);
+ transfered += transfersize;
#endif
- DPRINTK (DEBUG_FAST,
- "scsi%d : FAST transfer complete len = %d data = %08x\n",
- hostno, len, data);
- }
- else
- {
+ DPRINTK (DEBUG_FAST,
+ "scsi%d : FAST transfer complete len = %d data = %08x\n",
+ hostno, len, data);
+ } else {
#if (DEBUG & PHASE_DATAIN)
- printk ("scsi%d: transfered += %d\n", hostno, len);
- transfered += len; /* Assume we'll transfer it all, then
- subtract what we *didn't* transfer */
+ printk ("scsi%d: transfered += %d\n",
+ hostno, len);
+ transfered += len; /* Assume we'll transfer it all, then
+ subtract what we *didn't* transfer */
#endif
/*
- * We loop as long as we are in a data in phase, there is room to read,
+ * We loop as long as we are in a data in phase, there is room to read,
* and BSY is still active
*/
/* SJT: Start. */
#ifdef SEAGATE_USE_ASM
-int __dummy_3,__dummy_4;
+ int __dummy_3, __dummy_4;
/* Dummy clobbering variables for the new gcc-2.95 */
* We loop as long as we are in a data in phase, there is room to read,
* and BSY is still active
*/
- /* Local variables : ecx = len, edi = data
- esi = st0x_cr_sr, ebx = st0x_dr */
- __asm__ (
- /* Test for room to read */
- "orl %%ecx, %%ecx\n\t"
- "jz 2f\n\t"
- "cld\n\t"
+ /* Local variables : ecx = len, edi = data
+ esi = st0x_cr_sr, ebx = st0x_dr */
+ __asm__ (
+ /* Test for room to read */
+ "orl %%ecx, %%ecx\n\t"
+ "jz 2f\n\t" "cld\n\t"
/* "movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi\n\t" */
/* "movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx\n\t" */
- "1:\t"
- "movb (%%esi), %%al\n\t"
- /* Test for BSY */
- "test $1, %%al\n\t"
- "jz 2f\n\t"
- /* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN,
- = STAT_IO, which is 4. */
- "movb $0xe, %%ah\n\t"
- "andb %%al, %%ah\n\t"
- "cmpb $0x04, %%ah\n\t"
- "jne 2f\n\t"
- /* Test for REQ */
- "test $0x10, %%al\n\t"
- "jz 1b\n\t"
- "movb (%%ebx), %%al\n\t"
- "stosb\n\t"
- "loop 1b\n\t"
- "2:\n"
-/* output */ : "=D" (data), "=c" (len) ,"=S" (__dummy_3) ,"=b" (__dummy_4)
-/* input */ : "0" (data), "1" (len), "2" (phys_to_virt(st0x_cr_sr)), "3" (phys_to_virt(st0x_dr))
-/* clobbered */ : "eax" );
-#else /* SEAGATE_USE_ASM */
- while (len)
- {
- unsigned char stat;
-
- stat = STATUS;
- if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAIN))
- break;
- if (stat & STAT_REQ)
- {
- *data++ = DATA;
- --len;
- }
- }
-#endif /* SEAGATE_USE_ASM */
+ "1:\t"
+ "movb (%%esi), %%al\n\t"
+ /* Test for BSY */
+ "test $1, %%al\n\t"
+ "jz 2f\n\t"
+ /* Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN,
+ = STAT_IO, which is 4. */
+ "movb $0xe, %%ah\n\t"
+ "andb %%al, %%ah\n\t"
+ "cmpb $0x04, %%ah\n\t"
+ "jne 2f\n\t"
+ /* Test for REQ */
+ "test $0x10, %%al\n\t"
+ "jz 1b\n\t"
+ "movb (%%ebx), %%al\n\t"
+ "stosb\n\t"
+ "loop 1b\n\t" "2:\n"
+ /* output */ :"=D" (data), "=c" (len),
+ "=S"
+ (__dummy_3),
+ "=b" (__dummy_4)
+/* input */
+ : "0" (data), "1" (len),
+ "2" (phys_to_virt
+ (st0x_cr_sr)),
+ "3" (phys_to_virt
+ (st0x_dr))
+/* clobbered */
+ : "eax");
+#else /* SEAGATE_USE_ASM */
+ while (len) {
+ unsigned char stat;
+
+ stat = STATUS;
+ if (!(stat & STAT_BSY)
+ || ((stat & REQ_MASK) !=
+ REQ_DATAIN))
+ break;
+ if (stat & STAT_REQ) {
+ *data++ = DATA;
+ --len;
+ }
+ }
+#endif /* SEAGATE_USE_ASM */
/* SJT: End. */
#if (DEBUG & PHASE_DATAIN)
- printk ("scsi%d: transfered -= %d\n", hostno, len);
- transfered -= len; /* Since we assumed all of Len got *
- transfered, correct our mistake */
+ printk ("scsi%d: transfered -= %d\n",
+ hostno, len);
+ transfered -= len; /* Since we assumed all of Len got *
+ transfered, correct our mistake */
#endif
- }
-
- if (!len && nobuffs)
- {
- --nobuffs;
- ++buffer;
- len = buffer->length;
- data = (unsigned char *) buffer->address;
- DPRINTK (DEBUG_SG,
- "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
- hostno, len, data);
- }
-
- break;
-
- case REQ_CMDOUT:
- while (((status_read = STATUS) & STAT_BSY) &&
- ((status_read & REQ_MASK) == REQ_CMDOUT))
- if (status_read & STAT_REQ)
- {
- WRITE_DATA (*(const unsigned char *) cmnd);
- cmnd = 1 + (const unsigned char *) cmnd;
+ }
+
+ if (!len && nobuffs) {
+ --nobuffs;
+ ++buffer;
+ len = buffer->length;
+ data =
+ (unsigned char *) buffer->address;
+ DPRINTK (DEBUG_SG,
+ "scsi%d : next scatter-gather buffer len = %d address = %08x\n",
+ hostno, len, data);
+ }
+
+ break;
+
+ case REQ_CMDOUT:
+ while (((status_read = STATUS) & STAT_BSY) &&
+ ((status_read & REQ_MASK) == REQ_CMDOUT))
+ if (status_read & STAT_REQ) {
+ WRITE_DATA (*
+ (const unsigned char
+ *) cmnd);
+ cmnd =
+ 1 +
+ (const unsigned char *)
+ cmnd;
#ifdef SLOW_RATE
- if (borken)
- borken_wait ();
+ if (borken)
+ borken_wait ();
#endif
- }
- break;
+ }
+ break;
- case REQ_STATIN:
- status = DATA;
- break;
+ case REQ_STATIN:
+ status = DATA;
+ break;
- case REQ_MSGOUT:
+ case REQ_MSGOUT:
/*
- * We can only have sent a MSG OUT if we requested to do this
+ * We can only have sent a MSG OUT if we requested to do this
* by raising ATTN. So, we must drop ATTN.
*/
- WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);
+ WRITE_CONTROL (BASE_CMD | CMD_DRVR_ENABLE);
/*
- * If we are reconnecting, then we must send an IDENTIFY message in
- * response to MSGOUT.
+ * If we are reconnecting, then we must send an IDENTIFY message in
+ * response to MSGOUT.
*/
- switch (reselect)
- {
- case CAN_RECONNECT:
- WRITE_DATA (IDENTIFY (1, lun));
-
- DPRINTK (PHASE_RESELECT | PHASE_MSGOUT, "scsi%d : sent IDENTIFY message.\n", hostno);
- break;
+ switch (reselect) {
+ case CAN_RECONNECT:
+ WRITE_DATA (IDENTIFY (1, lun));
+
+ DPRINTK (PHASE_RESELECT | PHASE_MSGOUT,
+ "scsi%d : sent IDENTIFY message.\n",
+ hostno);
+ break;
#ifdef LINKED
- case LINKED_WRONG:
- WRITE_DATA (ABORT);
- linked_connected = 0;
- reselect = CAN_RECONNECT;
- goto connect_loop;
- DPRINTK (PHASE_MSGOUT | DEBUG_LINKED,
- "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n", hostno);
-#endif /* LINKED */
- DPRINTK (DEBUG_LINKED, "correct\n");
- default:
- WRITE_DATA (NOP);
- printk ("scsi%d : target %d requested MSGOUT, sent NOP message.\n", hostno, target);
- }
- break;
-
- case REQ_MSGIN:
- switch (message = DATA)
- {
- case DISCONNECT:
- DANY ("seagate: deciding to disconnect\n");
- should_reconnect = 1;
- current_data = data; /* WDE add */
- current_buffer = buffer;
- current_bufflen = len; /* WDE add */
- current_nobuffs = nobuffs;
+ case LINKED_WRONG:
+ WRITE_DATA (ABORT);
+ linked_connected = 0;
+ reselect = CAN_RECONNECT;
+ goto connect_loop;
+ DPRINTK (PHASE_MSGOUT | DEBUG_LINKED,
+ "scsi%d : sent ABORT message to cancel incorrect I_T_L nexus.\n",
+ hostno);
+#endif /* LINKED */
+ DPRINTK (DEBUG_LINKED, "correct\n");
+ default:
+ WRITE_DATA (NOP);
+ printk
+ ("scsi%d : target %d requested MSGOUT, sent NOP message.\n",
+ hostno, target);
+ }
+ break;
+
+ case REQ_MSGIN:
+ switch (message = DATA) {
+ case DISCONNECT:
+ DANY ("seagate: deciding to disconnect\n");
+ should_reconnect = 1;
+ current_data = data; /* WDE add */
+ current_buffer = buffer;
+ current_bufflen = len; /* WDE add */
+ current_nobuffs = nobuffs;
#ifdef LINKED
- linked_connected = 0;
+ linked_connected = 0;
#endif
- done = 1;
- DPRINTK ((PHASE_RESELECT | PHASE_MSGIN), "scsi%d : disconnected.\n", hostno);
- break;
+ done = 1;
+ DPRINTK ((PHASE_RESELECT | PHASE_MSGIN),
+ "scsi%d : disconnected.\n",
+ hostno);
+ break;
#ifdef LINKED
- case LINKED_CMD_COMPLETE:
- case LINKED_FLG_CMD_COMPLETE:
+ case LINKED_CMD_COMPLETE:
+ case LINKED_FLG_CMD_COMPLETE:
#endif
- case COMMAND_COMPLETE:
+ case COMMAND_COMPLETE:
/*
* Note : we should check for underflow here.
*/
- DPRINTK (PHASE_MSGIN, "scsi%d : command complete.\n", hostno);
- done = 1;
- break;
- case ABORT:
- DPRINTK (PHASE_MSGIN, "scsi%d : abort message.\n", hostno);
- done = 1;
- break;
- case SAVE_POINTERS:
- current_buffer = buffer;
- current_bufflen = len; /* WDE add */
- current_data = data; /* WDE mod */
- current_nobuffs = nobuffs;
- DPRINTK (PHASE_MSGIN, "scsi%d : pointers saved.\n", hostno);
- break;
- case RESTORE_POINTERS:
- buffer = current_buffer;
- cmnd = current_cmnd;
- data = current_data; /* WDE mod */
- len = current_bufflen;
- nobuffs = current_nobuffs;
- DPRINTK (PHASE_MSGIN, "scsi%d : pointers restored.\n", hostno);
- break;
- default:
+ DPRINTK (PHASE_MSGIN,
+ "scsi%d : command complete.\n",
+ hostno);
+ done = 1;
+ break;
+ case ABORT:
+ DPRINTK (PHASE_MSGIN,
+ "scsi%d : abort message.\n",
+ hostno);
+ done = 1;
+ break;
+ case SAVE_POINTERS:
+ current_buffer = buffer;
+ current_bufflen = len; /* WDE add */
+ current_data = data; /* WDE mod */
+ current_nobuffs = nobuffs;
+ DPRINTK (PHASE_MSGIN,
+ "scsi%d : pointers saved.\n",
+ hostno);
+ break;
+ case RESTORE_POINTERS:
+ buffer = current_buffer;
+ cmnd = current_cmnd;
+ data = current_data; /* WDE mod */
+ len = current_bufflen;
+ nobuffs = current_nobuffs;
+ DPRINTK (PHASE_MSGIN,
+ "scsi%d : pointers restored.\n",
+ hostno);
+ break;
+ default:
/*
- * IDENTIFY distinguishes itself from the other messages by setting the
+ * IDENTIFY distinguishes itself from the other messages by setting the
* high byte. [FIXME: should not this read "the high bit"? - pavel@ucw.cz]
*
* Note : we need to handle at least one outstanding command per LUN,
* known ID (at this point) and LUN.
*/
- if (message & 0x80)
- {
- DPRINTK (PHASE_MSGIN, "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
- hostno, target, message & 7);
- }
- else
- {
+ if (message & 0x80) {
+ DPRINTK (PHASE_MSGIN,
+ "scsi%d : IDENTIFY message received from id %d, lun %d.\n",
+ hostno, target,
+ message & 7);
+ } else {
/*
* We should go into a MESSAGE OUT phase, and send a MESSAGE_REJECT
* needs some serious restructuring first though.
*/
- DPRINTK (PHASE_MSGIN,
- "scsi%d : unknown message %d from target %d.\n", hostno, message, target);
- }
- }
- break;
+ DPRINTK (PHASE_MSGIN,
+ "scsi%d : unknown message %d from target %d.\n",
+ hostno, message,
+ target);
+ }
+ }
+ break;
- default:
- printk ("scsi%d : unknown phase.\n", hostno);
- st0x_aborted = DID_ERROR;
- } /* end of switch (status_read &
- REQ_MASK) */
+ default:
+ printk ("scsi%d : unknown phase.\n", hostno);
+ st0x_aborted = DID_ERROR;
+ } /* end of switch (status_read &
+ REQ_MASK) */
#ifdef SLOW_RATE
/*
* byte transfer case (ie, message in, message out, status), so
* I'll do the wait here if necessary.
*/
- if (borken)
- borken_wait ();
+ if (borken)
+ borken_wait ();
#endif
- } /* if(status_read & STAT_REQ) ends */
- } /* while(((status_read = STATUS)...)
- ends */
+ } /* if(status_read & STAT_REQ) ends */
+ } /* while(((status_read = STATUS)...)
+ ends */
- DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT,
- "scsi%d : Transfered %d bytes\n", hostno, transfered);
+ DPRINTK (PHASE_DATAIN | PHASE_DATAOUT | PHASE_EXIT,
+ "scsi%d : Transfered %d bytes\n", hostno, transfered);
#if (DEBUG & PHASE_EXIT)
-#if 0 /* Doesn't work for scatter/gather */
- printk ("Buffer : \n");
- for (i = 0; i < 20; ++i)
- printk ("%02x ", ((unsigned char *) data)[i]); /* WDE mod */
- printk ("\n");
+#if 0 /* Doesn't work for scatter/gather */
+ printk ("Buffer : \n");
+ for (i = 0; i < 20; ++i)
+ printk ("%02x ", ((unsigned char *) data)[i]); /* WDE mod */
+ printk ("\n");
#endif
- printk ("scsi%d : status = ", hostno);
- print_status (status);
- printk ("message = %02x\n", message);
+ printk ("scsi%d : status = ", hostno);
+ print_status (status);
+ printk ("message = %02x\n", message);
#endif
/* We shouldn't reach this until *after* BSY has been deasserted */
#ifdef LINKED
- else
- {
+ else
+ {
/*
* Fix the message byte so that unsuspecting high level drivers don't
* puke when they see a LINKED COMMAND message in place of the COMMAND
* and we are now disconnected.
*/
- switch (message)
- {
- case LINKED_CMD_COMPLETE:
- case LINKED_FLG_CMD_COMPLETE:
- message = COMMAND_COMPLETE;
- linked_target = current_target;
- linked_lun = current_lun;
- linked_connected = 1;
- DPRINTK (DEBUG_LINKED, "scsi%d : keeping I_T_L nexus established"
- "for linked command.\n", hostno);
- /* We also will need to adjust status to accommodate intermediate
- conditions. */
- if ((status == INTERMEDIATE_GOOD) ||
- (status == INTERMEDIATE_C_GOOD))
- status = GOOD;
-
- break;
+ switch (message) {
+ case LINKED_CMD_COMPLETE:
+ case LINKED_FLG_CMD_COMPLETE:
+ message = COMMAND_COMPLETE;
+ linked_target = current_target;
+ linked_lun = current_lun;
+ linked_connected = 1;
+ DPRINTK (DEBUG_LINKED,
+ "scsi%d : keeping I_T_L nexus established"
+ "for linked command.\n", hostno);
+ /* We also will need to adjust status to accommodate intermediate
+ conditions. */
+ if ((status == INTERMEDIATE_GOOD) ||
+ (status == INTERMEDIATE_C_GOOD))
+ status = GOOD;
+
+ break;
/*
* We should also handle what are "normal" termination messages
* here (ABORT, BUS_DEVICE_RESET?, and COMMAND_COMPLETE individually,
* and flake if things aren't right.
*/
- default:
- DPRINTK (DEBUG_LINKED, "scsi%d : closing I_T_L nexus.\n", hostno);
- linked_connected = 0;
- }
- }
-#endif /* LINKED */
-
- if (should_reconnect)
- {
- DPRINTK (PHASE_RESELECT, "scsi%d : exiting seagate_st0x_queue_command()"
- "with reconnect enabled.\n", hostno);
- WRITE_CONTROL (BASE_CMD | CMD_INTR);
- }
- else
- WRITE_CONTROL (BASE_CMD);
-
- return retcode (st0x_aborted);
-} /* end of internal_command */
-
-int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
+ default:
+ DPRINTK (DEBUG_LINKED,
+ "scsi%d : closing I_T_L nexus.\n", hostno);
+ linked_connected = 0;
+ }
+ }
+#endif /* LINKED */
+
+ if (should_reconnect) {
+ DPRINTK (PHASE_RESELECT,
+ "scsi%d : exiting seagate_st0x_queue_command()"
+ "with reconnect enabled.\n", hostno);
+ WRITE_CONTROL (BASE_CMD | CMD_INTR);
+ } else
+ WRITE_CONTROL (BASE_CMD);
+
+ return retcode (st0x_aborted);
+} /* end of internal_command */
+
+static int seagate_st0x_abort (Scsi_Cmnd * SCpnt)
{
- st0x_aborted = DID_ABORT;
- return SCSI_ABORT_PENDING;
+ st0x_aborted = DID_ABORT;
+ return SCSI_ABORT_PENDING;
}
+
#undef ULOOP
#undef TIMEOUT
* the seagate_st0x_reset function resets the SCSI bus
*/
-int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+static int seagate_st0x_reset (Scsi_Cmnd * SCpnt, unsigned int reset_flags)
{
/* No timeouts - this command is going to fail because it was reset. */
- DANY ("scsi%d: Reseting bus... ", hostno );
+ DANY ("scsi%d: Reseting bus... ", hostno);
/* assert RESET signal on SCSI bus. */
- WRITE_CONTROL (BASE_CMD | CMD_RST);
+ WRITE_CONTROL (BASE_CMD | CMD_RST);
- udelay( 20*1000 );
+ udelay (20 * 1000);
- WRITE_CONTROL (BASE_CMD);
- st0x_aborted = DID_RESET;
+ WRITE_CONTROL (BASE_CMD);
+ st0x_aborted = DID_RESET;
- DANY ("done.\n");
- return SCSI_RESET_WAKEUP;
+ DANY ("done.\n");
+ return SCSI_RESET_WAKEUP;
}
-
/* Eventually this will go into an include file, but this will be later */
static Scsi_Host_Template driver_template = SEAGATE_ST0X;
int seagate_st0x_command(Scsi_Cmnd *);
int seagate_st0x_queue_command(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-int seagate_st0x_abort(Scsi_Cmnd *);
+static int seagate_st0x_abort(Scsi_Cmnd *);
const char *seagate_st0x_info(struct Scsi_Host *);
-int seagate_st0x_reset(Scsi_Cmnd *, unsigned int);
+static int seagate_st0x_reset(Scsi_Cmnd *, unsigned int);
#define SEAGATE_ST0X { detect: seagate_st0x_detect, \
info: seagate_st0x_info, \
*/
#include <linux/config.h>
#ifdef CONFIG_PROC_FS
- static char sg_version_str[] = "Version: 3.1.19 (20010623)";
+ static char sg_version_str[] = "Version: 3.1.20 (20010814)";
#endif
- static int sg_version_num = 30119; /* 2 digits for each component */
+ static int sg_version_num = 30120; /* 2 digits for each component */
/*
* D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
* - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
/* Prevent the device driver from vanishing while we sleep */
if (sdp->device->host->hostt->module)
__MOD_INC_USE_COUNT(sdp->device->host->hostt->module);
+ sdp->device->access_count++;
if (! ((flags & O_NONBLOCK) ||
scsi_block_when_processing_errors(sdp->device))) {
return 0;
error_out:
+ sdp->device->access_count--;
if ((! sdp->detached) && sdp->device->host->hostt->module)
__MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
return retval;
SCSI_LOG_TIMEOUT(3, printk("sg_release: dev=%d\n", MINOR(sdp->i_rdev)));
sg_fasync(-1, filp, 0); /* remove filp from async notification list */
if (0 == sg_remove_sfp(sdp, sfp)) { /* Returns 1 when sdp gone */
- if ((! sdp->detached) && sdp->device->host->hostt->module)
- __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+ if (! sdp->detached) {
+ sdp->device->access_count--;
+ if (sdp->device->host->hostt->module)
+ __MOD_DEC_USE_COUNT(sdp->device->host->hostt->module);
+ }
sdp->exclude = 0;
wake_up_interruptible(&sdp->o_excl_wait);
}
return 0;
case SG_GET_VERSION_NUM:
return put_user(sg_version_num, (int *)arg);
+ case SG_GET_ACCESS_COUNT:
+ val = (sdp->device ? sdp->device->access_count : 0);
+ return put_user(val, (int *)arg);
case SG_GET_REQUEST_TABLE:
result = verify_area(VERIFY_WRITE, (void *) arg,
SZ_SG_REQ_INFO * SG_MAX_QUEUE);
sg_remove_sfp(sdp, sfp);
sfp = NULL;
}
+ sdp->device->access_count--;
if (sg_template.module)
__MOD_DEC_USE_COUNT(sg_template.module);
if (sdp->device->host->hostt->module)
for(k = 0; k < sg_template.dev_max; k++)
if(! sg_dev_arr[k]) break;
+ if (k > MINORMASK) {
+ scsidp->attached--;
+ write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
+ printk("Unable to attach sg device <%d, %d, %d, %d>"
+ " type=%d, minor number exceed %d\n", scsidp->host->host_no,
+ scsidp->channel, scsidp->id, scsidp->lun, scsidp->type,
+ MINORMASK);
+ return 1;
+ }
if(k < sg_template.dev_max)
sdp = (Sg_device *)kmalloc(sizeof(Sg_device), GFP_ATOMIC);
else
sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,
SCSI_GENERIC_MAJOR, k,
S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
- &sg_fops, NULL);
+ &sg_fops, sdp);
sg_template.nr_dev++;
sg_dev_arr[k] = sdp;
write_unlock_irqrestore(&sg_dev_arr_lock, iflags);
sg_finish_rem_req(srp);
}
if (sfp->closed) {
+ sdp->device->access_count--;
if (sg_template.module)
__MOD_DEC_USE_COUNT(sg_template.module);
if (sdp->device->host->hostt->module)
}
else {
sfp->closed = 1; /* flag dirty state on this fd */
+ sdp->device->access_count++;
/* MOD_INC's to inhibit unloading sg and associated adapter driver */
if (sg_template.module)
__MOD_INC_USE_COUNT(sg_template.module);
static int sg_proc_devhdr_info(char * buffer, int * len, off_t * begin,
off_t offset, int size)
{
- PRINT_PROC("host\tchan\tid\tlun\ttype\tbopens\tqdepth\tbusy\tonline\n");
+ PRINT_PROC("host\tchan\tid\tlun\ttype\topens\tqdepth\tbusy\tonline\n");
return 1;
}
if [ "$CONFIG_VISWS" = "y" ]; then
dep_tristate ' SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
fi
+if [ "$CONFIG_DDB5477" = "y" ]; then
+ dep_tristate ' NEC Vrc5477 AC97 sound' CONFIG_SOUND_VRC5477 $CONFIG_SOUND
+fi
dep_tristate ' Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core' CONFIG_SOUND_TRIDENT $CONFIG_SOUND
dep_tristate ' Support for Turtle Beach MultiSound Classic, Tahiti, Monterey' CONFIG_SOUND_MSNDCLAS $CONFIG_SOUND
#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_DAC_RATE 0x0032 /* PCM LR DAC Rate */
+#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR DAC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
{0x41445303, "Analog Devices AD1819", &null_ops},
{0x41445340, "Analog Devices AD1881", &null_ops},
{0x41445348, "Analog Devices AD1881A", &null_ops},
+ {0x41445360, "Analog Devices AD1885", &default_ops},
{0x41445460, "Analog Devices AD1885", &default_ops},
{0x414B4D00, "Asahi Kasei AK4540", &null_ops},
{0x414B4D01, "Asahi Kasei AK4542", &null_ops},
EXPORT_SYMBOL(ac97_read_proc);
EXPORT_SYMBOL(ac97_probe_codec);
+
+/*
+ * AC97 library support routines
+ */
+
+/**
+ * ac97_set_dac_rate - set codec rate adaption
+ * @codec: ac97 code
+ * @rate: rate in hertz
+ *
+ * Set the DAC rate. Assumes the codec supports VRA. The caller is
+ * expected to have checked this little detail.
+ */
+
+unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate)
+{
+ unsigned int new_rate = rate;
+ u32 dacp;
+ u32 mast_vol, phone_vol, mono_vol, pcm_vol;
+ u32 mute_vol = 0x8000; /* The mute volume? */
+
+ if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE))
+ {
+ /* Mute several registers */
+ mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
+ mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
+ phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
+ pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
+ codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
+ codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
+ codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
+
+ /* Power down the DAC */
+ dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
+ /* Power it back up */
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+
+ /* Restore volumes */
+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
+ codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
+ codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
+ codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
+ }
+ return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_dac_rate);
+
+/**
+ * ac97_set_adc_rate - set codec rate adaption
+ * @codec: ac97 code
+ * @rate: rate in hertz
+ *
+ * Set the ADC rate. Assumes the codec supports VRA. The caller is
+ * expected to have checked this little detail.
+ */
+
+unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
+{
+ unsigned int new_rate = rate;
+ u32 dacp;
+
+ if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE))
+ {
+ /* Power down the ADC */
+ dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100);
+ /* Load the rate and read the effective rate */
+ codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
+ new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
+ /* Power it back up */
+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
+ }
+ return new_rate;
+}
+
+EXPORT_SYMBOL(ac97_set_adc_rate);
* Christoph Hellwig : adapted to module_init/module_exit
* Aki Laukkanen : added power management support
* Arnaldo C. de Melo : added missing restore_flags in ad1848_resume
+ * Miguel Freitas : added ISA PnP support
*
* Status:
* Tested. Believed fully functional.
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/pm.h>
+#include <linux/isapnp.h>
#define DEB(x)
#define DEB1(x)
,{CAP_F_TIMER} /* MD_1845_SSCAPE */
};
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+static int isapnp = 1;
+static int isapnpjump = 0;
+static int reverse = 0;
+
+static int audio_activated = 0;
+#else
+static int isapnp = 0;
+#endif
+
+
+
static int ad1848_open(int dev, int mode);
static void ad1848_close(int dev);
static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag);
MODULE_PARM(dma, "i"); /* First DMA channel */
MODULE_PARM(dma2, "i"); /* Second DMA channel */
MODULE_PARM(type, "i"); /* Card type */
-MODULE_PARM(deskpro_xl, "i"); /* Special magic for Deskpro XL boxen
-*/
+MODULE_PARM(deskpro_xl, "i"); /* Special magic for Deskpro XL boxen */
MODULE_PARM(deskpro_m, "i"); /* Special magic for Deskpro M box */
-MODULE_PARM(soundpro, "i"); /* More special magic for SoundPro
-chips */
+MODULE_PARM(soundpro, "i"); /* More special magic for SoundPro chips */
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+MODULE_PARM(isapnp, "i");
+MODULE_PARM(isapnpjump, "i");
+MODULE_PARM(reverse, "i");
+MODULE_PARM_DESC(isapnp, "When set to 0, Plug & Play support will be disabled");
+MODULE_PARM_DESC(isapnpjump, "Jumps to a specific slot in the driver's PnP table. Use the source, Luke.");
+MODULE_PARM_DESC(reverse, "When set to 1, will reverse ISAPnP search order");
+
+struct pci_dev *ad1848_dev = NULL;
+
+/* Please add new entries at the end of the table */
+static struct {
+ char *name;
+ unsigned short card_vendor, card_device,
+ vendor, function;
+ short mss_io, irq, dma, dma2; /* index into isapnp table */
+ int type;
+} ad1848_isapnp_list[] __initdata = {
+ {"CMI 8330 SoundPRO",
+ ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
+ ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001),
+ 0, 0, 0,-1, 0},
+ {"CS4232 based card",
+ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000),
+ 0, 0, 0, 1, 0},
+ {"CS4232 based card",
+ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100),
+ 0, 0, 0, 1, 0},
+ {"OPL3-SA2 WSS mode",
+ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),
+ 1, 0, 0, 1, 1},
+ {0}
+};
+
+static struct isapnp_device_id id_table[] __devinitdata = {
+ { ISAPNP_VENDOR('C','M','I'), ISAPNP_DEVICE(0x0001),
+ ISAPNP_VENDOR('@','@','@'), ISAPNP_FUNCTION(0x0001), 0 },
+ { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0000), 0 },
+ { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('C','S','C'), ISAPNP_FUNCTION(0x0100), 0 },
+ { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021), 0 },
+ {0}
+};
+
+MODULE_DEVICE_TABLE(isapnp, id_table);
+
+static struct pci_dev *activate_dev(char *devname, char *resname, struct pci_dev *dev)
+{
+ int err;
+
+ /* Device already active? Let's use it */
+ if(dev->active)
+ return(dev);
+
+ if((err = dev->activate(dev)) < 0) {
+ printk(KERN_ERR "ad1848: %s %s config failed (out of resources?)[%d]\n", devname, resname, err);
+
+ dev->deactivate(dev);
+
+ return(NULL);
+ }
+ return(dev);
+}
+
+static struct pci_dev *ad1848_init_generic(struct pci_bus *bus, struct address_info *hw_config, int slot)
+{
+
+ /* Configure Audio device */
+ if((ad1848_dev = isapnp_find_dev(bus, ad1848_isapnp_list[slot].vendor, ad1848_isapnp_list[slot].function, NULL)))
+ {
+ int ret;
+ ret = ad1848_dev->prepare(ad1848_dev);
+ /* If device is active, assume configured with /proc/isapnp
+ * and use anyway. Some other way to check this? */
+ if(ret && ret != -EBUSY) {
+ printk(KERN_ERR "ad1848: ISAPnP found device that could not be autoconfigured.\n");
+ return(NULL);
+ }
+ if(ret == -EBUSY)
+ audio_activated = 1;
+
+ if((ad1848_dev = activate_dev(ad1848_isapnp_list[slot].name, "ad1848", ad1848_dev)))
+ {
+ hw_config->io_base = ad1848_dev->resource[ad1848_isapnp_list[slot].mss_io].start;
+ hw_config->irq = ad1848_dev->irq_resource[ad1848_isapnp_list[slot].irq].start;
+ hw_config->dma = ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma].start;
+ if(ad1848_isapnp_list[slot].dma2 != -1)
+ hw_config->dma2 = ad1848_dev->dma_resource[ad1848_isapnp_list[slot].dma2].start;
+ else
+ hw_config->dma2 = -1;
+ hw_config->card_subtype = ad1848_isapnp_list[slot].type;
+ } else
+ return(NULL);
+ } else
+ return(NULL);
+
+ return(ad1848_dev);
+}
+
+static int __init ad1848_isapnp_init(struct address_info *hw_config, struct pci_bus *bus, int slot)
+{
+ char *busname = bus->name[0] ? bus->name : ad1848_isapnp_list[slot].name;
+
+ printk(KERN_INFO "ad1848: %s detected\n", busname);
+
+ /* Initialize this baby. */
+
+ if(ad1848_init_generic(bus, hw_config, slot)) {
+ /* We got it. */
+
+ printk(KERN_NOTICE "ad1848: ISAPnP reports '%s' at i/o %#x, irq %d, dma %d, %d\n",
+ busname,
+ hw_config->io_base, hw_config->irq, hw_config->dma,
+ hw_config->dma2);
+ return 1;
+ }
+ else
+ printk(KERN_INFO "ad1848: Failed to initialize %s\n", busname);
+
+ return 0;
+}
+
+static int __init ad1848_isapnp_probe(struct address_info *hw_config)
+{
+ static int first = 1;
+ int i;
+
+ /* Count entries in sb_isapnp_list */
+ for (i = 0; ad1848_isapnp_list[i].card_vendor != 0; i++);
+ i--;
+
+ /* Check and adjust isapnpjump */
+ if( isapnpjump < 0 || isapnpjump > i) {
+ isapnpjump = reverse ? i : 0;
+ printk(KERN_ERR "ad1848: Valid range for isapnpjump is 0-%d. Adjusted to %d.\n", i, isapnpjump);
+ }
+
+ if(!first || !reverse)
+ i = isapnpjump;
+ first = 0;
+ while(ad1848_isapnp_list[i].card_vendor != 0) {
+ static struct pci_bus *bus = NULL;
+
+ while ((bus = isapnp_find_card(
+ ad1848_isapnp_list[i].card_vendor,
+ ad1848_isapnp_list[i].card_device,
+ bus))) {
+
+ if(ad1848_isapnp_init(hw_config, bus, i)) {
+ isapnpjump = i; /* start next search from here */
+ return 0;
+ }
+ }
+ i += reverse ? -1 : 1;
+ }
+
+ return -ENODEV;
+}
+#endif
+
static int __init init_ad1848(void)
{
printk(KERN_INFO "ad1848/cs4248 codec driver Copyright (C) by Hannu Savolainen 1993-1996\n");
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+ if(isapnp && (ad1848_isapnp_probe(&cfg) < 0) ) {
+ printk(KERN_NOTICE "ad1848: No ISAPnP cards found, trying standard ones...\n");
+ isapnp = 0;
+ }
+#endif
+
if(io != -1) {
- if(irq == -1 || dma == -1) {
- printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
- return -EINVAL;
- }
+ if( isapnp == 0 )
+ {
+ if(irq == -1 || dma == -1) {
+ printk(KERN_WARNING "ad1848: must give I/O , IRQ and DMA.\n");
+ return -EINVAL;
+ }
- cfg.irq = irq;
- cfg.io_base = io;
- cfg.dma = dma;
- cfg.dma2 = dma2;
- cfg.card_subtype = type;
+ cfg.irq = irq;
+ cfg.io_base = io;
+ cfg.dma = dma;
+ cfg.dma2 = dma2;
+ cfg.card_subtype = type;
+ }
if(!probe_ms_sound(&cfg))
return -ENODEV;
attach_ms_sound(&cfg, THIS_MODULE);
loaded = 1;
}
-
return 0;
}
{
if(loaded)
unload_ms_sound(&cfg);
+
+#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE
+ if(audio_activated)
+ if(ad1848_dev)
+ ad1848_dev->deactivate(ad1848_dev);
+#endif
}
module_init(init_ad1848);
* was calling prog_dmabuf with s->lock held, call missing
* unlock_kernel in cm_midi_release
*
- * Fri May 25 2001 - Carlos Eduardo Gorges <carlos@techlinux.com.br>
- * - some driver cleanups
- * - spin[un]lock* revision ( fix SMP support )
- * - cosmetic code changes
+ * Carlos Eduardo Gorges <carlos@techlinux.com.br>
+ * Fri May 25 2001
+ * - SMP support ( spin[un]lock* revision )
+ * - speaker mixer support
+ * Mon Aug 13 2001
+ * - optimizations and cleanups
*
*/
-
/*****************************************************************************/
#include <linux/version.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardirq.h>
+#include <linux/bitops.h>
#include "dm.h"
/* --------------------------------------------------------------------- */
-
#undef OSS_DOCUMENTED_MIXER_SEMANTICS
-
+#undef DMABYTEIO
/* --------------------------------------------------------------------- */
-#ifndef PCI_VENDOR_ID_CMEDIA
-#define PCI_VENDOR_ID_CMEDIA 0x13F6
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338A
-#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8338B
-#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738
-#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111
-#endif
-#ifndef PCI_DEVICE_ID_CMEDIA_CM8738B
-#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112
-#endif
-
#define CM_MAGIC ((PCI_VENDOR_ID_CMEDIA<<16)|PCI_DEVICE_ID_CMEDIA_CM8338A)
-/*
- * CM8338 registers definition
- */
-
-#define CODEC_CMI_FUNCTRL0 (0x00)
-#define CODEC_CMI_FUNCTRL1 (0x04)
-#define CODEC_CMI_CHFORMAT (0x08)
-#define CODEC_CMI_INT_HLDCLR (0x0C)
-#define CODEC_CMI_INT_STATUS (0x10)
-#define CODEC_CMI_LEGACY_CTRL (0x14)
-#define CODEC_CMI_MISC_CTRL (0x18)
-#define CODEC_CMI_TDMA_POS (0x1C)
-#define CODEC_CMI_MIXER (0x20)
-#define CODEC_SB16_DATA (0x22)
-#define CODEC_SB16_ADDR (0x23)
-#define CODEC_CMI_MIXER1 (0x24)
-#define CODEC_CMI_MIXER2 (0x25)
-#define CODEC_CMI_AUX_VOL (0x26)
-#define CODEC_CMI_MISC (0x27)
-#define CODEC_CMI_AC97 (0x28)
-
-#define CODEC_CMI_CH0_FRAME1 (0x80)
-#define CODEC_CMI_CH0_FRAME2 (0x84)
-#define CODEC_CMI_CH1_FRAME1 (0x88)
-#define CODEC_CMI_CH1_FRAME2 (0x8C)
-
-#define CODEC_CMI_EXT_REG (0xF0)
-#define UCHAR unsigned char
-/*
-** Mixer registers for SB16
-*/
-
-#define DSP_MIX_DATARESETIDX ((UCHAR)(0x00))
-
-#define DSP_MIX_MASTERVOLIDX_L ((UCHAR)(0x30))
-#define DSP_MIX_MASTERVOLIDX_R ((UCHAR)(0x31))
-#define DSP_MIX_VOICEVOLIDX_L ((UCHAR)(0x32))
-#define DSP_MIX_VOICEVOLIDX_R ((UCHAR)(0x33))
-#define DSP_MIX_FMVOLIDX_L ((UCHAR)(0x34))
-#define DSP_MIX_FMVOLIDX_R ((UCHAR)(0x35))
-#define DSP_MIX_CDVOLIDX_L ((UCHAR)(0x36))
-#define DSP_MIX_CDVOLIDX_R ((UCHAR)(0x37))
-#define DSP_MIX_LINEVOLIDX_L ((UCHAR)(0x38))
-#define DSP_MIX_LINEVOLIDX_R ((UCHAR)(0x39))
-
-#define DSP_MIX_MICVOLIDX ((UCHAR)(0x3A))
-#define DSP_MIX_SPKRVOLIDX ((UCHAR)(0x3B))
-
-#define DSP_MIX_OUTMIXIDX ((UCHAR)(0x3C))
-
-#define DSP_MIX_ADCMIXIDX_L ((UCHAR)(0x3D))
-#define DSP_MIX_ADCMIXIDX_R ((UCHAR)(0x3E))
-
-#define DSP_MIX_INGAINIDX_L ((UCHAR)(0x3F))
-#define DSP_MIX_INGAINIDX_R ((UCHAR)(0x40))
-#define DSP_MIX_OUTGAINIDX_L ((UCHAR)(0x41))
-#define DSP_MIX_OUTGAINIDX_R ((UCHAR)(0x42))
-
-#define DSP_MIX_AGCIDX ((UCHAR)(0x43))
-
-#define DSP_MIX_TREBLEIDX_L ((UCHAR)(0x44))
-#define DSP_MIX_TREBLEIDX_R ((UCHAR)(0x45))
-#define DSP_MIX_BASSIDX_L ((UCHAR)(0x46))
-#define DSP_MIX_BASSIDX_R ((UCHAR)(0x47))
-#define CM_CH0_RESET 0x04
-#define CM_CH1_RESET 0x08
-#define CM_EXTENT_CODEC 0x100
-#define CM_EXTENT_MIDI 0x2
-#define CM_EXTENT_SYNTH 0x4
-#define CM_INT_CH0 1
-#define CM_INT_CH1 2
-
-#define CM_CFMT_STEREO 0x01
-#define CM_CFMT_16BIT 0x02
-#define CM_CFMT_MASK 0x03
-#define CM_CFMT_DACSHIFT 2
-#define CM_CFMT_ADCSHIFT 0
-
-static const unsigned sample_size[] = { 1, 2, 2, 4 };
-static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+/* CM8338 registers definition ****************/
+
+#define CODEC_CMI_FUNCTRL0 (0x00)
+#define CODEC_CMI_FUNCTRL1 (0x04)
+#define CODEC_CMI_CHFORMAT (0x08)
+#define CODEC_CMI_INT_HLDCLR (0x0C)
+#define CODEC_CMI_INT_STATUS (0x10)
+#define CODEC_CMI_LEGACY_CTRL (0x14)
+#define CODEC_CMI_MISC_CTRL (0x18)
+#define CODEC_CMI_TDMA_POS (0x1C)
+#define CODEC_CMI_MIXER (0x20)
+#define CODEC_SB16_DATA (0x22)
+#define CODEC_SB16_ADDR (0x23)
+#define CODEC_CMI_MIXER1 (0x24)
+#define CODEC_CMI_MIXER2 (0x25)
+#define CODEC_CMI_AUX_VOL (0x26)
+#define CODEC_CMI_MISC (0x27)
+#define CODEC_CMI_AC97 (0x28)
+
+#define CODEC_CMI_CH0_FRAME1 (0x80)
+#define CODEC_CMI_CH0_FRAME2 (0x84)
+#define CODEC_CMI_CH1_FRAME1 (0x88)
+#define CODEC_CMI_CH1_FRAME2 (0x8C)
+
+#define CODEC_CMI_EXT_REG (0xF0)
+
+/* Mixer registers for SB16 ******************/
+
+#define DSP_MIX_DATARESETIDX ((unsigned char)(0x00))
+
+#define DSP_MIX_MASTERVOLIDX_L ((unsigned char)(0x30))
+#define DSP_MIX_MASTERVOLIDX_R ((unsigned char)(0x31))
+#define DSP_MIX_VOICEVOLIDX_L ((unsigned char)(0x32))
+#define DSP_MIX_VOICEVOLIDX_R ((unsigned char)(0x33))
+#define DSP_MIX_FMVOLIDX_L ((unsigned char)(0x34))
+#define DSP_MIX_FMVOLIDX_R ((unsigned char)(0x35))
+#define DSP_MIX_CDVOLIDX_L ((unsigned char)(0x36))
+#define DSP_MIX_CDVOLIDX_R ((unsigned char)(0x37))
+#define DSP_MIX_LINEVOLIDX_L ((unsigned char)(0x38))
+#define DSP_MIX_LINEVOLIDX_R ((unsigned char)(0x39))
+
+#define DSP_MIX_MICVOLIDX ((unsigned char)(0x3A))
+#define DSP_MIX_SPKRVOLIDX ((unsigned char)(0x3B))
+
+#define DSP_MIX_OUTMIXIDX ((unsigned char)(0x3C))
+
+#define DSP_MIX_ADCMIXIDX_L ((unsigned char)(0x3D))
+#define DSP_MIX_ADCMIXIDX_R ((unsigned char)(0x3E))
+
+#define DSP_MIX_INGAINIDX_L ((unsigned char)(0x3F))
+#define DSP_MIX_INGAINIDX_R ((unsigned char)(0x40))
+#define DSP_MIX_OUTGAINIDX_L ((unsigned char)(0x41))
+#define DSP_MIX_OUTGAINIDX_R ((unsigned char)(0x42))
+
+#define DSP_MIX_AGCIDX ((unsigned char)(0x43))
+
+#define DSP_MIX_TREBLEIDX_L ((unsigned char)(0x44))
+#define DSP_MIX_TREBLEIDX_R ((unsigned char)(0x45))
+#define DSP_MIX_BASSIDX_L ((unsigned char)(0x46))
+#define DSP_MIX_BASSIDX_R ((unsigned char)(0x47))
+
+#define CM_CH0_RESET 0x04
+#define CM_CH1_RESET 0x08
+#define CM_EXTENT_CODEC 0x100
+#define CM_EXTENT_MIDI 0x2
+#define CM_EXTENT_SYNTH 0x4
+#define CM_INT_CH0 1
+#define CM_INT_CH1 2
+
+#define CM_CFMT_STEREO 0x01
+#define CM_CFMT_16BIT 0x02
+#define CM_CFMT_MASK 0x03
+#define CM_CFMT_DACSHIFT 2
+#define CM_CFMT_ADCSHIFT 0
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
#define CM_ENABLE_CH1 0x2
#define CM_ENABLE_CH0 0x1
-
-/* MIDI buffer sizes */
+/* MIDI buffer sizes **************************/
#define MIDIINBUF 256
#define MIDIOUTBUF 256
#define SND_DEV_DSP16 5
-/* --------------------------------------------------------------------- */
+#define NR_DEVICE 3 /* maximum number of devices */
-struct cm_state {
- /* magic */
- unsigned int magic;
+/*********************************************/
- /* we keep cm cards in a linked list */
- struct cm_state *next;
+struct cm_state {
+ unsigned int magic; /* magic */
+ struct cm_state *next; /* we keep cm cards in a linked list */
- /* soundcore stuff */
- int dev_audio;
+ int dev_audio; /* soundcore stuff */
int dev_mixer;
int dev_midi;
int dev_dmfm;
- /* hardware resources */
- unsigned int iosb, iobase, iosynth, iomidi, iogame, irq;
- unsigned short deviceid;
+ unsigned int iosb, iobase, iosynth,
+ iomidi, iogame, irq; /* hardware resources */
+ unsigned short deviceid; /* pci_id */
- /* mixer stuff */
- struct {
+ struct { /* mixer stuff */
unsigned int modcnt;
-#ifndef OSS_DOCUMENTED_MIXER_SEMANTICS
unsigned short vol[13];
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
} mix;
- /* wave stuff */
- unsigned int rateadc, ratedac;
+ unsigned int rateadc, ratedac; /* wave stuff */
unsigned char fmt, enable;
spinlock_t lock;
unsigned hwptr, swptr;
unsigned total_bytes;
int count;
- unsigned error; /* over/underrun */
+ unsigned error; /* over/underrun */
wait_queue_head_t wait;
- /* redundant, but makes calculations easier */
- unsigned fragsize;
+
+ unsigned fragsize; /* redundant, but makes calculations easier */
unsigned dmasize;
unsigned fragsamples;
unsigned dmasamples;
- /* OSS stuff */
- unsigned mapped:1;
+
+ unsigned mapped:1; /* OSS stuff */
unsigned ready:1;
unsigned endcleared:1;
unsigned ossfragshift;
unsigned subdivision;
} dma_dac, dma_adc;
- /* midi stuff */
- struct {
+ struct { /* midi stuff */
unsigned ird, iwr, icnt;
unsigned ord, owr, ocnt;
wait_queue_head_t iwait;
unsigned char obuf[MIDIOUTBUF];
} midi;
- /* misc stuff */
- int chip_version;
+ int chip_version;
int max_channels;
- int curr_channels;
- int speakers; // number of speakers
- int capability; // HW capability, various for chip versions
- int status; // HW or SW state
+ int curr_channels;
+ int speakers; /* number of speakers */
+ int capability; /* HW capability, various for chip versions */
+
+ int status; /* HW or SW state */
- /* spdif frame counter */
- int spdif_counter;
+ int spdif_counter; /* spdif frame counter */
};
/* flags used for capability */
-#define CAN_AC3_HW 0x00000001 // 037 or later
-#define CAN_AC3_SW 0x00000002 // 033 or later
-#define CAN_AC3 (CAN_AC3_HW | CAN_AC3_SW)
-#define CAN_DUAL_DAC 0x00000004 // 033 or later
-#define CAN_MULTI_CH_HW 0x00000008 // 039 or later
-#define CAN_MULTI_CH (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
-#define CAN_LINE_AS_REAR 0x00000010 // 033 or later
-#define CAN_LINE_AS_BASS 0x00000020 // 039 or later
-#define CAN_MIC_AS_BASS 0x00000040 // 039 or later
+#define CAN_AC3_HW 0x00000001 /* 037 or later */
+#define CAN_AC3_SW 0x00000002 /* 033 or later */
+#define CAN_AC3 (CAN_AC3_HW | CAN_AC3_SW)
+#define CAN_DUAL_DAC 0x00000004 /* 033 or later */
+#define CAN_MULTI_CH_HW 0x00000008 /* 039 or later */
+#define CAN_MULTI_CH (CAN_MULTI_CH_HW | CAN_DUAL_DAC)
+#define CAN_LINE_AS_REAR 0x00000010 /* 033 or later */
+#define CAN_LINE_AS_BASS 0x00000020 /* 039 or later */
+#define CAN_MIC_AS_BASS 0x00000040 /* 039 or later */
/* flags used for status */
-#define DO_AC3_HW 0x00000001
-#define DO_AC3_SW 0x00000002
-#define DO_AC3 (DO_AC3_HW | DO_AC3_SW)
-#define DO_DUAL_DAC 0x00000004
-#define DO_MULTI_CH_HW 0x00000008
-#define DO_MULTI_CH (DO_MULTI_CH_HW | DO_DUAL_DAC)
-#define DO_LINE_AS_REAR 0x00000010 // 033 or later
-#define DO_LINE_AS_BASS 0x00000020 // 039 or later
-#define DO_MIC_AS_BASS 0x00000040 // 039 or later
-#define DO_SPDIF_OUT 0x00000100
-#define DO_SPDIF_IN 0x00000200
-#define DO_SPDIF_LOOP 0x00000400
-
-/* --------------------------------------------------------------------- */
+#define DO_AC3_HW 0x00000001
+#define DO_AC3_SW 0x00000002
+#define DO_AC3 (DO_AC3_HW | DO_AC3_SW)
+#define DO_DUAL_DAC 0x00000004
+#define DO_MULTI_CH_HW 0x00000008
+#define DO_MULTI_CH (DO_MULTI_CH_HW | DO_DUAL_DAC)
+#define DO_LINE_AS_REAR 0x00000010 /* 033 or later */
+#define DO_LINE_AS_BASS 0x00000020 /* 039 or later */
+#define DO_MIC_AS_BASS 0x00000040 /* 039 or later */
+#define DO_SPDIF_OUT 0x00000100
+#define DO_SPDIF_IN 0x00000200
+#define DO_SPDIF_LOOP 0x00000400
static struct cm_state *devs;
static unsigned long wavetable_mem;
static inline unsigned ld2(unsigned int x)
{
- unsigned r = 0;
+ unsigned exp=16,l=5,r=0;
+ static const unsigned num[]={0x2,0x4,0x10,0x100,0x10000};
+
+ /* num: 2, 4, 16, 256, 65536 */
+ /* exp: 1, 2, 4, 8, 16 */
- if (x >= 0x10000) {
- x >>= 16;
- r += 16;
- }
- if (x >= 0x100) {
- x >>= 8;
- r += 8;
- }
- if (x >= 0x10) {
- x >>= 4;
- r += 4;
- }
- if (x >= 4) {
- x >>= 2;
- r += 2;
+ while(l--) {
+ if( x >= num[l] ) {
+ if(num[l]>2) x >>= exp;
+ r+=exp;
+ }
+ exp>>=1;
}
- if (x >= 2)
- r++;
- return r;
-}
-/*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
- */
-
-#ifdef hweight32
-#undef hweight32
-#endif
-
-static inline unsigned int hweight32(unsigned int w)
-{
- unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
- res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
- res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
- res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
- return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+ return r;
}
/* --------------------------------------------------------------------- */
-/*
- * Why use byte IO? Nobody knows, but S3 does it also in their Windows driver.
- */
-
-#undef DMABYTEIO
-
static void maskb(unsigned int addr, unsigned int mask, unsigned int value)
{
outb((inb(addr) & mask) | value, addr);
{
unsigned int curr_addr;
-#if 1
curr_addr = inw(s->iobase + CODEC_CMI_CH1_FRAME2) + 1;
curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
curr_addr = s->dma_dac.dmasize - curr_addr;
-#else
- curr_addr = inl(s->iobase + CODEC_CMI_CH1_FRAME1);
- curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK]-1);
- curr_addr -= s->dma_dac.rawphys;
-#endif
+
return curr_addr;
}
{
unsigned int curr_addr;
-#if 1
curr_addr = inw(s->iobase + CODEC_CMI_CH0_FRAME2) + 1;
curr_addr <<= sample_shift[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK];
curr_addr = s->dma_adc.dmasize - curr_addr;
-#else
- curr_addr = inl(s->iobase + CODEC_CMI_CH0_FRAME1);
- curr_addr &= ~(sample_size[(s->fmt >> CM_CFMT_ADCSHIFT) & CM_CFMT_MASK]-1);
- curr_addr -= s->dma_adc.rawphys;
-#endif
+
return curr_addr;
}
static void wrmixer(struct cm_state *s, unsigned char idx, unsigned char data)
{
outb(idx, s->iobase + CODEC_SB16_ADDR);
+ udelay(10);
outb(data, s->iobase + CODEC_SB16_DATA);
+ udelay(10);
}
static unsigned char rdmixer(struct cm_state *s, unsigned char idx)
{
unsigned char v;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
outb(idx, s->iobase + CODEC_SB16_ADDR);
+ udelay(10);
v = inb(s->iobase + CODEC_SB16_DATA);
+ udelay(10);
+ spin_unlock_irqrestore(&s->lock, flags);
return v;
}
static void set_fmt_unlocked(struct cm_state *s, unsigned char mask, unsigned char data)
{
if (mask)
+ {
s->fmt = inb(s->iobase + CODEC_CMI_CHFORMAT);
+ udelay(10);
+ }
s->fmt = (s->fmt & mask) | data;
outb(s->fmt, s->iobase + CODEC_CMI_CHFORMAT);
+ udelay(10);
}
static void set_fmt(struct cm_state *s, unsigned char mask, unsigned char data)
static void frobindir(struct cm_state *s, unsigned char idx, unsigned char mask, unsigned char data)
{
outb(idx, s->iobase + CODEC_SB16_ADDR);
+ udelay(10);
outb((inb(s->iobase + CODEC_SB16_DATA) & mask) | data, s->iobase + CODEC_SB16_DATA);
+ udelay(10);
}
static struct {
{
/* reset bus master */
outb(s->enable | CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
+ udelay(10);
outb(s->enable & ~CM_CH0_RESET, s->iobase + CODEC_CMI_FUNCTRL0 + 2);
}
}
}
-//static void start_dac1(struct cm_state *s)
-//{
-// unsigned long flags;
-//
-// spin_lock_irqsave(&s->lock, flags);
-// start_dac1_unlocked(s);
-// spin_unlock_irqrestore(&s->lock, flags);
-//}
-
static void start_dac_unlocked(struct cm_state *s)
{
if ((s->dma_dac.mapped || s->dma_dac.count > 0) && s->dma_dac.ready) {
set_adc_rate_unlocked(s, s->ratedac);
}
- // N4SPK3D, disable 4 speaker mode (analog duplicate)
+
if (s->speakers > 2)
maskb(s->iobase + CODEC_CMI_MISC_CTRL + 3, ~0x04, 0);
s->curr_channels = channels;
db->buforder = order;
db->rawphys = virt_to_bus(db->rawbuf);
if ((db->rawphys ^ (db->rawphys + (PAGE_SIZE << db->buforder) - 1)) & ~0xffff)
- printk(KERN_DEBUG "cm: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n",
+ printk(KERN_DEBUG "cmpci: DMA buffer crosses 64k boundary: busaddr 0x%lx size %ld\n",
(long) db->rawphys, PAGE_SIZE << db->buforder);
if ((db->rawphys + (PAGE_SIZE << db->buforder) - 1) & ~0xffffff)
- printk(KERN_DEBUG "cm: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n",
+ printk(KERN_DEBUG "cmpci: DMA buffer beyond 16MB: busaddr 0x%lx size %ld\n",
(long) db->rawphys, PAGE_SIZE << db->buforder);
/* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
/* --------------------------------------------------------------------- */
-static const char invalid_magic[] = KERN_CRIT "cm: invalid magic value\n";
+static const char invalid_magic[] = KERN_CRIT "cmpci: invalid magic value\n";
#ifdef CONFIG_SOUND_CMPCI /* support multiple chips */
#define VALIDATE_STATE(s)
[SOUND_MIXER_SPEAKER]= { DSP_MIX_SPKRVOLIDX, DSP_MIX_SPKRVOLIDX, MT_5MUTEMONO, 0x01, 0x01 }
};
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
-
-static int return_mixval(struct cm_state *s, unsigned i, int *arg)
-{
- unsigned long flags;
- unsigned char l, r, rl, rr;
-
- spin_lock_irqsave(&s->lock, flags);
- l = rdmixer(s, mixtable[i].left);
- r = rdmixer(s, mixtable[i].right);
- spin_unlock_irqrestore(&s->lock, flags);
- switch (mixtable[i].type) {
- case MT_4:
- r &= 0xf;
- l &= 0xf;
- rl = 10 + 6 * (l & 15);
- rr = 10 + 6 * (r & 15);
- break;
-
- case MT_4MUTEMONO:
- rl = 55 - 3 * (l & 15);
- if (r & 0x10)
- rl += 45;
- rr = rl;
- r = l;
- break;
-
- case MT_5MUTEMONO:
- r = l;
- rl = 100 - 3 * ((l >> 3) & 31);
- rr = rl;
- break;
-
- case MT_5MUTE:
- default:
- rl = 100 - 3 * ((l >> 3) & 31);
- rr = 100 - 3 * ((r >> 3) & 31);
- break;
-
- case MT_6MUTE:
- rl = 100 - 3 * (l & 63) / 2;
- rr = 100 - 3 * (r & 63) / 2;
- break;
- }
- if (l & 0x80)
- rl = 0;
- if (r & 0x80)
- rr = 0;
- return put_user((rr << 8) | rl, arg);
-}
-
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
static const unsigned char volidx[SOUND_MIXER_NRDEVICES] =
{
[SOUND_MIXER_CD] = 1,
[SOUND_MIXER_SPEAKER]= 7
};
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
-
static unsigned mixer_recmask(struct cm_state *s)
{
- unsigned long flags;
int i, j, k;
- spin_lock_irqsave(&s->lock, flags);
j = rdmixer(s, DSP_MIX_ADCMIXIDX_L);
- spin_unlock_irqrestore(&s->lock, flags);
j &= 0x7f;
for (k = i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if (j & mixtable[i].rec)
i = _IOC_NR(cmd);
if (i >= SOUND_MIXER_NRDEVICES || !mixtable[i].type)
return -EINVAL;
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- return return_mixval(s, i, (int *)arg);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
if (!volidx[i])
return -EINVAL;
return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
}
}
if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */
if (get_user(val, (int *)arg))
return -EFAULT;
- i = hweight32(val);
+ i = generic_hweight32(val);
for (j = i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
if (!(val & (1 << i)))
continue;
break;
}
spin_unlock_irqrestore(&s->lock, flags);
-#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
- return return_mixval(s, i, (int *)arg);
-#else /* OSS_DOCUMENTED_MIXER_SEMANTICS */
+
if (!volidx[i])
return -EINVAL;
s->mix.vol[volidx[i]-1] = val;
return put_user(s->mix.vol[volidx[i]-1], (int *)arg);
-#endif /* OSS_DOCUMENTED_MIXER_SEMANTICS */
}
}
tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->ratedac;
tmo >>= sample_shift[(s->fmt >> CM_CFMT_DACSHIFT) & CM_CFMT_MASK];
if (!schedule_timeout(tmo + 1))
- printk(KERN_DEBUG "cm: dma timed out??\n");
+ printk(KERN_DEBUG "cmpci: dma timed out??\n");
}
remove_wait_queue(&s->dma_dac.wait, &wait);
current->state = TASK_RUNNING;
if (!access_ok(VERIFY_WRITE, buffer, count))
return -EFAULT;
ret = 0;
-#if 0
- spin_lock_irqsave(&s->lock, flags);
- cm_update_ptr(s);
- spin_unlock_irqrestore(&s->lock, flags);
-#endif
+
while (count > 0) {
spin_lock_irqsave(&s->lock, flags);
swptr = s->dma_adc.swptr;
if (file->f_flags & O_NONBLOCK)
return ret ? ret : -EAGAIN;
if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
- printk(KERN_DEBUG "cm: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+ printk(KERN_DEBUG "cmpci: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
s->dma_adc.hwptr, s->dma_adc.swptr);
spin_lock_irqsave(&s->lock, flags);
return -EFAULT;
}
ret = 0;
-#if 0
- spin_lock_irqsave(&s->lock, flags);
- cm_update_ptr(s);
- spin_unlock_irqrestore(&s->lock, flags);
-#endif
+
while (count > 0) {
spin_lock_irqsave(&s->lock, flags);
if (s->dma_dac.count < 0) {
if (file->f_flags & O_NONBLOCK)
return ret ? ret : -EAGAIN;
if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
- printk(KERN_DEBUG "cm: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+ printk(KERN_DEBUG "cmpci: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
s->dma_dac.hwptr, s->dma_dac.swptr);
spin_lock_irqsave(&s->lock, flags);
down(&s->open_sem);
if (file->f_mode & FMODE_WRITE) {
stop_dac(s);
-#ifndef FIXEDDMA
+
dealloc_dmabuf(&s->dma_dac);
if (s->status & DO_DUAL_DAC)
dealloc_dmabuf(&s->dma_adc);
-#endif
+
if (s->status & DO_MULTI_CH)
set_dac_channels(s, 0);
if (s->status & DO_AC3)
}
if (file->f_mode & FMODE_READ) {
stop_adc(s);
-#ifndef FIXEDDMA
dealloc_dmabuf(&s->dma_adc);
-#endif
}
s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
up(&s->open_sem);
}
tmo = (count * HZ) / 3100;
if (!schedule_timeout(tmo ? : 1) && tmo)
- printk(KERN_DEBUG "cm: midi timed out??\n");
+ printk(KERN_DEBUG "cmpci: midi timed out??\n");
}
remove_wait_queue(&s->midi.owait, &wait);
set_current_state(TASK_RUNNING);
};
#endif /* CONFIG_SOUND_CMPCI_FM */
-/* --------------------------------------------------------------------- */
-
-/* maximum number of devices */
-#define NR_DEVICE 5
-
-#if 0
-static int reverb[NR_DEVICE] = { 0, };
-static int wavetable[NR_DEVICE] = { 0, };
-#endif
-
-/* --------------------------------------------------------------------- */
static struct initvol {
int mixch;
}
#ifdef CONFIG_SOUND_CMPCI_MIDI
-static int mpu_io = CONFIG_SOUND_CMPCI_MPUIO;
+static int mpuio = CONFIG_SOUND_CMPCI_MPUIO;
#else
-static int mpu_io;
+static int mpuio;
#endif
#ifdef CONFIG_SOUND_CMPCI_FM
-static int fm_io = CONFIG_SOUND_CMPCI_FMIO;
+static int fmio = CONFIG_SOUND_CMPCI_FMIO;
#else
-static int fm_io;
+static int fmio;
#endif
#ifdef CONFIG_SOUND_CMPCI_SPDIFINVERSE
static int spdif_inverse = 1;
#else
static int joystick;
#endif
-MODULE_PARM(mpu_io, "i");
-MODULE_PARM(fm_io, "i");
+MODULE_PARM(mpuio, "i");
+MODULE_PARM(fmio, "i");
MODULE_PARM(spdif_inverse, "i");
MODULE_PARM(spdif_loop, "i");
MODULE_PARM(speakers, "i");
MODULE_PARM(use_line_as_rear, "i");
MODULE_PARM(use_line_as_bass, "i");
MODULE_PARM(joystick, "i");
-MODULE_PARM_DESC(mpu_io, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
-MODULE_PARM_DESC(fm_io, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
+MODULE_PARM_DESC(mpuio, "(0x330, 0x320, 0x310, 0x300) Base of MPU-401, 0 to disable");
+MODULE_PARM_DESC(fmio, "(0x388, 0x3C8, 0x3E0) Base of OPL3, 0 to disable");
MODULE_PARM_DESC(spdif_inverse, "(1/0) Invert S/PDIF-in signal");
MODULE_PARM_DESC(spdif_loop, "(1/0) Route S/PDIF-in to S/PDIF-out directly");
MODULE_PARM_DESC(speakers, "(2-6) Number of speakers you connect");
return;
s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s) {
- printk(KERN_WARNING "cm: out of memory\n");
+ printk(KERN_WARNING "cmpci: out of memory\n");
return;
}
/* search device name */
spin_lock_init(&s->lock);
s->magic = CM_MAGIC;
s->iobase = pci_resource_start(pcidev, 0);
- s->iosynth = fm_io;
- s->iomidi = mpu_io;
+ s->iosynth = fmio;
+ s->iomidi = mpuio;
s->status = 0;
/* range check */
if (speakers < 2)
s->irq = pcidev->irq;
if (!request_region(s->iobase, CM_EXTENT_CODEC, "cmpci")) {
- printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
+ printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iobase, s->iobase+CM_EXTENT_CODEC-1);
goto err_region5;
}
#ifdef CONFIG_SOUND_CMPCI_MIDI
maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0x04, 0);
if (s->iomidi) {
if (!request_region(s->iomidi, CM_EXTENT_MIDI, "cmpci Midi")) {
- printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
+ printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+CM_EXTENT_MIDI-1);
s->iomidi = 0;
} else {
/* set IO based at 0x330 */
maskb(s->iobase + CODEC_CMI_MISC_CTRL + 2, ~8, 0);
if (s->iosynth) {
if (!request_region(s->iosynth, CM_EXTENT_SYNTH, "cmpci FM")) {
- printk(KERN_ERR "cm: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
+ printk(KERN_ERR "cmpci: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+CM_EXTENT_SYNTH-1);
s->iosynth = 0;
} else {
/* set IO based at 0x388 */
/* request irq */
if (request_irq(s->irq, cm_interrupt, SA_SHIRQ, "cmpci", s)) {
- printk(KERN_ERR "cm: irq %u in use\n", s->irq);
+ printk(KERN_ERR "cmpci: irq %u in use\n", s->irq);
goto err_irq;
}
- printk(KERN_INFO "cm: found %s adapter at io %#06x irq %u\n",
+ printk(KERN_INFO "cmpci: found %s adapter at io %#06x irq %u\n",
devicename, s->iobase, s->irq);
/* register devices */
if ((s->dev_audio = register_sound_dsp(&cm_audio_fops, -1)) < 0)
/* use channel 0 for record, channel 1 for play */
maskb(s->iobase + CODEC_CMI_FUNCTRL0, ~2, 1);
s->deviceid = pcidev->device;
+
if (pcidev->device == PCI_DEVICE_ID_CMEDIA_CM8738) {
+
/* chip version and hw capability check */
s->chip_version = query_chip(s);
- printk(KERN_INFO "chip version = 0%d\n", s->chip_version);
+ printk(KERN_INFO "cmpci: chip version = 0%d\n", s->chip_version);
+
/* seet SPDIF-in inverse before enable SPDIF loop */
if (spdif_inverse) {
/* turn on spdif-in inverse */
maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~0, 1);
- printk(KERN_INFO "cm: Inverse SPDIF-in\n");
+ printk(KERN_INFO "cmpci: Inverse SPDIF-in\n");
} else {
/* turn off spdif-ininverse */
maskb(s->iobase + CODEC_CMI_CHFORMAT + 2, ~1, 0);
s->status |= DO_SPDIF_LOOP;
/* turn on spdif-in to spdif-out */
maskb(s->iobase + CODEC_CMI_FUNCTRL1, ~0, 0x80);
- printk(KERN_INFO "cm: Enable SPDIF loop\n");
+ printk(KERN_INFO "cmpci: Enable SPDIF loop\n");
} else {
s->status &= ~DO_SPDIF_LOOP;
/* turn off spdif-in to spdif-out */
err_dev2:
unregister_sound_dsp(s->dev_audio);
err_dev1:
- printk(KERN_ERR "cm: cannot register misc device\n");
+ printk(KERN_ERR "cmpci: cannot register misc device\n");
free_irq(s->irq, s);
err_irq:
#ifdef CONFIG_SOUND_CMPCI_FM
if (!pci_present()) /* No PCI bus in this machine! */
#endif
return -ENODEV;
- printk(KERN_INFO "cm: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
-#if 0
- if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
- printk(KERN_INFO "cm: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
-#endif
+ printk(KERN_INFO "cmpci: version $Revision: 5.64 $ time " __TIME__ " " __DATE__ "\n");
+
while (index < NR_DEVICE && (
(pcidev = pci_find_device(PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, pcidev)))) {
initialize_chip(pcidev);
synchronize_irq();
outb(0, s->iobase + CODEC_CMI_FUNCTRL0 + 2); /* disable channels */
free_irq(s->irq, s);
-#ifdef FIXEDDMA
- dealloc_dmabuf(&s->dma_dac);
- dealloc_dmabuf(&s->dma_adc);
-#endif
/* reset mixer */
wrmixer(s, DSP_MIX_DATARESETIDX, 0);
}
if (wavetable_mem)
free_pages(wavetable_mem, 20-PAGE_SHIFT);
- printk(KERN_INFO "cm: unloading\n");
+ printk(KERN_INFO "cmpci: unloading\n");
}
module_init(init_cmpci);
spin_unlock_irqrestore(&card->midi.lock, flags);
card->midi.open_mode |= (file->f_mode & (FMODE_READ | FMODE_WRITE));
up(&card->midi.open_sem);
- MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT; /* for 2.2 */
return 0;
}
card->midi.open_mode &= (~(file->f_mode & (FMODE_READ | FMODE_WRITE)));
up(&card->midi.open_sem);
wake_up(&card->midi.open_wait);
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT; /* for 2.2 */
return 0;
}
state->open_mode |= FMODE_READ;
up(&state->open_sem);
- MOD_INC_USE_COUNT;
}
if(file->f_mode & FMODE_WRITE)
{
state->open_mode |= FMODE_WRITE;
up(&state->open_sem);
- MOD_INC_USE_COUNT;
if((ret = prog_dmabuf(state)))
return ret;
}
+ MOD_INC_USE_COUNT; /* for 2.2 */
CS_DBGOUT(CS_OPEN | CS_FUNCTION, 2, printk("cs46xx: cs_open()- 0\n") );
return 0;
}
kfree(state);
}
- MOD_DEC_USE_COUNT;
}
state = card->states[0];
kfree(state);
}
- MOD_DEC_USE_COUNT;
}
CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 2, printk("cs46xx: cs_release()- 0\n") );
+ MOD_DEC_USE_COUNT; /* For 2.2 */
return 0;
}
}
card->amplifier_ctrl(card, 1);
CS_INC_USE_COUNT(&card->mixer_use_cnt);
- MOD_INC_USE_COUNT;
+ MOD_INC_USE_COUNT; /* for 2.2 */
CS_DBGOUT(CS_FUNCTION | CS_OPEN, 4,
printk(KERN_INFO "cs46xx: cs_open_mixdev()- 0\n"));
return 0;
return -ENODEV;
}
match:
- MOD_DEC_USE_COUNT;
+ MOD_DEC_USE_COUNT; /* for 2.2 */
if(!CS_DEC_AND_TEST(&card->mixer_use_cnt))
{
CS_DBGOUT(CS_FUNCTION | CS_RELEASE, 4,
solo1_suspend(struct pci_dev *pci_dev, u32 state) {
struct solo1_state *s = (struct solo1_state*)pci_get_drvdata(pci_dev);
if (!s)
- return;
+ return 1;
outb(0, s->iobase+6);
/* DMA master clear */
outb(0, s->ddmabase+0xd);
#define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
-#define DRIVER_VERSION "0.03"
+#define DRIVER_VERSION "0.04"
/* magic numbers to protect our data structures */
#define I810_CARD_MAGIC 0x5072696E /* "Prin" */
dmabuf->rate = (rate * 48000)/clocking;
}
- if(rate != i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE))
- {
- /* Power down the DAC */
- dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
- i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0200);
- /* Load the rate and read the effective rate */
- i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
- new_rate=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
- /* Power it back up */
- i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
- if(new_rate != rate) {
- dmabuf->rate = (new_rate * 48000)/clocking;
- rate = new_rate;
- }
+ new_rate = ac97_set_dac_rate(codec, rate);
+
+ if(new_rate != rate) {
+ dmabuf->rate = (new_rate * 48000)/clocking;
+ rate = new_rate;
}
#ifdef DEBUG
printk("i810_audio: called i810_set_dac_rate : rate = %d/%d\n", dmabuf->rate, rate);
rate = 8000;
dmabuf->rate = (rate * 48000)/clocking;
}
+
+ new_rate = ac97_set_adc_rate(codec, rate);
- if(rate != i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE))
- {
- /* Power down the ADC */
- dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
- i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
- /* Load the rate and read the effective rate */
- i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate);
- new_rate=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
- /* Power it back up */
- i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
- if(new_rate != rate) {
- dmabuf->rate = (new_rate * 48000)/clocking;
- rate = new_rate;
- }
+ if(new_rate != rate) {
+ dmabuf->rate = (new_rate * 48000)/clocking;
+ rate = new_rate;
}
#ifdef DEBUG
printk("i810_audio: called i810_set_adc_rate : rate = %d/%d\n", dmabuf->rate, rate);
dmabuf = &state->dmabuf;
if(dmabuf->enable & DAC_RUNNING)
c=dmabuf->write_channel;
- else
+ else if(dmabuf->enable & ADC_RUNNING)
c=dmabuf->read_channel;
+ else /* This can occur going from R/W to close */
+ continue;
port+=c->port;
#endif
if (get_user(val, (int *)arg))
return -EFAULT;
- if(val==0) {
- return -EINVAL;
- } else {
- ret = 1;
- }
+
if (dmabuf->enable & DAC_RUNNING) {
stop_dac(state);
}
if (dmabuf->enable & ADC_RUNNING) {
stop_adc(state);
}
- return put_user(ret, (int *)arg);
+ return put_user(1, (int *)arg);
case SNDCTL_DSP_GETBLKSIZE:
if (file->f_mode & FMODE_WRITE) {
#ifdef DEBUG
printk("SNDCTL_DSP_CHANNELS\n");
#endif
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+
+ if (val > 0) {
+ if (dmabuf->enable & DAC_RUNNING) {
+ stop_dac(state);
+ }
+ if (dmabuf->enable & ADC_RUNNING) {
+ stop_adc(state);
+ }
+ }
return put_user(2, (int *)arg);
case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */
return num_ac97;
}
+static void __init i810_configure_clocking (void)
+{
+ struct i810_card *card;
+ struct i810_state *state;
+ struct dmabuf *dmabuf;
+ unsigned int i, offset, new_offset;
+ unsigned long flags;
+
+ card = devs;
+ /* We could try to set the clocking for multiple cards, but can you even have
+ * more than one i810 in a machine? Besides, clocking is global, so unless
+ * someone actually thinks more than one i810 in a machine is possible and
+ * decides to rewrite that little bit, setting the rate for more than one card
+ * is a waste of time.
+ */
+ if(card != NULL) {
+ state = card->states[0] = (struct i810_state *)
+ kmalloc(sizeof(struct i810_state), GFP_KERNEL);
+ if (state == NULL)
+ return;
+ memset(state, 0, sizeof(struct i810_state));
+ dmabuf = &state->dmabuf;
+
+ dmabuf->write_channel = card->alloc_pcm_channel(card);
+ state->virt = 0;
+ state->card = card;
+ state->magic = I810_STATE_MAGIC;
+ init_waitqueue_head(&dmabuf->wait);
+ init_MUTEX(&state->open_sem);
+ dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
+ dmabuf->trigger = PCM_ENABLE_OUTPUT;
+ i810_set_dac_rate(state, 48000);
+ if(prog_dmabuf(state, 0) != 0) {
+ goto config_out_nodmabuf;
+ }
+ if(dmabuf->dmasize < 16384) {
+ goto config_out;
+ }
+ dmabuf->count = dmabuf->dmasize;
+ outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
+ save_flags(flags);
+ cli();
+ start_dac(state);
+ offset = i810_get_dma_addr(state, 0);
+ mdelay(50);
+ new_offset = i810_get_dma_addr(state, 0);
+ stop_dac(state);
+ outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
+ restore_flags(flags);
+ i = new_offset - offset;
+#ifdef DEBUG
+ printk("i810_audio: %d bytes in 50 milliseconds\n", i);
+#endif
+ if(i == 0)
+ goto config_out;
+ i = i / 4 * 20;
+ if (i > 48500 || i < 47500) {
+ clocking = clocking * clocking / i;
+ printk("i810_audio: setting clocking to %d\n", clocking);
+ }
+config_out:
+ dealloc_dmabuf(state);
+config_out_nodmabuf:
+ state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
+ kfree(state);
+ card->states[0] = NULL;
+ }
+}
+
/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered
until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
kfree(card);
return -ENODEV;
}
- /* register /dev/dsp */
- if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
- printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
+
+ /* initialize AC97 codec and register /dev/mixer */
+ if (i810_ac97_init(card) <= 0) {
release_region(card->iobase, 64);
release_region(card->ac97base, 256);
free_irq(card->irq, card);
kfree(card);
return -ENODEV;
}
+ pci_dev->driver_data = card;
+ if(clocking == 48000) {
+ i810_configure_clocking();
+ }
- /* initialize AC97 codec and register /dev/mixer */
- if (i810_ac97_init(card) <= 0) {
- unregister_sound_dsp(card->dev_audio);
+ /* register /dev/dsp */
+ if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) {
+ int i;
+ printk(KERN_ERR "i810_audio: couldn't register DSP device!\n");
release_region(card->iobase, 64);
release_region(card->ac97base, 256);
free_irq(card->irq, card);
+ for (i = 0; i < NR_AC97; i++)
+ if (card->ac97_codec[i] != NULL) {
+ unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
+ kfree (card->ac97_codec[i]);
+ }
kfree(card);
return -ENODEV;
}
- pci_dev->driver_data = card;
+
return 0;
}
/* unregister audio devices */
for (i = 0; i < NR_AC97; i++)
- if (devs->ac97_codec[i] != NULL) {
+ if (card->ac97_codec[i] != NULL) {
unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
kfree (card->ac97_codec[i]);
}
remove: i810_remove,
};
-static void __init i810_configure_clocking (void)
-{
- struct i810_card *card;
- struct i810_state *state;
- struct dmabuf *dmabuf;
- unsigned int i, offset, new_offset;
- unsigned long flags;
-
- card = devs;
- /* We could try to set the clocking for multiple cards, but can you even have
- * more than one i810 in a machine? Besides, clocking is global, so unless
- * someone actually thinks more than one i810 in a machine is possible and
- * decides to rewrite that little bit, setting the rate for more than one card
- * is a waste of time.
- */
- if(card != NULL) {
- state = card->states[0] = (struct i810_state *)
- kmalloc(sizeof(struct i810_state), GFP_KERNEL);
- if (state == NULL)
- return;
- memset(state, 0, sizeof(struct i810_state));
- dmabuf = &state->dmabuf;
-
- dmabuf->write_channel = card->alloc_pcm_channel(card);
- state->virt = 0;
- state->card = card;
- state->magic = I810_STATE_MAGIC;
- init_waitqueue_head(&dmabuf->wait);
- init_MUTEX(&state->open_sem);
- dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
- dmabuf->trigger = PCM_ENABLE_OUTPUT;
- i810_set_dac_rate(state, 48000);
- if(prog_dmabuf(state, 0) != 0) {
- goto config_out_nodmabuf;
- }
- if(dmabuf->dmasize < 16384) {
- goto config_out;
- }
- dmabuf->count = dmabuf->dmasize;
- outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
- save_flags(flags);
- cli();
- start_dac(state);
- offset = i810_get_dma_addr(state, 0);
- mdelay(50);
- new_offset = i810_get_dma_addr(state, 0);
- stop_dac(state);
- outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
- restore_flags(flags);
- i = new_offset - offset;
-#ifdef DEBUG
- printk("i810_audio: %d bytes in 50 milliseconds\n", i);
-#endif
- if(i == 0)
- goto config_out;
- i = i / 4 * 20;
- if (i > 48500 || i < 47500) {
- clocking = clocking * clocking / i;
- printk("i810_audio: setting clocking to %d\n", clocking);
- }
-config_out:
- dealloc_dmabuf(state);
-config_out_nodmabuf:
- state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
- kfree(state);
- card->states[0] = NULL;
- }
-}
static int __init i810_init_module (void)
{
--- /dev/null
+/*
+ * ite8172.c -- ITE IT8172G Sound Driver.
+ *
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc.
+ * stevel@mvista.com or source@mvista.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * Module command line parameters:
+ *
+ * Supported devices:
+ * /dev/dsp standard OSS /dev/dsp device
+ * /dev/mixer standard OSS /dev/mixer device
+ *
+ * Notes:
+ *
+ * 1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ * taken, slightly modified or not at all, from the ES1371 driver,
+ * so refer to the credits in es1371.c for those. The rest of the
+ * code (probe, open, read, write, the ISR, etc.) is new.
+ * 2. The following support is untested:
+ * * Memory mapping the audio buffers, and the ioctl controls that go
+ * with it.
+ * * S/PDIF output.
+ * 3. The following is not supported:
+ * * I2S input.
+ * * legacy audio mode.
+ * 4. Support for volume button interrupts is implemented but doesn't
+ * work yet.
+ *
+ * Revision history
+ * 02.08.2001 0.1 Initial release
+ */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <asm/it8172/it8172.h>
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+#define IT8172_DEBUG
+#undef IT8172_VERBOSE_DEBUG
+#define DBG(x) {}
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+
+/*
+ * Audio Controller register bit definitions follow. See
+ * include/asm/it8172/it8172.h for register offsets.
+ */
+
+/* PCM Out Volume Reg */
+#define PCMOV_PCMOM (1<<15) /* PCM Out Mute default 1: mute */
+#define PCMOV_PCMRCG_BIT 8 /* PCM Right channel Gain */
+#define PCMOV_PCMRCG_MASK (0x1f<<PCMOV_PCMRCG_BIT)
+#define PCMOV_PCMLCG_BIT 0 /* PCM Left channel gain */
+#define PCMOV_PCMLCG_MASK 0x1f
+
+/* FM Out Volume Reg */
+#define FMOV_FMOM (1<<15) /* FM Out Mute default 1: mute */
+#define FMOV_FMRCG_BIT 8 /* FM Right channel Gain */
+#define FMOV_FMRCG_MASK (0x1f<<FMOV_FMRCG_BIT)
+#define FMOV_FMLCG_BIT 0 /* FM Left channel gain */
+#define FMOV_FMLCG_MASK 0x1f
+
+/* I2S Out Volume Reg */
+#define I2SV_I2SOM (1<<15) /* I2S Out Mute default 1: mute */
+#define I2SV_I2SRCG_BIT 8 /* I2S Right channel Gain */
+#define I2SV_I2SRCG_MASK (0x1f<<I2SV_I2SRCG_BIT)
+#define I2SV_I2SLCG_BIT 0 /* I2S Left channel gain */
+#define I2SV_I2SLCG_MASK 0x1f
+
+/* Digital Recording Source Select Reg */
+#define DRSS_BIT 0
+#define DRSS_MASK 0x07
+#define DRSS_AC97_PRIM 0
+#define DRSS_FM 1
+#define DRSS_I2S 2
+#define DRSS_PCM 3
+#define DRSS_AC97_SEC 4
+
+/* Playback/Capture Channel Control Registers */
+#define CC_SM (1<<15) /* Stereo, Mone 0: mono 1: stereo */
+#define CC_DF (1<<14) /* Data Format 0: 8 bit 1: 16 bit */
+#define CC_FMT_BIT 14
+#define CC_FMT_MASK (0x03<<CC_FMT_BIT)
+#define CC_CF_BIT 12 /* Channel format (Playback only) */
+#define CC_CF_MASK (0x03<<CC_CF_BIT)
+#define CC_CF_2 0
+#define CC_CF_4 (1<<CC_CF_BIT)
+#define CC_CF_6 (2<<CC_CF_BIT)
+#define CC_SR_BIT 8 /* sample Rate */
+#define CC_SR_MASK (0x0f<<CC_SR_BIT)
+#define CC_SR_5500 0
+#define CC_SR_8000 (1<<CC_SR_BIT)
+#define CC_SR_9600 (2<<CC_SR_BIT)
+#define CC_SR_11025 (3<<CC_SR_BIT)
+#define CC_SR_16000 (4<<CC_SR_BIT)
+#define CC_SR_19200 (5<<CC_SR_BIT)
+#define CC_SR_22050 (6<<CC_SR_BIT)
+#define CC_SR_32000 (7<<CC_SR_BIT)
+#define CC_SR_38400 (8<<CC_SR_BIT)
+#define CC_SR_44100 (9<<CC_SR_BIT)
+#define CC_SR_48000 (10<<CC_SR_BIT)
+#define CC_CSP (1<<7) /* Channel stop
+ * 0: End of Current buffer
+ * 1: Immediately stop when rec stop */
+#define CC_CP (1<<6) /* Channel pause 0: normal, 1: pause */
+#define CC_CA (1<<5) /* Channel Action 0: Stop , 1: start */
+#define CC_CB2L (1<<2) /* Cur. buf. 2 xfr is last 0: No, 1: Yes */
+#define CC_CB1L (1<<1) /* Cur. buf. 1 xfr is last 0: No, 1: Yes */
+#define CC_DE 1 /* DFC/DFIFO Data Empty 1: empty, 0: not empty
+ * (Playback only)
+ */
+
+/* Codec Control Reg */
+#define CODECC_GME (1<<9) /* AC97 GPIO Mode enable */
+#define CODECC_ATM (1<<8) /* AC97 ATE test mode 0: test 1: normal */
+#define CODECC_WR (1<<6) /* AC97 Warn reset 1: warm reset , 0: Normal */
+#define CODECC_CR (1<<5) /* AC97 Cold reset 1: Cold reset , 0: Normal */
+
+
+/* I2S Control Reg */
+#define I2SMC_SR_BIT 6 /* I2S Sampling rate
+ * 00: 48KHz, 01: 44.1 KHz, 10: 32 32 KHz */
+#define I2SMC_SR_MASK (0x03<<I2SMC_SR_BIT)
+#define I2SMC_SR_48000 0
+#define I2SMC_SR_44100 (1<<I2SMC_SR_BIT)
+#define I2SMC_SR_32000 (2<<I2SMC_SR_BIT)
+#define I2SMC_SRSS (1<<5) /* Sample Rate Source Select 1:S/W, 0: H/W */
+#define I2SMC_I2SF_BIT 0 /* I2S Format */
+#define I2SMC_I2SF_MASK 0x03
+#define I2SMC_I2SF_DAC 0
+#define I2SMC_I2SF_ADC 2
+#define I2SMC_I2SF_I2S 3
+
+
+/* Volume up, Down, Mute */
+#define VS_VMP (1<<2) /* Volume mute 1: pushed, 0: not */
+#define VS_VDP (1<<1) /* Volume Down 1: pushed, 0: not */
+#define VS_VUP 1 /* Volime Up 1: pushed, 0: not */
+
+/* SRC, Mixer test control/DFC status reg */
+#define SRCS_DPUSC (1<<5) /* DFC Playback underrun Status/clear */
+#define SRCS_DCOSC (1<<4) /* DFC Capture Overrun Status/clear */
+#define SRCS_SIS (1<<3) /* SRC input select 1: Mixer, 0: Codec I/F */
+#define SRCS_CDIS_BIT 0 /* Codec Data Input Select */
+#define SRCS_CDIS_MASK 0x07
+#define SRCS_CDIS_MIXER 0
+#define SRCS_CDIS_PCM 1
+#define SRCS_CDIS_I2S 2
+#define SRCS_CDIS_FM 3
+#define SRCS_CDIS_DFC 4
+
+
+/* Codec Index Reg command Port */
+#define CIRCP_CID_BIT 10
+#define CIRCP_CID_MASK (0x03<<CIRCP_CID_BIT)
+#define CIRCP_CPS (1<<9) /* Command Port Status 0: ready, 1: busy */
+#define CIRCP_DPVF (1<<8) /* Data Port Valid Flag 0: invalis, 1: valid */
+#define CIRCP_RWC (1<<7) /* Read/write command */
+#define CIRCP_CIA_BIT 0
+#define CIRCP_CIA_MASK 0x007F /* Codec Index Address */
+
+/* Test Mode Control/Test group Select Control */
+
+/* General Control Reg */
+#define GC_VDC_BIT 6 /* Volume Division Control */
+#define GC_VDC_MASK (0x03<<GC_VDC_BIT)
+#define GC_VDC_NONE 0
+#define GC_VDC_DIV2 (1<<GC_VDC_BIT)
+#define GC_VDC_DIV4 (2<<GC_VDC_BIT)
+#define GC_SOE (1<<2) /* S/PDIF Output enable */
+#define GC_SWR 1 /* Software warn reset */
+
+/* Interrupt mask Control Reg */
+#define IMC_VCIM (1<<6) /* Volume CNTL interrupt mask */
+#define IMC_CCIM (1<<1) /* Capture Chan. iterrupt mask */
+#define IMC_PCIM 1 /* Playback Chan. interrupt mask */
+
+/* Interrupt status/clear reg */
+#define ISC_VCI (1<<6) /* Volume CNTL interrupt 1: clears */
+#define ISC_CCI (1<<1) /* Capture Chan. interrupt 1: clears */
+#define ISC_PCI 1 /* Playback Chan. interrupt 1: clears */
+
+/* misc stuff */
+#define POLL_COUNT 0x5000
+
+
+#define IT8172_MODULE_NAME "IT8172 audio"
+#define PFX IT8172_MODULE_NAME ": "
+
+
+/* --------------------------------------------------------------------- */
+
+struct it8172_state {
+ /* list of it8172 devices */
+ struct list_head devs;
+
+ /* the corresponding pci_dev structure */
+ struct pci_dev *dev;
+
+ /* soundcore stuff */
+ int dev_audio;
+
+ /* hardware resources */
+ unsigned long io;
+ unsigned int irq;
+
+ /* PCI ID's */
+ u16 vendor;
+ u16 device;
+ u8 rev; /* the chip revision */
+
+ /* options */
+ int spdif_volume; /* S/PDIF output is enabled if != -1 */
+
+#ifdef IT8172_DEBUG
+ /* debug /proc entry */
+ struct proc_dir_entry *ps;
+ struct proc_dir_entry *ac97_ps;
+#endif /* IT8172_DEBUG */
+
+ struct ac97_codec codec;
+
+ unsigned short pcc, capcc;
+ unsigned dacrate, adcrate;
+
+ spinlock_t lock;
+ struct semaphore open_sem;
+ mode_t open_mode;
+ wait_queue_head_t open_wait;
+
+ struct dmabuf {
+ void *rawbuf;
+ dma_addr_t dmaaddr;
+ unsigned buforder;
+ unsigned numfrag;
+ unsigned fragshift;
+ void* nextIn;
+ void* nextOut;
+ int count;
+ int curBufPtr;
+ unsigned total_bytes;
+ unsigned error; /* over/underrun */
+ wait_queue_head_t wait;
+ /* redundant, but makes calculations easier */
+ unsigned fragsize;
+ unsigned dmasize;
+ unsigned fragsamples;
+ /* OSS stuff */
+ unsigned mapped:1;
+ unsigned ready:1;
+ unsigned stopped:1;
+ unsigned ossfragshift;
+ int ossmaxfrags;
+ unsigned subdivision;
+ } dma_dac, dma_adc;
+};
+
+/* --------------------------------------------------------------------- */
+
+static LIST_HEAD(devs);
+
+/* --------------------------------------------------------------------- */
+
+extern inline unsigned ld2(unsigned int x)
+{
+ unsigned r = 0;
+
+ if (x >= 0x10000) {
+ x >>= 16;
+ r += 16;
+ }
+ if (x >= 0x100) {
+ x >>= 8;
+ r += 8;
+ }
+ if (x >= 0x10) {
+ x >>= 4;
+ r += 4;
+ }
+ if (x >= 4) {
+ x >>= 2;
+ r += 2;
+ }
+ if (x >= 2)
+ r++;
+ return r;
+}
+
+/* --------------------------------------------------------------------- */
+
+static void it8172_delay(int msec)
+{
+ unsigned long tmo;
+ signed long tmo2;
+
+ if (in_interrupt())
+ return;
+
+ tmo = jiffies + (msec*HZ)/1000;
+ for (;;) {
+ tmo2 = tmo - jiffies;
+ if (tmo2 <= 0)
+ break;
+ schedule_timeout(tmo2);
+ }
+}
+
+
+static unsigned short
+get_compat_rate(unsigned* rate)
+{
+ unsigned rate_out = *rate;
+ unsigned short sr;
+
+ if (rate_out >= 46050) {
+ sr = CC_SR_48000; rate_out = 48000;
+ } else if (rate_out >= 41250) {
+ sr = CC_SR_44100; rate_out = 44100;
+ } else if (rate_out >= 35200) {
+ sr = CC_SR_38400; rate_out = 38400;
+ } else if (rate_out >= 27025) {
+ sr = CC_SR_32000; rate_out = 32000;
+ } else if (rate_out >= 20625) {
+ sr = CC_SR_22050; rate_out = 22050;
+ } else if (rate_out >= 17600) {
+ sr = CC_SR_19200; rate_out = 19200;
+ } else if (rate_out >= 13513) {
+ sr = CC_SR_16000; rate_out = 16000;
+ } else if (rate_out >= 10313) {
+ sr = CC_SR_11025; rate_out = 11025;
+ } else if (rate_out >= 8800) {
+ sr = CC_SR_9600; rate_out = 9600;
+ } else if (rate_out >= 6750) {
+ sr = CC_SR_8000; rate_out = 8000;
+ } else {
+ sr = CC_SR_5500; rate_out = 5500;
+ }
+
+ *rate = rate_out;
+ return sr;
+}
+
+static void set_adc_rate(struct it8172_state *s, unsigned rate)
+{
+ unsigned long flags;
+ unsigned short sr;
+
+ sr = get_compat_rate(&rate);
+
+ spin_lock_irqsave(&s->lock, flags);
+ s->capcc &= ~CC_SR_MASK;
+ s->capcc |= sr;
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ s->adcrate = rate;
+}
+
+
+static void set_dac_rate(struct it8172_state *s, unsigned rate)
+{
+ unsigned long flags;
+ unsigned short sr;
+
+ sr = get_compat_rate(&rate);
+
+ spin_lock_irqsave(&s->lock, flags);
+ s->pcc &= ~CC_SR_MASK;
+ s->pcc |= sr;
+ outw(s->pcc, s->io+IT_AC_PCC);
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ s->dacrate = rate;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+ struct it8172_state *s = (struct it8172_state *)codec->private_data;
+ unsigned long flags;
+ unsigned short circp, data;
+ int i;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ for (i = 0; i < POLL_COUNT; i++)
+ if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+ break;
+ if (i == POLL_COUNT)
+ printk(KERN_INFO PFX "rdcodec: codec ready poll expired!\n");
+
+ circp = addr & CIRCP_CIA_MASK;
+ circp |= (codec->id << CIRCP_CID_BIT);
+ circp |= CIRCP_RWC; // read command
+ outw(circp, s->io+IT_AC_CIRCP);
+
+ /* now wait for the data */
+ for (i = 0; i < POLL_COUNT; i++)
+ if (inw(s->io+IT_AC_CIRCP) & CIRCP_DPVF)
+ break;
+ if (i == POLL_COUNT)
+ printk(KERN_INFO PFX "rdcodec: read poll expired!\n");
+
+ data = inw(s->io+IT_AC_CIRDP);
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ return data;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+ struct it8172_state *s = (struct it8172_state *)codec->private_data;
+ unsigned long flags;
+ unsigned short circp;
+ int i;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ for (i = 0; i < POLL_COUNT; i++)
+ if (!(inw(s->io+IT_AC_CIRCP) & CIRCP_CPS))
+ break;
+ if (i == POLL_COUNT)
+ printk(KERN_INFO PFX "wrcodec: codec ready poll expired!\n");
+
+ circp = addr & CIRCP_CIA_MASK;
+ circp |= (codec->id << CIRCP_CID_BIT);
+ circp &= ~CIRCP_RWC; // write command
+
+ outw(data, s->io+IT_AC_CIRDP); // send data first
+ outw(circp, s->io+IT_AC_CIRCP);
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void waitcodec(struct ac97_codec *codec)
+{
+ unsigned short temp;
+
+ /* codec_wait is used to wait for a ready state after
+ an AC97_RESET. */
+ it8172_delay(10);
+
+ temp = rdcodec(codec, 0x26);
+
+ // If power down, power up
+ if (temp & 0x3f00) {
+ // Power on
+ wrcodec(codec, 0x26, 0);
+ it8172_delay(100);
+ // Reread
+ temp = rdcodec(codec, 0x26);
+ }
+
+ // Check if Codec REF,ANL,DAC,ADC ready***/
+ if ((temp & 0x3f0f) != 0x000f) {
+ printk(KERN_INFO PFX "codec reg 26 status (0x%x) not ready!!\n",
+ temp);
+ return;
+ }
+}
+
+
+/* --------------------------------------------------------------------- */
+
+extern inline void stop_adc(struct it8172_state *s)
+{
+ struct dmabuf* db = &s->dma_adc;
+ unsigned long flags;
+ unsigned char imc;
+
+ if (db->stopped)
+ return;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ s->capcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+ s->capcc |= CC_CSP;
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+
+ // disable capture interrupt
+ imc = inb(s->io+IT_AC_IMC);
+ outb(imc | IMC_CCIM, s->io+IT_AC_IMC);
+
+ db->stopped = 1;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+extern inline void stop_dac(struct it8172_state *s)
+{
+ struct dmabuf* db = &s->dma_dac;
+ unsigned long flags;
+ unsigned char imc;
+
+ if (db->stopped)
+ return;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ s->pcc &= ~(CC_CA | CC_CP | CC_CB2L | CC_CB1L);
+ s->pcc |= CC_CSP;
+ outw(s->pcc, s->io+IT_AC_PCC);
+
+ // disable playback interrupt
+ imc = inb(s->io+IT_AC_IMC);
+ outb(imc | IMC_PCIM, s->io+IT_AC_IMC);
+
+ db->stopped = 1;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void start_dac(struct it8172_state *s)
+{
+ struct dmabuf* db = &s->dma_dac;
+ unsigned long flags;
+ unsigned char imc;
+ unsigned long buf1, buf2;
+
+ if (!db->stopped)
+ return;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ // reset Buffer 1 and 2 pointers to nextOut and nextOut+fragsize
+ buf1 = virt_to_bus(db->nextOut);
+ buf2 = buf1 + db->fragsize;
+ if (buf2 >= db->dmaaddr + db->dmasize)
+ buf2 -= db->dmasize;
+
+ outl(buf1, s->io+IT_AC_PCB1STA);
+ outl(buf2, s->io+IT_AC_PCB2STA);
+ db->curBufPtr = IT_AC_PCB1STA;
+
+ // enable playback interrupt
+ imc = inb(s->io+IT_AC_IMC);
+ outb(imc & ~IMC_PCIM, s->io+IT_AC_IMC);
+
+ s->pcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+ s->pcc |= CC_CA;
+ outw(s->pcc, s->io+IT_AC_PCC);
+
+ db->stopped = 0;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void start_adc(struct it8172_state *s)
+{
+ struct dmabuf* db = &s->dma_adc;
+ unsigned long flags;
+ unsigned char imc;
+ unsigned long buf1, buf2;
+
+ if (!db->stopped)
+ return;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ // reset Buffer 1 and 2 pointers to nextIn and nextIn+fragsize
+ buf1 = virt_to_bus(db->nextIn);
+ buf2 = buf1 + db->fragsize;
+ if (buf2 >= db->dmaaddr + db->dmasize)
+ buf2 -= db->dmasize;
+
+ outl(buf1, s->io+IT_AC_CAPB1STA);
+ outl(buf2, s->io+IT_AC_CAPB2STA);
+ db->curBufPtr = IT_AC_CAPB1STA;
+
+ // enable capture interrupt
+ imc = inb(s->io+IT_AC_IMC);
+ outb(imc & ~IMC_CCIM, s->io+IT_AC_IMC);
+
+ s->capcc &= ~(CC_CSP | CC_CP | CC_CB2L | CC_CB1L);
+ s->capcc |= CC_CA;
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+
+ db->stopped = 0;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct it8172_state *s, struct dmabuf *db)
+{
+ struct page *page, *pend;
+
+ if (db->rawbuf) {
+ /* undo marking the pages as reserved */
+ pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+ for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+ mem_map_unreserve(page);
+ pci_free_consistent(s->dev, PAGE_SIZE << db->buforder,
+ db->rawbuf, db->dmaaddr);
+ }
+ db->rawbuf = db->nextIn = db->nextOut = NULL;
+ db->mapped = db->ready = 0;
+}
+
+static int prog_dmabuf(struct it8172_state *s, struct dmabuf *db,
+ unsigned rate, unsigned fmt, unsigned reg)
+{
+ int order;
+ unsigned bytepersec;
+ unsigned bufs;
+ struct page *page, *pend;
+
+ if (!db->rawbuf) {
+ db->ready = db->mapped = 0;
+ for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+ if ((db->rawbuf = pci_alloc_consistent(s->dev,
+ PAGE_SIZE << order,
+ &db->dmaaddr)))
+ break;
+ if (!db->rawbuf)
+ return -ENOMEM;
+ db->buforder = order;
+ /* now mark the pages as reserved;
+ otherwise remap_page_range doesn't do what we want */
+ pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+ for (page = virt_to_page(db->rawbuf); page <= pend; page++)
+ mem_map_reserve(page);
+ }
+
+ db->count = 0;
+ db->nextIn = db->nextOut = db->rawbuf;
+
+ bytepersec = rate << sample_shift[fmt];
+ bufs = PAGE_SIZE << db->buforder;
+ if (db->ossfragshift) {
+ if ((1000 << db->ossfragshift) < bytepersec)
+ db->fragshift = ld2(bytepersec/1000);
+ else
+ db->fragshift = db->ossfragshift;
+ } else {
+ db->fragshift = ld2(bytepersec/100/(db->subdivision ?
+ db->subdivision : 1));
+ if (db->fragshift < 3)
+ db->fragshift = 3;
+ }
+ db->numfrag = bufs >> db->fragshift;
+ while (db->numfrag < 4 && db->fragshift > 3) {
+ db->fragshift--;
+ db->numfrag = bufs >> db->fragshift;
+ }
+ db->fragsize = 1 << db->fragshift;
+ if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag)
+ db->numfrag = db->ossmaxfrags;
+ db->fragsamples = db->fragsize >> sample_shift[fmt];
+ db->dmasize = db->numfrag << db->fragshift;
+ memset(db->rawbuf, (fmt & (CC_DF>>CC_FMT_BIT)) ? 0 : 0x80, db->dmasize);
+
+ // set data length register
+ outw(db->fragsize, s->io+reg+2);
+ db->ready = 1;
+
+ return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct it8172_state *s)
+{
+ stop_adc(s);
+ return prog_dmabuf(s, &s->dma_adc, s->adcrate,
+ (s->capcc & CC_FMT_MASK) >> CC_FMT_BIT,
+ IT_AC_CAPCC);
+}
+
+extern inline int prog_dmabuf_dac(struct it8172_state *s)
+{
+ stop_dac(s);
+ return prog_dmabuf(s, &s->dma_dac, s->dacrate,
+ (s->pcc & CC_FMT_MASK) >> CC_FMT_BIT,
+ IT_AC_PCC);
+}
+
+
+/* hold spinlock for the following! */
+
+static void it8172_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct it8172_state *s = (struct it8172_state *)dev_id;
+ struct dmabuf* dac = &s->dma_dac;
+ struct dmabuf* adc = &s->dma_adc;
+ unsigned char isc, vs;
+ unsigned short vol, mute;
+ unsigned long newptr;
+
+ spin_lock(&s->lock);
+
+ isc = inb(s->io+IT_AC_ISC);
+
+ /* fastpath out, to ease interrupt sharing */
+ if (!(isc & (ISC_VCI | ISC_CCI | ISC_PCI)))
+ return;
+
+ /* clear audio interrupts first */
+ outb(isc | ISC_VCI | ISC_CCI | ISC_PCI, s->io+IT_AC_ISC);
+
+ /* handle volume button events */
+ if (isc & ISC_VCI) {
+ vs = inb(s->io+IT_AC_VS);
+ outb(0, s->io+IT_AC_VS);
+ vol = inw(s->io+IT_AC_PCMOV);
+ mute = vol & PCMOV_PCMOM;
+ vol &= PCMOV_PCMLCG_MASK;
+ if ((vs & VS_VUP) && vol > 0)
+ vol--;
+ if ((vs & VS_VDP) && vol < 0x1f)
+ vol++;
+ vol |= (vol << PCMOV_PCMRCG_BIT);
+ if (vs & VS_VMP)
+ vol |= (mute ^ PCMOV_PCMOM);
+ outw(vol, s->io+IT_AC_PCMOV);
+ }
+
+ /* update capture pointers */
+ if (isc & ISC_CCI) {
+ if (adc->count > adc->dmasize - adc->fragsize) {
+ // Overrun. Stop ADC and log the error
+ stop_adc(s);
+ adc->error++;
+ printk(KERN_INFO PFX "adc overrun\n");
+ } else {
+ newptr = virt_to_bus(adc->nextIn) + 2*adc->fragsize;
+ if (newptr >= adc->dmaaddr + adc->dmasize)
+ newptr -= adc->dmasize;
+
+ outl(newptr, s->io+adc->curBufPtr);
+ adc->curBufPtr = (adc->curBufPtr == IT_AC_CAPB1STA) ?
+ IT_AC_CAPB2STA : IT_AC_CAPB1STA;
+
+ adc->nextIn += adc->fragsize;
+ if (adc->nextIn >= adc->rawbuf + adc->dmasize)
+ adc->nextIn -= adc->dmasize;
+
+ adc->count += adc->fragsize;
+ adc->total_bytes += adc->fragsize;
+
+ /* wake up anybody listening */
+ if (waitqueue_active(&adc->wait))
+ wake_up_interruptible(&adc->wait);
+ }
+ }
+
+ /* update playback pointers */
+ if (isc & ISC_PCI) {
+ newptr = virt_to_bus(dac->nextOut) + 2*dac->fragsize;
+ if (newptr >= dac->dmaaddr + dac->dmasize)
+ newptr -= dac->dmasize;
+
+ outl(newptr, s->io+dac->curBufPtr);
+ dac->curBufPtr = (dac->curBufPtr == IT_AC_PCB1STA) ?
+ IT_AC_PCB2STA : IT_AC_PCB1STA;
+
+ dac->nextOut += dac->fragsize;
+ if (dac->nextOut >= dac->rawbuf + dac->dmasize)
+ dac->nextOut -= dac->dmasize;
+
+ dac->count -= dac->fragsize;
+ dac->total_bytes += dac->fragsize;
+
+ /* wake up anybody listening */
+ if (waitqueue_active(&dac->wait))
+ wake_up_interruptible(&dac->wait);
+
+ if (dac->count <= 0)
+ stop_dac(s);
+ }
+
+ spin_unlock(&s->lock);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t it8172_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+
+static int it8172_open_mixdev(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+ struct list_head *list;
+ struct it8172_state *s;
+
+ for (list = devs.next; ; list = list->next) {
+ if (list == &devs)
+ return -ENODEV;
+ s = list_entry(list, struct it8172_state, devs);
+ if (s->codec.dev_mixer == minor)
+ break;
+ }
+ file->private_data = s;
+ return 0;
+}
+
+static int it8172_release_mixdev(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+ unsigned long arg)
+{
+ return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int it8172_ioctl_mixdev(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+ struct ac97_codec *codec = &s->codec;
+
+ return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations it8172_mixer_fops = {
+ owner: THIS_MODULE,
+ llseek: it8172_llseek,
+ ioctl: it8172_ioctl_mixdev,
+ open: it8172_open_mixdev,
+ release: it8172_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct it8172_state *s, int nonblock)
+{
+ unsigned long flags;
+ int count, tmo;
+
+ if (s->dma_dac.mapped || !s->dma_dac.ready)
+ return 0;
+
+ for (;;) {
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count <= 0)
+ break;
+ if (signal_pending(current))
+ break;
+ if (nonblock)
+ return -EBUSY;
+ tmo = 1000 * count / s->dacrate;
+ tmo >>= sample_shift[(s->pcc & CC_FMT_MASK) >> CC_FMT_BIT];
+ it8172_delay(tmo);
+ }
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static ssize_t it8172_read(struct file *file, char *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+ struct dmabuf *db = &s->dma_adc;
+ ssize_t ret;
+ unsigned long flags;
+ int cnt, bufcnt, avail;
+
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ if (db->mapped)
+ return -ENXIO;
+ if (!access_ok(VERIFY_WRITE, buffer, count))
+ return -EFAULT;
+ ret = 0;
+
+ while (count > 0) {
+ // wait for samples in capture buffer
+ do {
+ spin_lock_irqsave(&s->lock, flags);
+ if (db->stopped)
+ start_adc(s);
+ avail = db->count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (avail <= 0) {
+ if (file->f_flags & O_NONBLOCK) {
+ if (!ret)
+ ret = -EAGAIN;
+ return ret;
+ }
+ interruptible_sleep_on(&db->wait);
+ if (signal_pending(current)) {
+ if (!ret)
+ ret = -ERESTARTSYS;
+ return ret;
+ }
+ }
+ } while (avail <= 0);
+
+ cnt = count > avail ? avail : count;
+ bufcnt = cnt;
+ if (cnt % db->fragsize) {
+ // round count up to nearest fragment
+ int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
+ cnt = newcnt;
+ }
+
+ // copy from nextOut to user
+ if (copy_to_user(buffer, db->nextOut, bufcnt)) {
+ if (!ret)
+ ret = -EFAULT;
+ return ret;
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+ db->count -= cnt;
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ db->nextOut += cnt;
+ if (db->nextOut >= db->rawbuf + db->dmasize)
+ db->nextOut -= db->dmasize;
+
+ count -= bufcnt;
+ buffer += bufcnt;
+ ret += bufcnt;
+ } // while (count > 0)
+
+ return ret;
+}
+
+static ssize_t it8172_write(struct file *file, const char *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+ struct dmabuf *db = &s->dma_dac;
+ ssize_t ret;
+ unsigned long flags;
+ int cnt, bufcnt, avail;
+
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ if (db->mapped)
+ return -ENXIO;
+ if (!access_ok(VERIFY_READ, buffer, count))
+ return -EFAULT;
+ ret = 0;
+
+ while (count > 0) {
+ // wait for space in playback buffer
+ do {
+ spin_lock_irqsave(&s->lock, flags);
+ avail = db->dmasize - db->count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (avail <= 0) {
+ if (file->f_flags & O_NONBLOCK) {
+ if (!ret)
+ ret = -EAGAIN;
+ return ret;
+ }
+ interruptible_sleep_on(&db->wait);
+ if (signal_pending(current)) {
+ if (!ret)
+ ret = -ERESTARTSYS;
+ return ret;
+ }
+ }
+ } while (avail <= 0);
+
+ cnt = count > avail ? avail : count;
+ // copy to nextIn
+ if (copy_from_user(db->nextIn, buffer, cnt)) {
+ if (!ret)
+ ret = -EFAULT;
+ return ret;
+ }
+
+ bufcnt = cnt;
+ if (cnt % db->fragsize) {
+ // round count up to nearest fragment, and fill remainder of
+ // fragment with silence
+ int newcnt = db->fragsize * ((cnt + db->fragsize) / db->fragsize);
+ memset(db->nextIn + cnt, (s->pcc & CC_DF) ? 0 : 0x80, newcnt - cnt);
+ cnt = newcnt;
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+ db->count += cnt;
+ if (db->stopped)
+ start_dac(s);
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ db->nextIn += cnt;
+ if (db->nextIn >= db->rawbuf + db->dmasize)
+ db->nextIn -= db->dmasize;
+
+ count -= bufcnt;
+ buffer += bufcnt;
+ ret += bufcnt;
+ } // while (count > 0)
+
+ return ret;
+}
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int it8172_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+ unsigned long flags;
+ unsigned int mask = 0;
+
+ if (file->f_mode & FMODE_WRITE)
+ poll_wait(file, &s->dma_dac.wait, wait);
+ if (file->f_mode & FMODE_READ)
+ poll_wait(file, &s->dma_adc.wait, wait);
+ spin_lock_irqsave(&s->lock, flags);
+ if (file->f_mode & FMODE_READ) {
+ if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+ mask |= POLLIN | POLLRDNORM;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ if (s->dma_dac.mapped) {
+ if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
+ mask |= POLLOUT | POLLWRNORM;
+ } else {
+ if ((signed)s->dma_dac.dmasize >=
+ s->dma_dac.count + (signed)s->dma_dac.fragsize)
+ mask |= POLLOUT | POLLWRNORM;
+ }
+ }
+ spin_unlock_irqrestore(&s->lock, flags);
+ return mask;
+}
+
+static int it8172_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+ struct dmabuf *db;
+ unsigned long size;
+
+ lock_kernel();
+ if (vma->vm_flags & VM_WRITE)
+ db = &s->dma_dac;
+ else if (vma->vm_flags & VM_READ)
+ db = &s->dma_adc;
+ else {
+ unlock_kernel();
+ return -EINVAL;
+ }
+ if (vma->vm_pgoff != 0) {
+ unlock_kernel();
+ return -EINVAL;
+ }
+ size = vma->vm_end - vma->vm_start;
+ if (size > (PAGE_SIZE << db->buforder)) {
+ unlock_kernel();
+ return -EINVAL;
+ }
+ if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf),
+ size, vma->vm_page_prot)) {
+ unlock_kernel();
+ return -EAGAIN;
+ }
+ db->mapped = 1;
+ unlock_kernel();
+ return 0;
+}
+
+
+#ifdef IT8172_VERBOSE_DEBUG
+static struct ioctl_str_t {
+ unsigned int cmd;
+ const char* str;
+} ioctl_str[] = {
+ {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+ {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+ {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+ {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+ {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+ {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+ {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+ {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+ {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+ {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+ {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+ {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+ {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+ {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+ {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+ {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+ {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+ {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+ {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+ {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+ {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+ {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+ {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+ {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+ {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+ {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+ {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+ {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+ {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+ {OSS_GETVERSION, "OSS_GETVERSION"},
+ {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+ {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+ {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+ {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif
+
+static int it8172_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+ unsigned long flags;
+ audio_buf_info abinfo;
+ count_info cinfo;
+ int count;
+ int val, mapped, ret, diff;
+
+ mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+ ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+
+#ifdef IT8172_VERBOSE_DEBUG
+ for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+ if (ioctl_str[count].cmd == cmd)
+ break;
+ }
+ if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+ printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
+ else
+ printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+#endif
+
+ switch (cmd) {
+ case OSS_GETVERSION:
+ return put_user(SOUND_VERSION, (int *)arg);
+
+ case SNDCTL_DSP_SYNC:
+ if (file->f_mode & FMODE_WRITE)
+ return drain_dac(s, file->f_flags & O_NONBLOCK);
+ return 0;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ return 0;
+
+ case SNDCTL_DSP_GETCAPS:
+ return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME |
+ DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+ case SNDCTL_DSP_RESET:
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ synchronize_irq();
+ s->dma_dac.count = s->dma_dac.total_bytes = 0;
+ s->dma_dac.nextIn = s->dma_dac.nextOut = s->dma_dac.rawbuf;
+ }
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ synchronize_irq();
+ s->dma_adc.count = s->dma_adc.total_bytes = 0;
+ s->dma_adc.nextIn = s->dma_adc.nextOut = s->dma_adc.rawbuf;
+ }
+ return 0;
+
+ case SNDCTL_DSP_SPEED:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val >= 0) {
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ set_adc_rate(s, val);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ set_dac_rate(s, val);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ }
+ return put_user((file->f_mode & FMODE_READ) ?
+ s->adcrate : s->dacrate, (int *)arg);
+
+ case SNDCTL_DSP_STEREO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ if (val)
+ s->capcc |= CC_SM;
+ else
+ s->capcc &= ~CC_SM;
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ if (val)
+ s->pcc |= CC_SM;
+ else
+ s->pcc &= ~CC_SM;
+ outw(s->pcc, s->io+IT_AC_PCC);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ return 0;
+
+ case SNDCTL_DSP_CHANNELS:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != 0) {
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ if (val >= 2) {
+ val = 2;
+ s->capcc |= CC_SM;
+ }
+ else
+ s->capcc &= ~CC_SM;
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ switch (val) {
+ case 1:
+ s->pcc &= ~CC_SM;
+ break;
+ case 2:
+ s->pcc |= CC_SM;
+ break;
+ default:
+ // FIX! support multichannel???
+ val = 2;
+ s->pcc |= CC_SM;
+ break;
+ }
+ outw(s->pcc, s->io+IT_AC_PCC);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ }
+ return put_user(val, (int *)arg);
+
+ case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+ return put_user(AFMT_S16_LE|AFMT_U8, (int *)arg);
+
+ case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != AFMT_QUERY) {
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ if (val == AFMT_S16_LE)
+ s->capcc |= CC_DF;
+ else {
+ val = AFMT_U8;
+ s->capcc &= ~CC_DF;
+ }
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ if (val == AFMT_S16_LE)
+ s->pcc |= CC_DF;
+ else {
+ val = AFMT_U8;
+ s->pcc &= ~CC_DF;
+ }
+ outw(s->pcc, s->io+IT_AC_PCC);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ } else {
+ if (file->f_mode & FMODE_READ)
+ val = (s->capcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
+ else
+ val = (s->pcc & CC_DF) ? AFMT_S16_LE : AFMT_U8;
+ }
+ return put_user(val, (int *)arg);
+
+ case SNDCTL_DSP_POST:
+ return 0;
+
+ case SNDCTL_DSP_GETTRIGGER:
+ val = 0;
+ spin_lock_irqsave(&s->lock, flags);
+ if (file->f_mode & FMODE_READ && !s->dma_adc.stopped)
+ val |= PCM_ENABLE_INPUT;
+ if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped)
+ val |= PCM_ENABLE_OUTPUT;
+ spin_unlock_irqrestore(&s->lock, flags);
+ return put_user(val, (int *)arg);
+
+ case SNDCTL_DSP_SETTRIGGER:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (file->f_mode & FMODE_READ) {
+ if (val & PCM_ENABLE_INPUT)
+ start_adc(s);
+ else
+ stop_adc(s);
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ if (val & PCM_ENABLE_OUTPUT)
+ start_dac(s);
+ else
+ stop_dac(s);
+ }
+ return 0;
+
+ case SNDCTL_DSP_GETOSPACE:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;
+ abinfo.fragsize = s->dma_dac.fragsize;
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ if (!s->dma_dac.stopped)
+ count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count < 0)
+ count = 0;
+ abinfo.bytes = s->dma_dac.dmasize - count;
+ abinfo.fragstotal = s->dma_dac.numfrag;
+ abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;
+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+ case SNDCTL_DSP_GETISPACE:
+ if (!(file->f_mode & FMODE_READ))
+ return -EINVAL;
+ abinfo.fragsize = s->dma_adc.fragsize;
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_adc.count;
+ if (!s->dma_adc.stopped)
+ count += (s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL));
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count < 0)
+ count = 0;
+ abinfo.bytes = count;
+ abinfo.fragstotal = s->dma_adc.numfrag;
+ abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+ case SNDCTL_DSP_NONBLOCK:
+ file->f_flags |= O_NONBLOCK;
+ return 0;
+
+ case SNDCTL_DSP_GETODELAY:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ if (!s->dma_dac.stopped)
+ count -= (s->dma_dac.fragsize - inw(s->io+IT_AC_PCDL));
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count < 0)
+ count = 0;
+ return put_user(count, (int *)arg);
+
+ case SNDCTL_DSP_GETIPTR:
+ if (!(file->f_mode & FMODE_READ))
+ return -EINVAL;
+ spin_lock_irqsave(&s->lock, flags);
+ cinfo.bytes = s->dma_adc.total_bytes;
+ count = s->dma_adc.count;
+ if (!s->dma_adc.stopped) {
+ diff = s->dma_adc.fragsize - inw(s->io+IT_AC_CAPCDL);
+ count += diff;
+ cinfo.bytes += diff;
+ cinfo.ptr = inl(s->io+s->dma_adc.curBufPtr) - s->dma_adc.dmaaddr;
+ } else
+ cinfo.ptr = virt_to_bus(s->dma_adc.nextIn) - s->dma_adc.dmaaddr;
+ if (s->dma_adc.mapped)
+ s->dma_adc.count &= s->dma_adc.fragsize-1;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count < 0)
+ count = 0;
+ cinfo.blocks = count >> s->dma_adc.fragshift;
+ return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+ case SNDCTL_DSP_GETOPTR:
+ if (!(file->f_mode & FMODE_READ))
+ return -EINVAL;
+ spin_lock_irqsave(&s->lock, flags);
+ cinfo.bytes = s->dma_dac.total_bytes;
+ count = s->dma_dac.count;
+ if (!s->dma_dac.stopped) {
+ diff = s->dma_dac.fragsize - inw(s->io+IT_AC_CAPCDL);
+ count -= diff;
+ cinfo.bytes += diff;
+ cinfo.ptr = inl(s->io+s->dma_dac.curBufPtr) - s->dma_dac.dmaaddr;
+ } else
+ cinfo.ptr = virt_to_bus(s->dma_dac.nextOut) - s->dma_dac.dmaaddr;
+ if (s->dma_dac.mapped)
+ s->dma_dac.count &= s->dma_dac.fragsize-1;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count < 0)
+ count = 0;
+ cinfo.blocks = count >> s->dma_dac.fragshift;
+ return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+ case SNDCTL_DSP_GETBLKSIZE:
+ if (file->f_mode & FMODE_WRITE)
+ return put_user(s->dma_dac.fragsize, (int *)arg);
+ else
+ return put_user(s->dma_adc.fragsize, (int *)arg);
+
+ case SNDCTL_DSP_SETFRAGMENT:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ s->dma_adc.ossfragshift = val & 0xffff;
+ s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff;
+ if (s->dma_adc.ossfragshift < 4)
+ s->dma_adc.ossfragshift = 4;
+ if (s->dma_adc.ossfragshift > 15)
+ s->dma_adc.ossfragshift = 15;
+ if (s->dma_adc.ossmaxfrags < 4)
+ s->dma_adc.ossmaxfrags = 4;
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ s->dma_dac.ossfragshift = val & 0xffff;
+ s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff;
+ if (s->dma_dac.ossfragshift < 4)
+ s->dma_dac.ossfragshift = 4;
+ if (s->dma_dac.ossfragshift > 15)
+ s->dma_dac.ossfragshift = 15;
+ if (s->dma_dac.ossmaxfrags < 4)
+ s->dma_dac.ossmaxfrags = 4;
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ return 0;
+
+ case SNDCTL_DSP_SUBDIVIDE:
+ if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+ (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+ return -EINVAL;
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != 1 && val != 2 && val != 4)
+ return -EINVAL;
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ s->dma_adc.subdivision = val;
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ s->dma_dac.subdivision = val;
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ return 0;
+
+ case SOUND_PCM_READ_RATE:
+ return put_user((file->f_mode & FMODE_READ) ?
+ s->adcrate : s->dacrate, (int *)arg);
+
+ case SOUND_PCM_READ_CHANNELS:
+ if (file->f_mode & FMODE_READ)
+ return put_user((s->capcc & CC_SM) ? 2 : 1, (int *)arg);
+ else
+ return put_user((s->pcc & CC_SM) ? 2 : 1, (int *)arg);
+
+ case SOUND_PCM_READ_BITS:
+ if (file->f_mode & FMODE_READ)
+ return put_user((s->capcc & CC_DF) ? 16 : 8, (int *)arg);
+ else
+ return put_user((s->pcc & CC_DF) ? 16 : 8, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
+ case SOUND_PCM_READ_FILTER:
+ return -EINVAL;
+ }
+
+ return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int it8172_open(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+ struct list_head *list;
+ struct it8172_state *s;
+ int ret;
+
+ for (list = devs.next; ; list = list->next) {
+ if (list == &devs)
+ return -ENODEV;
+ s = list_entry(list, struct it8172_state, devs);
+ if (!((s->dev_audio ^ minor) & ~0xf))
+ break;
+ }
+ file->private_data = s;
+ /* wait for device to become free */
+ down(&s->open_sem);
+ while (s->open_mode & file->f_mode) {
+ if (file->f_flags & O_NONBLOCK) {
+ up(&s->open_sem);
+ return -EBUSY;
+ }
+ add_wait_queue(&s->open_wait, &wait);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ up(&s->open_sem);
+ schedule();
+ remove_wait_queue(&s->open_wait, &wait);
+ set_current_state(TASK_RUNNING);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ down(&s->open_sem);
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (file->f_mode & FMODE_READ) {
+ s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags =
+ s->dma_adc.subdivision = s->dma_adc.total_bytes = 0;
+ s->capcc &= ~(CC_SM | CC_DF);
+ set_adc_rate(s, 8000);
+ if ((minor & 0xf) == SND_DEV_DSP16)
+ s->capcc |= CC_DF;
+ outw(s->capcc, s->io+IT_AC_CAPCC);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags =
+ s->dma_dac.subdivision = s->dma_dac.total_bytes = 0;
+ s->pcc &= ~(CC_SM | CC_DF);
+ set_dac_rate(s, 8000);
+ if ((minor & 0xf) == SND_DEV_DSP16)
+ s->pcc |= CC_DF;
+ outw(s->pcc, s->io+IT_AC_PCC);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+ up(&s->open_sem);
+ return 0;
+}
+
+static int it8172_release(struct inode *inode, struct file *file)
+{
+ struct it8172_state *s = (struct it8172_state *)file->private_data;
+
+ lock_kernel();
+ if (file->f_mode & FMODE_WRITE)
+ drain_dac(s, file->f_flags & O_NONBLOCK);
+ down(&s->open_sem);
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ dealloc_dmabuf(s, &s->dma_dac);
+ }
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ dealloc_dmabuf(s, &s->dma_adc);
+ }
+ s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+ up(&s->open_sem);
+ wake_up(&s->open_wait);
+ unlock_kernel();
+ return 0;
+}
+
+static /*const*/ struct file_operations it8172_audio_fops = {
+ owner: THIS_MODULE,
+ llseek: it8172_llseek,
+ read: it8172_read,
+ write: it8172_write,
+ poll: it8172_poll,
+ ioctl: it8172_ioctl,
+ mmap: it8172_mmap,
+ open: it8172_open,
+ release: it8172_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef IT8172_DEBUG
+static int proc_it8172_dump (char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data)
+{
+ struct it8172_state *s;
+ int cnt, len = 0;
+
+ if (list_empty(&devs))
+ return 0;
+ s = list_entry(devs.next, struct it8172_state, devs);
+
+ /* print out header */
+ len += sprintf(buf + len, "\n\t\tIT8172 Audio Debug\n\n");
+
+ // print out digital controller state
+ len += sprintf (buf + len, "IT8172 Audio Controller registers\n");
+ len += sprintf (buf + len, "---------------------------------\n");
+ cnt=0;
+ while (cnt < 0x72) {
+ if (cnt == IT_AC_PCB1STA || cnt == IT_AC_PCB2STA ||
+ cnt == IT_AC_CAPB1STA || cnt == IT_AC_CAPB2STA ||
+ cnt == IT_AC_PFDP) {
+ len+= sprintf (buf + len, "reg %02x = %08x\n",
+ cnt, inl(s->io+cnt));
+ cnt += 4;
+ } else {
+ len+= sprintf (buf + len, "reg %02x = %04x\n",
+ cnt, inw(s->io+cnt));
+ cnt += 2;
+ }
+ }
+
+ /* print out CODEC state */
+ len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+ len += sprintf (buf + len, "----------------------\n");
+ for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+ len+= sprintf (buf + len, "reg %02x = %04x\n",
+ cnt, rdcodec(&s->codec, cnt));
+
+ if (fpos >=len){
+ *start = buf;
+ *eof =1;
+ return 0;
+ }
+ *start = buf + fpos;
+ if ((len -= fpos) > length)
+ return length;
+ *eof =1;
+ return len;
+
+}
+#endif /* IT8172_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+/* maximum number of devices; only used for command line params */
+#define NR_DEVICE 5
+
+static int spdif[NR_DEVICE] = { 0, };
+
+static unsigned int devindex = 0;
+
+MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(spdif, "if 1 the S/PDIF digital output is enabled");
+
+MODULE_AUTHOR("Monta Vista Software, stevel@mvista.com");
+MODULE_DESCRIPTION("IT8172 AudioPCI97 Driver");
+
+/* --------------------------------------------------------------------- */
+
+static int __devinit it8172_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *pciid)
+{
+ struct it8172_state *s;
+ int i, val;
+ unsigned short pcisr, vol;
+ unsigned char legacy, imc;
+ char proc_str[80];
+
+ if (pcidev->irq == 0)
+ return -1;
+
+ if (!(s = kmalloc(sizeof(struct it8172_state), GFP_KERNEL))) {
+ printk(KERN_ERR PFX "alloc of device struct failed\n");
+ return -1;
+ }
+
+ memset(s, 0, sizeof(struct it8172_state));
+ init_waitqueue_head(&s->dma_adc.wait);
+ init_waitqueue_head(&s->dma_dac.wait);
+ init_waitqueue_head(&s->open_wait);
+ init_MUTEX(&s->open_sem);
+ spin_lock_init(&s->lock);
+ s->dev = pcidev;
+ s->io = pci_resource_start(pcidev, 0);
+ s->irq = pcidev->irq;
+ s->vendor = pcidev->vendor;
+ s->device = pcidev->device;
+ pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
+ s->codec.private_data = s;
+ s->codec.id = 0;
+ s->codec.codec_read = rdcodec;
+ s->codec.codec_write = wrcodec;
+ s->codec.codec_wait = waitcodec;
+
+ if (!request_region(s->io, pci_resource_len(pcidev,0),
+ IT8172_MODULE_NAME)) {
+ printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+ s->io, s->io + pci_resource_len(pcidev,0)-1);
+ goto err_region;
+ }
+ if (request_irq(s->irq, it8172_interrupt, SA_INTERRUPT,
+ IT8172_MODULE_NAME, s)) {
+ printk(KERN_ERR PFX "irq %u in use\n", s->irq);
+ goto err_irq;
+ }
+
+ printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
+
+ /* register devices */
+ if ((s->dev_audio = register_sound_dsp(&it8172_audio_fops, -1)) < 0)
+ goto err_dev1;
+ if ((s->codec.dev_mixer =
+ register_sound_mixer(&it8172_mixer_fops, -1)) < 0)
+ goto err_dev2;
+
+#ifdef IT8172_DEBUG
+ /* intialize the debug proc device */
+ s->ps = create_proc_read_entry(IT8172_MODULE_NAME, 0, NULL,
+ proc_it8172_dump, NULL);
+#endif /* IT8172_DEBUG */
+
+ /*
+ * Reset the Audio device using the IT8172 PCI Reset register. This
+ * creates an audible double click on a speaker connected to Line-out.
+ */
+ IT_IO_READ16(IT_PM_PCISR, pcisr);
+ pcisr |= IT_PM_PCISR_ACSR;
+ IT_IO_WRITE16(IT_PM_PCISR, pcisr);
+ /* wait up to 100msec for reset to complete */
+ for (i=0; pcisr & IT_PM_PCISR_ACSR; i++) {
+ it8172_delay(10);
+ if (i == 10)
+ break;
+ IT_IO_READ16(IT_PM_PCISR, pcisr);
+ }
+ if (i == 10) {
+ printk(KERN_ERR PFX "chip reset timeout!\n");
+ goto err_dev3;
+ }
+
+ /* enable pci io and bus mastering */
+ if (pci_enable_device(pcidev))
+ goto err_dev3;
+ pci_set_master(pcidev);
+
+ /* get out of legacy mode */
+ pci_read_config_byte (pcidev, 0x40, &legacy);
+ pci_write_config_byte (pcidev, 0x40, legacy & ~1);
+
+ s->spdif_volume = -1;
+ /* check to see if s/pdif mode is being requested */
+ if (spdif[devindex]) {
+ printk(KERN_INFO PFX "enabling S/PDIF output\n");
+ s->spdif_volume = 0;
+ outb(GC_SOE, s->io+IT_AC_GC);
+ } else {
+ printk(KERN_INFO PFX "disabling S/PDIF output\n");
+ outb(0, s->io+IT_AC_GC);
+ }
+
+ /* cold reset the AC97 */
+ outw(CODECC_CR, s->io+IT_AC_CODECC);
+ udelay(1000);
+ outw(0, s->io+IT_AC_CODECC);
+ /* need to delay around 500msec(bleech) to give
+ some CODECs enough time to wakeup */
+ it8172_delay(500);
+
+ /* AC97 warm reset to start the bitclk */
+ outw(CODECC_WR, s->io+IT_AC_CODECC);
+ udelay(1000);
+ outw(0, s->io+IT_AC_CODECC);
+
+ /* codec init */
+ if (!ac97_probe_codec(&s->codec))
+ goto err_dev3;
+
+ /* Enable Volume button interrupts */
+ imc = inb(s->io+IT_AC_IMC);
+ outb(imc & ~IMC_VCIM, s->io+IT_AC_IMC);
+
+ /* Un-mute PCM and FM out on the controller */
+ vol = inw(s->io+IT_AC_PCMOV);
+ outw(vol & ~PCMOV_PCMOM, s->io+IT_AC_PCMOV);
+ vol = inw(s->io+IT_AC_FMOV);
+ outw(vol & ~FMOV_FMOM, s->io+IT_AC_FMOV);
+
+ /* set channel defaults to 8-bit, mono, 8 Khz */
+ s->pcc = 0;
+ s->capcc = 0;
+ set_dac_rate(s, 8000);
+ set_adc_rate(s, 8000);
+
+ /* set mic to be the recording source */
+ val = SOUND_MASK_MIC;
+ mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+
+ /* mute master and PCM when in S/PDIF mode */
+ if (s->spdif_volume != -1) {
+ val = 0x0000;
+ mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME,
+ (unsigned long)&val);
+ mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM,
+ (unsigned long)&val);
+ }
+
+#ifdef IT8172_DEBUG
+ sprintf(proc_str, "driver/%s/%d/ac97", IT8172_MODULE_NAME, s->codec.id);
+ s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+ ac97_read_proc, &s->codec);
+#endif
+
+ /* store it in the driver field */
+ pci_set_drvdata(pcidev, s);
+ pcidev->dma_mask = 0xffffffff;
+ /* put it into driver list */
+ list_add_tail(&s->devs, &devs);
+ /* increment devindex */
+ if (devindex < NR_DEVICE-1)
+ devindex++;
+ return 0;
+
+ err_dev3:
+ unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+ unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+ printk(KERN_ERR PFX "cannot register misc device\n");
+ free_irq(s->irq, s);
+ err_irq:
+ release_region(s->io, pci_resource_len(pcidev,0));
+ err_region:
+ kfree(s);
+ return -1;
+}
+
+static void __devinit it8172_remove(struct pci_dev *dev)
+{
+ struct it8172_state *s = pci_get_drvdata(dev);
+
+ if (!s)
+ return;
+ list_del(&s->devs);
+#ifdef IT8172_DEBUG
+ if (s->ps)
+ remove_proc_entry(IT8172_MODULE_NAME, NULL);
+#endif /* IT8172_DEBUG */
+ synchronize_irq();
+ free_irq(s->irq, s);
+ release_region(s->io, pci_resource_len(dev,0));
+ unregister_sound_dsp(s->dev_audio);
+ unregister_sound_mixer(s->codec.dev_mixer);
+ kfree(s);
+ pci_set_drvdata(dev, NULL);
+}
+
+
+
+static struct pci_device_id id_table[] __devinitdata = {
+ { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_IT8172G_AUDIO, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver it8172_driver = {
+ name: IT8172_MODULE_NAME,
+ id_table: id_table,
+ probe: it8172_probe,
+ remove: it8172_remove
+};
+
+static int __init init_it8172(void)
+{
+ if (!pci_present()) /* No PCI bus in this machine! */
+ return -ENODEV;
+ printk("version v0.26 time " __TIME__ " " __DATE__ "\n");
+ return pci_module_init(&it8172_driver);
+}
+
+static void __exit cleanup_it8172(void)
+{
+ printk(KERN_INFO PFX "unloading\n");
+ pci_unregister_driver(&it8172_driver);
+}
+
+module_init(init_it8172);
+module_exit(cleanup_it8172);
+
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv Exp $
+ * $Id: msnd_pinnacle.c,v 1.8 2000/12/30 00:33:21 sycamore Exp $
+ *
+ * 12-3-2000 Modified IO port validation Steve Sycamore
+ *
+ *
+ * $$$: msnd_pinnacle.c,v 1.75 1999/03/21 16:50:09 andrewtv $$$ $
*
********************************************************************/
if (io == -1 || irq == -1 || mem == -1)
printk(KERN_WARNING LOGNAME ": io, irq and mem must be set\n");
+#ifdef MSND_CLASSIC
if (io == -1 ||
!(io == 0x290 ||
io == 0x260 ||
printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must be set to 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x290, or 0x3E0\n");
return -EINVAL;
}
+#else
+ if (io == -1 ||
+ io < 0x100 ||
+ io > 0x3e0 ||
+ (io % 0x10) != 0) {
+ printk(KERN_ERR LOGNAME ": \"io\" - DSP I/O base must within the range 0x100 to 0x3E0 and must be evenly divisible by 0x10\n");
+ return -EINVAL;
+ }
+#endif /* MSND_CLASSIC */
if (irq == -1 ||
!(irq == 5 ||
--- /dev/null
+/***********************************************************************
+ * Copyright 2001 MontaVista Software Inc.
+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
+ *
+ * drivers/sound/nec_vrc5477.c
+ * AC97 sound dirver for NEC Vrc5477 chip (an integrated,
+ * multi-function controller chip for MIPS CPUs)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ ***********************************************************************
+ */
+
+/*
+ * This code is derived from ite8172.c, which is written by Steve Longerbeam.
+ *
+ * Features:
+ * Currently we only support the following capabilities:
+ * . mono output to PCM L/R (line out).
+ * . stereo output to PCM L/R (line out).
+ * . mono input from PCM L (line in).
+ * . stereo output from PCM (line in).
+ * . sampling rate at 48k or variable sampling rate
+ * . support /dev/dsp, /dev/mixer devices, standard OSS devices.
+ * . only support 16-bit PCM format (hardware limit, no software
+ * translation)
+ * . support duplex, but no trigger or realtime.
+ *
+ * Specifically the following are not supported:
+ * . app-set frag size.
+ * . mmap'ed buffer access
+ */
+
+/*
+ * Original comments from ite8172.c file.
+ */
+
+/*
+ *
+ * Notes:
+ *
+ * 1. Much of the OSS buffer allocation, ioctl's, and mmap'ing are
+ * taken, slightly modified or not at all, from the ES1371 driver,
+ * so refer to the credits in es1371.c for those. The rest of the
+ * code (probe, open, read, write, the ISR, etc.) is new.
+ * 2. The following support is untested:
+ * * Memory mapping the audio buffers, and the ioctl controls that go
+ * with it.
+ * * S/PDIF output.
+ * 3. The following is not supported:
+ * * I2S input.
+ * * legacy audio mode.
+ * 4. Support for volume button interrupts is implemented but doesn't
+ * work yet.
+ *
+ * Revision history
+ * 02.08.2001 0.1 Initial release
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/bitops.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/ac97_codec.h>
+#include <linux/wrapper.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#include <asm/ddb5xxx/debug.h>
+
+#undef VRC5477_AC97_VERBOSE_DEBUG
+
+/* one must turn on CONFIG_LL_DEBUG before VERBOSE_DEBUG is turned */
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+#if !defined(CONFIG_LL_DEBUG)
+#error "You must turn CONFIG_LL_DEBUG"
+#endif
+#endif
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+static u16 inTicket=0; /* check sync between intr & write */
+static u16 outTicket=0;
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+#define VRC5477_INT_CLR 0x0
+#define VRC5477_INT_STATUS 0x0
+#define VRC5477_CODEC_WR 0x4
+#define VRC5477_CODEC_RD 0x8
+#define VRC5477_CTRL 0x18
+#define VRC5477_ACLINK_CTRL 0x1c
+#define VRC5477_INT_MASK 0x24
+
+#define VRC5477_DAC1_CTRL 0x30
+#define VRC5477_DAC1L 0x34
+#define VRC5477_DAC1_BADDR 0x38
+#define VRC5477_DAC2_CTRL 0x3c
+#define VRC5477_DAC2L 0x40
+#define VRC5477_DAC2_BADDR 0x44
+#define VRC5477_DAC3_CTRL 0x48
+#define VRC5477_DAC3L 0x4c
+#define VRC5477_DAC3_BADDR 0x50
+
+#define VRC5477_ADC1_CTRL 0x54
+#define VRC5477_ADC1L 0x58
+#define VRC5477_ADC1_BADDR 0x5c
+#define VRC5477_ADC2_CTRL 0x60
+#define VRC5477_ADC2L 0x64
+#define VRC5477_ADC2_BADDR 0x68
+#define VRC5477_ADC3_CTRL 0x6c
+#define VRC5477_ADC3L 0x70
+#define VRC5477_ADC3_BADDR 0x74
+
+#define VRC5477_CODEC_WR_RWC (1 << 23)
+
+#define VRC5477_CODEC_RD_RRDYA (1 << 31)
+#define VRC5477_CODEC_RD_RRDYD (1 << 30)
+
+#define VRC5477_ACLINK_CTRL_RST_ON (1 << 15)
+#define VRC5477_ACLINK_CTRL_RST_TIME 0x7f
+#define VRC5477_ACLINK_CTRL_SYNC_ON (1 << 30)
+#define VRC5477_ACLINK_CTRL_CK_STOP_ON (1 << 31)
+
+#define VRC5477_CTRL_DAC2ENB (1 << 15)
+#define VRC5477_CTRL_ADC2ENB (1 << 14)
+#define VRC5477_CTRL_DAC1ENB (1 << 13)
+#define VRC5477_CTRL_ADC1ENB (1 << 12)
+
+#define VRC5477_INT_MASK_NMASK (1 << 31)
+#define VRC5477_INT_MASK_DAC1END (1 << 5)
+#define VRC5477_INT_MASK_DAC2END (1 << 4)
+#define VRC5477_INT_MASK_DAC3END (1 << 3)
+#define VRC5477_INT_MASK_ADC1END (1 << 2)
+#define VRC5477_INT_MASK_ADC2END (1 << 1)
+#define VRC5477_INT_MASK_ADC3END (1 << 0)
+
+#define VRC5477_DMA_ACTIVATION (1 << 31)
+#define VRC5477_DMA_WIP (1 << 30)
+
+
+#define VRC5477_AC97_MODULE_NAME "NEC_Vrc5477_audio"
+#define PFX VRC5477_AC97_MODULE_NAME ": "
+
+/* --------------------------------------------------------------------- */
+
+struct vrc5477_ac97_state {
+ /* list of vrc5477_ac97 devices */
+ struct list_head devs;
+
+ /* the corresponding pci_dev structure */
+ struct pci_dev *dev;
+
+ /* soundcore stuff */
+ int dev_audio;
+
+ /* hardware resources */
+ unsigned long io;
+ unsigned int irq;
+
+#ifdef CONFIG_LL_DEBUG
+ /* debug /proc entry */
+ struct proc_dir_entry *ps;
+ struct proc_dir_entry *ac97_ps;
+#endif /* CONFIG_LL_DEBUG */
+
+ struct ac97_codec codec;
+
+ unsigned dacChannels, adcChannels;
+ unsigned short dacRate, adcRate;
+
+ spinlock_t lock;
+ struct semaphore open_sem;
+ mode_t open_mode;
+ wait_queue_head_t open_wait;
+
+ struct dmabuf {
+ void *lbuf, *rbuf;
+ dma_addr_t lbufDma, rbufDma;
+ unsigned bufOrder;
+ unsigned numFrag;
+ unsigned fragShift;
+ unsigned fragSize; /* redundant */
+ unsigned fragTotalSize; /* = numFrag * fragSize(real) */
+ unsigned nextIn;
+ unsigned nextOut;
+ int count;
+ unsigned error; /* over/underrun */
+ wait_queue_head_t wait;
+ /* OSS stuff */
+ unsigned stopped:1;
+ unsigned ready:1;
+ } dma_dac, dma_adc;
+
+ #define WORK_BUF_SIZE 2048
+ struct {
+ u16 lchannel;
+ u16 rchannel;
+ } workBuf[WORK_BUF_SIZE/4];
+};
+
+/* --------------------------------------------------------------------- */
+
+static LIST_HEAD(devs);
+
+/* --------------------------------------------------------------------- */
+
+extern inline unsigned ld2(unsigned int x)
+{
+ unsigned r = 0;
+
+ if (x >= 0x10000) {
+ x >>= 16;
+ r += 16;
+ }
+ if (x >= 0x100) {
+ x >>= 8;
+ r += 8;
+ }
+ if (x >= 0x10) {
+ x >>= 4;
+ r += 4;
+ }
+ if (x >= 4) {
+ x >>= 2;
+ r += 2;
+ }
+ if (x >= 2)
+ r++;
+ return r;
+}
+
+/* --------------------------------------------------------------------- */
+
+static u16 rdcodec(struct ac97_codec *codec, u8 addr)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)codec->private_data;
+ unsigned long flags;
+ u32 result;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ /* wait until we can access codec registers */
+ while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+
+ /* write the address and "read" command to codec */
+ addr = addr & 0x7f;
+ outl((addr << 16) | VRC5477_CODEC_WR_RWC, s->io + VRC5477_CODEC_WR);
+
+ /* get the return result */
+ udelay(100); /* workaround hardware bug */
+ while ( (result = inl(s->io + VRC5477_CODEC_RD)) &
+ (VRC5477_CODEC_RD_RRDYA | VRC5477_CODEC_RD_RRDYD) ) {
+ /* we get either addr or data, or both */
+ if (result & VRC5477_CODEC_RD_RRDYA) {
+ MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+ }
+ if (result & VRC5477_CODEC_RD_RRDYD) {
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ return result & 0xffff;;
+}
+
+
+static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)codec->private_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ /* wait until we can access codec registers */
+ while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+
+ /* write the address and value to codec */
+ outl((addr << 16) | data, s->io + VRC5477_CODEC_WR);
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void waitcodec(struct ac97_codec *codec)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)codec->private_data;
+
+ /* wait until we can access codec registers */
+ while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+}
+
+
+/* --------------------------------------------------------------------- */
+
+static void vrc5477_ac97_delay(int msec)
+{
+ unsigned long tmo;
+ signed long tmo2;
+
+ if (in_interrupt())
+ return;
+
+ tmo = jiffies + (msec*HZ)/1000;
+ for (;;) {
+ tmo2 = tmo - jiffies;
+ if (tmo2 <= 0)
+ break;
+ schedule_timeout(tmo2);
+ }
+}
+
+
+static void set_adc_rate(struct vrc5477_ac97_state *s, unsigned rate)
+{
+ wrcodec(&s->codec, AC97_PCM_LR_ADC_RATE, rate);
+ s->adcRate = rate;
+}
+
+
+static void set_dac_rate(struct vrc5477_ac97_state *s, unsigned rate)
+{
+ wrcodec(&s->codec, AC97_PCM_FRONT_DAC_RATE, rate);
+ s->dacRate = rate;
+}
+
+
+/* --------------------------------------------------------------------- */
+
+extern inline void
+stop_dac(struct vrc5477_ac97_state *s)
+{
+ struct dmabuf* db = &s->dma_dac;
+ unsigned long flags;
+ u32 temp;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (db->stopped) {
+ spin_unlock_irqrestore(&s->lock, flags);
+ return;
+ }
+
+ /* deactivate the dma */
+ outl(0, s->io + VRC5477_DAC1_CTRL);
+ outl(0, s->io + VRC5477_DAC2_CTRL);
+
+ /* wait for DAM completely stop */
+ while (inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+ while (inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+ /* disable dac slots in aclink */
+ temp = inl(s->io + VRC5477_CTRL);
+ temp &= ~ (VRC5477_CTRL_DAC1ENB | VRC5477_CTRL_DAC2ENB);
+ outl (temp, s->io + VRC5477_CTRL);
+
+ /* disable interrupts */
+ temp = inl(s->io + VRC5477_INT_MASK);
+ temp &= ~ (VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END);
+ outl (temp, s->io + VRC5477_INT_MASK);
+
+ /* clear pending ones */
+ outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END,
+ s->io + VRC5477_INT_CLR);
+
+ db->stopped = 1;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void start_dac(struct vrc5477_ac97_state *s)
+{
+ struct dmabuf* db = &s->dma_dac;
+ unsigned long flags;
+ u32 dmaLength;
+ u32 temp;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (!db->stopped) {
+ spin_unlock_irqrestore(&s->lock, flags);
+ return;
+ }
+
+ /* we should have some data to do the DMA trasnfer */
+ MIPS_ASSERT(db->count >= db->fragSize);
+
+ /* clear pending fales interrupts */
+ outl(VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END,
+ s->io + VRC5477_INT_CLR);
+
+ /* enable interrupts */
+ temp = inl(s->io + VRC5477_INT_MASK);
+ temp |= VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END;
+ outl(temp, s->io + VRC5477_INT_MASK);
+
+ /* setup dma base addr */
+ outl(db->lbufDma + db->nextOut, s->io + VRC5477_DAC1_BADDR);
+ if (s->dacChannels == 1) {
+ outl(db->lbufDma + db->nextOut, s->io + VRC5477_DAC2_BADDR);
+ } else {
+ outl(db->rbufDma + db->nextOut, s->io + VRC5477_DAC2_BADDR);
+ }
+
+ /* set dma length, in the unit of 0x10 bytes */
+ dmaLength = db->fragSize >> 4;
+ outl(dmaLength, s->io + VRC5477_DAC1L);
+ outl(dmaLength, s->io + VRC5477_DAC2L);
+
+ /* activate dma */
+ outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_DAC1_CTRL);
+ outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_DAC2_CTRL);
+
+ /* enable dac slots - we should hear the music now! */
+ temp = inl(s->io + VRC5477_CTRL);
+ temp |= (VRC5477_CTRL_DAC1ENB | VRC5477_CTRL_DAC2ENB);
+ outl (temp, s->io + VRC5477_CTRL);
+
+ /* it is time to setup next dma transfer */
+ MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+ MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+ temp = db->nextOut + db->fragSize;
+ if (temp >= db->fragTotalSize) {
+ MIPS_ASSERT(temp == db->fragTotalSize);
+ temp = 0;
+ }
+
+ outl(db->lbufDma + temp, s->io + VRC5477_DAC1_BADDR);
+ if (s->dacChannels == 1) {
+ outl(db->lbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+ } else {
+ outl(db->rbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+ }
+
+ db->stopped = 0;
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+ outTicket = *(u16*)(db->lbuf+db->nextOut);
+ if (db->count > db->fragSize) {
+ MIPS_ASSERT((u16)(outTicket+1) == *(u16*)(db->lbuf+temp));
+ }
+#endif
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+extern inline void stop_adc(struct vrc5477_ac97_state *s)
+{
+ struct dmabuf* db = &s->dma_adc;
+ unsigned long flags;
+ u32 temp;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (db->stopped) {
+ spin_unlock_irqrestore(&s->lock, flags);
+ return;
+ }
+
+ /* deactivate the dma */
+ outl(0, s->io + VRC5477_ADC1_CTRL);
+ outl(0, s->io + VRC5477_ADC2_CTRL);
+
+ /* disable adc slots in aclink */
+ temp = inl(s->io + VRC5477_CTRL);
+ temp &= ~ (VRC5477_CTRL_ADC1ENB | VRC5477_CTRL_ADC2ENB);
+ outl (temp, s->io + VRC5477_CTRL);
+
+ /* disable interrupts */
+ temp = inl(s->io + VRC5477_INT_MASK);
+ temp &= ~ (VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END);
+ outl (temp, s->io + VRC5477_INT_MASK);
+
+ /* clear pending ones */
+ outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END,
+ s->io + VRC5477_INT_CLR);
+
+ db->stopped = 1;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+static void start_adc(struct vrc5477_ac97_state *s)
+{
+ struct dmabuf* db = &s->dma_adc;
+ unsigned long flags;
+ u32 dmaLength;
+ u32 temp;
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (!db->stopped) {
+ spin_unlock_irqrestore(&s->lock, flags);
+ return;
+ }
+
+ /* we should at least have some free space in the buffer */
+ MIPS_ASSERT(db->count < db->fragTotalSize - db->fragSize * 2);
+
+ /* clear pending ones */
+ outl(VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END,
+ s->io + VRC5477_INT_CLR);
+
+ /* enable interrupts */
+ temp = inl(s->io + VRC5477_INT_MASK);
+ temp |= VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END;
+ outl(temp, s->io + VRC5477_INT_MASK);
+
+ /* setup dma base addr */
+ outl(db->lbufDma + db->nextIn, s->io + VRC5477_ADC1_BADDR);
+ outl(db->rbufDma + db->nextIn, s->io + VRC5477_ADC2_BADDR);
+
+ /* setup dma length */
+ dmaLength = db->fragSize >> 4;
+ outl(dmaLength, s->io + VRC5477_ADC1L);
+ outl(dmaLength, s->io + VRC5477_ADC2L);
+
+ /* activate dma */
+ outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_ADC1_CTRL);
+ outl(VRC5477_DMA_ACTIVATION, s->io + VRC5477_ADC2_CTRL);
+
+ /* enable adc slots */
+ temp = inl(s->io + VRC5477_CTRL);
+ temp |= (VRC5477_CTRL_ADC1ENB | VRC5477_CTRL_ADC2ENB);
+ outl (temp, s->io + VRC5477_CTRL);
+
+ /* it is time to setup next dma transfer */
+ temp = db->nextIn + db->fragSize;
+ if (temp >= db->fragTotalSize) {
+ MIPS_ASSERT(temp == db->fragTotalSize);
+ temp = 0;
+ }
+ outl(db->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
+ outl(db->rbufDma + temp, s->io + VRC5477_ADC2_BADDR);
+
+ db->stopped = 0;
+
+ spin_unlock_irqrestore(&s->lock, flags);
+}
+
+/* --------------------------------------------------------------------- */
+
+#define DMABUF_DEFAULTORDER (16-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+extern inline void dealloc_dmabuf(struct vrc5477_ac97_state *s,
+ struct dmabuf *db)
+{
+ if (db->lbuf) {
+ MIPS_ASSERT(db->rbuf);
+ pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
+ db->lbuf, db->lbufDma);
+ pci_free_consistent(s->dev, PAGE_SIZE << db->bufOrder,
+ db->rbuf, db->rbufDma);
+ db->lbuf = db->rbuf = NULL;
+ }
+ db->nextIn = db->nextOut = 0;
+ db->ready = 0;
+}
+
+static int prog_dmabuf(struct vrc5477_ac97_state *s,
+ struct dmabuf *db,
+ unsigned rate)
+{
+ int order;
+ unsigned bufsize;
+
+ if (!db->lbuf) {
+ MIPS_ASSERT(!db->rbuf);
+
+ db->ready = 0;
+ for (order = DMABUF_DEFAULTORDER;
+ order >= DMABUF_MINORDER;
+ order--) {
+ db->lbuf = pci_alloc_consistent(s->dev,
+ PAGE_SIZE << order,
+ &db->lbufDma);
+ db->rbuf = pci_alloc_consistent(s->dev,
+ PAGE_SIZE << order,
+ &db->rbufDma);
+ if (db->lbuf && db->rbuf) break;
+ if (db->lbuf) {
+ MIPS_ASSERT(!db->rbuf);
+ pci_free_consistent(s->dev,
+ PAGE_SIZE << order,
+ db->lbuf,
+ db->lbufDma);
+ }
+ }
+ if (!db->lbuf) {
+ MIPS_ASSERT(!db->rbuf);
+ return -ENOMEM;
+ }
+
+ db->bufOrder = order;
+ }
+
+ db->count = 0;
+ db->nextIn = db->nextOut = 0;
+
+ bufsize = PAGE_SIZE << db->bufOrder;
+ db->fragShift = ld2(rate * 2 / 100);
+ if (db->fragShift < 4) db->fragShift = 4;
+
+ db->numFrag = bufsize >> db->fragShift;
+ while (db->numFrag < 4 && db->fragShift > 4) {
+ db->fragShift--;
+ db->numFrag = bufsize >> db->fragShift;
+ }
+ db->fragSize = 1 << db->fragShift;
+ db->fragTotalSize = db->numFrag << db->fragShift;
+ memset(db->lbuf, 0, db->fragTotalSize);
+ memset(db->rbuf, 0, db->fragTotalSize);
+
+ db->ready = 1;
+
+ return 0;
+}
+
+extern inline int prog_dmabuf_adc(struct vrc5477_ac97_state *s)
+{
+ stop_adc(s);
+ return prog_dmabuf(s, &s->dma_adc, s->adcRate);
+}
+
+extern inline int prog_dmabuf_dac(struct vrc5477_ac97_state *s)
+{
+ stop_dac(s);
+ return prog_dmabuf(s, &s->dma_dac, s->dacRate);
+}
+
+
+/* --------------------------------------------------------------------- */
+/* hold spinlock for the following! */
+
+static inline void vrc5477_ac97_adc_interrupt(struct vrc5477_ac97_state *s)
+{
+ struct dmabuf* adc = &s->dma_adc;
+ unsigned temp;
+
+ /* we need two frags avaiable because one is already being used
+ * and the other will be used when next interrupt happens.
+ */
+ if (adc->count >= adc->fragTotalSize - adc->fragSize) {
+ stop_adc(s);
+ adc->error++;
+ printk(KERN_INFO PFX "adc overrun\n");
+ return;
+ }
+
+ /* set the base addr for next DMA transfer */
+ temp = adc->nextIn + 2*adc->fragSize;
+ if (temp >= adc->fragTotalSize) {
+ MIPS_ASSERT( (temp == adc->fragTotalSize) ||
+ (temp == adc->fragTotalSize + adc->fragSize) );
+ temp -= adc->fragTotalSize;
+ }
+ outl(adc->lbufDma + temp, s->io + VRC5477_ADC1_BADDR);
+ outl(adc->rbufDma + temp, s->io + VRC5477_ADC2_BADDR);
+
+ /* adjust nextIn */
+ adc->nextIn += adc->fragSize;
+ if (adc->nextIn >= adc->fragTotalSize) {
+ MIPS_ASSERT(adc->nextIn == adc->fragTotalSize);
+ adc->nextIn = 0;
+ }
+
+ /* adjust count */
+ adc->count += adc->fragSize;
+
+ /* wake up anybody listening */
+ if (waitqueue_active(&adc->wait)) {
+ wake_up_interruptible(&adc->wait);
+ }
+}
+
+static inline void vrc5477_ac97_dac_interrupt(struct vrc5477_ac97_state *s)
+{
+ struct dmabuf* dac = &s->dma_dac;
+ unsigned temp;
+
+ /* next DMA transfer should already started */
+ MIPS_ASSERT(inl(s->io + VRC5477_DAC1_CTRL) & VRC5477_DMA_WIP);
+ MIPS_ASSERT(inl(s->io + VRC5477_DAC2_CTRL) & VRC5477_DMA_WIP);
+
+ /* let us set for next next DMA transfer */
+ temp = dac->nextOut + dac->fragSize*2;
+ if (temp >= dac->fragTotalSize) {
+ MIPS_ASSERT( (temp == dac->fragTotalSize) ||
+ (temp == dac->fragTotalSize + dac->fragSize) );
+ temp -= dac->fragTotalSize;
+ }
+ outl(dac->lbufDma + temp, s->io + VRC5477_DAC1_BADDR);
+ if (s->dacChannels == 1) {
+ outl(dac->lbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+ } else {
+ outl(dac->rbufDma + temp, s->io + VRC5477_DAC2_BADDR);
+ }
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+ if (*(u16*)(dac->lbuf + dac->nextOut) != outTicket) {
+ printk("assert fail: - %d vs %d\n",
+ *(u16*)(dac->lbuf + dac->nextOut),
+ outTicket);
+ MIPS_ASSERT(1 == 0);
+ }
+#endif
+
+ /* adjust nextOut pointer */
+ dac->nextOut += dac->fragSize;
+ if (dac->nextOut >= dac->fragTotalSize) {
+ MIPS_ASSERT(dac->nextOut == dac->fragTotalSize);
+ dac->nextOut = 0;
+ }
+
+ /* adjust count */
+ dac->count -= dac->fragSize;
+ if (dac->count <=0 ) {
+ MIPS_ASSERT(dac->count == 0);
+ MIPS_ASSERT(dac->nextIn == dac->nextOut);
+ /* buffer under run */
+ stop_dac(s);
+ }
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+ if (dac->count) {
+ outTicket ++;
+ MIPS_ASSERT(*(u16*)(dac->lbuf + dac->nextOut) == outTicket);
+ }
+#endif
+
+ /* we cannot have both under run and someone is waiting on us */
+ MIPS_ASSERT(! (waitqueue_active(&dac->wait) && (dac->count <= 0)) );
+
+ /* wake up anybody listening */
+ if (waitqueue_active(&dac->wait))
+ wake_up_interruptible(&dac->wait);
+}
+
+static void vrc5477_ac97_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)dev_id;
+ u32 irqStatus;
+ u32 adcInterrupts, dacInterrupts;
+
+ spin_lock(&s->lock);
+
+ /* get irqStatus and clear the detected ones */
+ irqStatus = inl(s->io + VRC5477_INT_STATUS);
+ outl(irqStatus, s->io + VRC5477_INT_CLR);
+
+ /* let us see what we get */
+ dacInterrupts = VRC5477_INT_MASK_DAC1END | VRC5477_INT_MASK_DAC2END;
+ adcInterrupts = VRC5477_INT_MASK_ADC1END | VRC5477_INT_MASK_ADC2END;
+ if (irqStatus & dacInterrupts) {
+ /* we should get both interrupts, but just in case ... */
+ if (irqStatus & VRC5477_INT_MASK_DAC1END) {
+ vrc5477_ac97_dac_interrupt(s);
+ }
+ if ( (irqStatus & dacInterrupts) != dacInterrupts ) {
+ printk(KERN_WARNING "vrc5477_ac97 : dac interrupts not in sync!!!\n");
+ stop_dac(s);
+ start_dac(s);
+ }
+ } else if (irqStatus & adcInterrupts) {
+ /* we should get both interrupts, but just in case ... */
+ if(irqStatus & VRC5477_INT_MASK_ADC1END) {
+ vrc5477_ac97_adc_interrupt(s);
+ }
+ if ( (irqStatus & adcInterrupts) != adcInterrupts ) {
+ printk(KERN_WARNING "vrc5477_ac97 : adc interrupts not in sync!!!\n");
+ stop_adc(s);
+ start_adc(s);
+ }
+ }
+
+ spin_unlock(&s->lock);
+}
+
+/* --------------------------------------------------------------------- */
+
+static loff_t vrc5477_ac97_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -ESPIPE;
+}
+
+
+static int vrc5477_ac97_open_mixdev(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+ struct list_head *list;
+ struct vrc5477_ac97_state *s;
+
+ for (list = devs.next; ; list = list->next) {
+ if (list == &devs)
+ return -ENODEV;
+ s = list_entry(list, struct vrc5477_ac97_state, devs);
+ if (s->codec.dev_mixer == minor)
+ break;
+ }
+ file->private_data = s;
+ return 0;
+}
+
+static int vrc5477_ac97_release_mixdev(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd,
+ unsigned long arg)
+{
+ return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static int vrc5477_ac97_ioctl_mixdev(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)file->private_data;
+ struct ac97_codec *codec = &s->codec;
+
+ return mixdev_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations vrc5477_ac97_mixer_fops = {
+ owner: THIS_MODULE,
+ llseek: vrc5477_ac97_llseek,
+ ioctl: vrc5477_ac97_ioctl_mixdev,
+ open: vrc5477_ac97_open_mixdev,
+ release: vrc5477_ac97_release_mixdev,
+};
+
+/* --------------------------------------------------------------------- */
+
+static int drain_dac(struct vrc5477_ac97_state *s, int nonblock)
+{
+ unsigned long flags;
+ int count, tmo;
+
+ if (!s->dma_dac.ready)
+ return 0;
+
+ for (;;) {
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count <= 0)
+ break;
+ if (signal_pending(current))
+ break;
+ if (nonblock)
+ return -EBUSY;
+ tmo = 1000 * count / s->dacRate / 2;
+ vrc5477_ac97_delay(tmo);
+ }
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+
+static int inline
+copy_two_channel_adc_to_user(struct vrc5477_ac97_state *s,
+ char *buffer,
+ int copyCount)
+{
+ struct dmabuf *db = &s->dma_adc;
+ int bufStart = db->nextOut;
+ for (; copyCount > 0; ) {
+ int i;
+ int count = copyCount;
+ if (count > WORK_BUF_SIZE/2) count = WORK_BUF_SIZE/2;
+ for (i=0; i< count/2; i++) {
+ s->workBuf[i].lchannel =
+ *(u16*)(db->lbuf + bufStart + i*2);
+ s->workBuf[i].rchannel =
+ *(u16*)(db->rbuf + bufStart + i*2);
+ }
+ if (copy_to_user(buffer, s->workBuf, count*2)) {
+ return -1;
+ }
+
+ copyCount -= count;
+ bufStart += count;
+ MIPS_ASSERT(bufStart <= db->fragTotalSize);
+ buffer += count *2;
+ }
+ return 0;
+}
+
+/* return the total bytes that is copied */
+static int inline
+copy_adc_to_user(struct vrc5477_ac97_state *s,
+ char * buffer,
+ size_t count,
+ int avail)
+{
+ struct dmabuf *db = &s->dma_adc;
+ int copyCount=0;
+ int copyFragCount=0;
+ int totalCopyCount = 0;
+ int totalCopyFragCount = 0;
+ unsigned long flags;
+
+ /* adjust count to signel channel byte count */
+ count >>= s->adcChannels - 1;
+
+ /* we may have to "copy" twice as ring buffer wraps around */
+ for (; (avail > 0) && (count > 0); ) {
+ /* determine max possible copy count for single channel */
+ copyCount = count;
+ if (copyCount > avail) {
+ copyCount = avail;
+ }
+ if (copyCount + db->nextOut > db->fragTotalSize) {
+ copyCount = db->fragTotalSize - db->nextOut;
+ MIPS_ASSERT((copyCount % db->fragSize) == 0);
+ }
+
+ copyFragCount = (copyCount-1) >> db->fragShift;
+ copyFragCount = (copyFragCount+1) << db->fragShift;
+ MIPS_ASSERT(copyFragCount >= copyCount);
+
+ /* we copy differently based on adc channels */
+ if (s->adcChannels == 1) {
+ if (copy_to_user(buffer,
+ db->lbuf + db->nextOut,
+ copyCount))
+ return -1;
+ } else {
+ /* *sigh* we have to mix two streams into one */
+ if (copy_two_channel_adc_to_user(s, buffer, copyCount))
+ return -1;
+ }
+
+ count -= copyCount;
+ totalCopyCount += copyCount;
+ avail -= copyFragCount;
+ totalCopyFragCount += copyFragCount;
+
+ buffer += copyCount << (s->adcChannels-1);
+
+ db->nextOut += copyFragCount;
+ if (db->nextOut >= db->fragTotalSize) {
+ MIPS_ASSERT(db->nextOut == db->fragTotalSize);
+ db->nextOut = 0;
+ }
+
+ MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
+ MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+ db->count -= totalCopyFragCount;
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ return totalCopyCount << (s->adcChannels-1);
+}
+
+static ssize_t
+vrc5477_ac97_read(struct file *file,
+ char *buffer,
+ size_t count,
+ loff_t *ppos)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)file->private_data;
+ struct dmabuf *db = &s->dma_adc;
+ ssize_t ret = 0;
+ unsigned long flags;
+ int copyCount;
+ size_t avail;
+
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ if (!access_ok(VERIFY_WRITE, buffer, count))
+ return -EFAULT;
+
+ MIPS_ASSERT(db->ready);
+
+ while (count > 0) {
+ // wait for samples in capture buffer
+ do {
+ spin_lock_irqsave(&s->lock, flags);
+ if (db->stopped)
+ start_adc(s);
+ avail = db->count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (avail <= 0) {
+ if (file->f_flags & O_NONBLOCK) {
+ if (!ret)
+ ret = -EAGAIN;
+ return ret;
+ }
+ interruptible_sleep_on(&db->wait);
+ if (signal_pending(current)) {
+ if (!ret)
+ ret = -ERESTARTSYS;
+ return ret;
+ }
+ }
+ } while (avail <= 0);
+
+ MIPS_ASSERT( (avail % db->fragSize) == 0);
+ copyCount = copy_adc_to_user(s, buffer, count, avail);
+ if (copyCount <=0 ) {
+ if (!ret) ret = -EFAULT;
+ return ret;
+ }
+
+ count -= copyCount;
+ buffer += copyCount;
+ ret += copyCount;
+ } // while (count > 0)
+
+ return ret;
+}
+
+static int inline
+copy_two_channel_dac_from_user(struct vrc5477_ac97_state *s,
+ const char *buffer,
+ int copyCount)
+{
+ struct dmabuf *db = &s->dma_dac;
+ int bufStart = db->nextIn;
+
+ MIPS_ASSERT(db->ready);
+
+ for (; copyCount > 0; ) {
+ int i;
+ int count = copyCount;
+ if (count > WORK_BUF_SIZE/2) count = WORK_BUF_SIZE/2;
+ if (copy_from_user(s->workBuf, buffer, count*2)) {
+ return -1;
+ }
+ for (i=0; i< count/2; i++) {
+ *(u16*)(db->lbuf + bufStart + i*2) =
+ s->workBuf[i].lchannel;
+ *(u16*)(db->rbuf + bufStart + i*2) =
+ s->workBuf[i].rchannel;
+ }
+
+ copyCount -= count;
+ bufStart += count;
+ MIPS_ASSERT(bufStart <= db->fragTotalSize);
+ buffer += count *2;
+ }
+ return 0;
+
+}
+
+/* return the total bytes that is copied */
+static int inline
+copy_dac_from_user(struct vrc5477_ac97_state *s,
+ const char *buffer,
+ size_t count,
+ int avail)
+{
+ struct dmabuf *db = &s->dma_dac;
+ int copyCount=0;
+ int copyFragCount=0;
+ int totalCopyCount = 0;
+ int totalCopyFragCount = 0;
+ unsigned long flags;
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+ int i;
+#endif
+
+ /* adjust count to signel channel byte count */
+ count >>= s->dacChannels - 1;
+
+ /* we may have to "copy" twice as ring buffer wraps around */
+ for (; (avail > 0) && (count > 0); ) {
+ /* determine max possible copy count for single channel */
+ copyCount = count;
+ if (copyCount > avail) {
+ copyCount = avail;
+ }
+ if (copyCount + db->nextIn > db->fragTotalSize) {
+ copyCount = db->fragTotalSize - db->nextIn;
+ MIPS_ASSERT((copyCount % db->fragSize) == 0);
+ MIPS_ASSERT(copyCount > 0);
+ }
+
+ copyFragCount = (copyCount-1) >> db->fragShift;
+ copyFragCount = (copyFragCount+1) << db->fragShift;
+ MIPS_ASSERT(copyFragCount >= copyCount);
+
+ /* we copy differently based on the number channels */
+ if (s->dacChannels == 1) {
+ if (copy_from_user(db->lbuf + db->nextIn,
+ buffer,
+ copyCount))
+ return -1;
+ /* fill gaps with 0 */
+ memset(db->lbuf + db->nextIn + copyCount,
+ 0,
+ copyFragCount - copyCount);
+ } else {
+ /* we have demux the stream into two separate ones */
+ if (copy_two_channel_dac_from_user(s, buffer, copyCount))
+ return -1;
+ /* fill gaps with 0 */
+ memset(db->lbuf + db->nextIn + copyCount,
+ 0,
+ copyFragCount - copyCount);
+ memset(db->rbuf + db->nextIn + copyCount,
+ 0,
+ copyFragCount - copyCount);
+ }
+
+#if defined(VRC5477_AC97_VERBOSE_DEBUG)
+ for (i=0; i< copyFragCount; i+= db->fragSize) {
+ *(u16*)(db->lbuf + db->nextIn + i) = inTicket ++;
+ }
+#endif
+
+ count -= copyCount;
+ totalCopyCount =+ copyCount;
+ avail -= copyFragCount;
+ totalCopyFragCount += copyFragCount;
+
+ buffer += copyCount << (s->dacChannels - 1);
+
+ db->nextIn += copyFragCount;
+ if (db->nextIn >= db->fragTotalSize) {
+ MIPS_ASSERT(db->nextIn == db->fragTotalSize);
+ db->nextIn = 0;
+ }
+
+ MIPS_ASSERT((copyFragCount % db->fragSize) == 0);
+ MIPS_ASSERT( (count == 0) || (copyCount == copyFragCount));
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+ db->count += totalCopyFragCount;
+ if (db->stopped) {
+ start_dac(s);
+ }
+
+ /* nextIn should not be equal to nextOut unless we are full */
+ MIPS_ASSERT( ( (db->count == db->fragTotalSize) &&
+ (db->nextIn == db->nextOut) ) ||
+ ( (db->count < db->fragTotalSize) &&
+ (db->nextIn != db->nextOut) ) );
+
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ return totalCopyCount << (s->dacChannels-1);
+
+}
+
+static ssize_t vrc5477_ac97_write(struct file *file, const char *buffer,
+ size_t count, loff_t *ppos)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)file->private_data;
+ struct dmabuf *db = &s->dma_dac;
+ ssize_t ret;
+ unsigned long flags;
+ int copyCount, avail;
+
+ if (ppos != &file->f_pos)
+ return -ESPIPE;
+ if (!access_ok(VERIFY_READ, buffer, count))
+ return -EFAULT;
+ ret = 0;
+
+ while (count > 0) {
+ // wait for space in playback buffer
+ do {
+ spin_lock_irqsave(&s->lock, flags);
+ avail = db->fragTotalSize - db->count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (avail <= 0) {
+ if (file->f_flags & O_NONBLOCK) {
+ if (!ret)
+ ret = -EAGAIN;
+ return ret;
+ }
+ interruptible_sleep_on(&db->wait);
+ if (signal_pending(current)) {
+ if (!ret)
+ ret = -ERESTARTSYS;
+ return ret;
+ }
+ }
+ } while (avail <= 0);
+
+ MIPS_ASSERT( (avail % db->fragSize) == 0);
+ copyCount = copy_dac_from_user(s, buffer, count, avail);
+ if (copyCount < 0) {
+ if (!ret) ret = -EFAULT;
+ return ret;
+ }
+
+ count -= copyCount;
+ buffer += copyCount;
+ ret += copyCount;
+ } // while (count > 0)
+
+ return ret;
+}
+
+/* No kernel lock - we have our own spinlock */
+static unsigned int vrc5477_ac97_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)file->private_data;
+ unsigned long flags;
+ unsigned int mask = 0;
+
+ if (file->f_mode & FMODE_WRITE)
+ poll_wait(file, &s->dma_dac.wait, wait);
+ if (file->f_mode & FMODE_READ)
+ poll_wait(file, &s->dma_adc.wait, wait);
+ spin_lock_irqsave(&s->lock, flags);
+ if (file->f_mode & FMODE_READ) {
+ if (s->dma_adc.count >= (signed)s->dma_adc.fragSize)
+ mask |= POLLIN | POLLRDNORM;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ if ((signed)s->dma_dac.fragTotalSize >=
+ s->dma_dac.count + (signed)s->dma_dac.fragSize)
+ mask |= POLLOUT | POLLWRNORM;
+ }
+ spin_unlock_irqrestore(&s->lock, flags);
+ return mask;
+}
+
+#ifdef CONFIG_LL_DEBUG
+static struct ioctl_str_t {
+ unsigned int cmd;
+ const char* str;
+} ioctl_str[] = {
+ {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"},
+ {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"},
+ {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"},
+ {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"},
+ {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"},
+ {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"},
+ {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"},
+ {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"},
+ {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"},
+ {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"},
+ {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"},
+ {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"},
+ {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"},
+ {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"},
+ {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"},
+ {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"},
+ {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"},
+ {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"},
+ {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"},
+ {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"},
+ {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"},
+ {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"},
+ {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"},
+ {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"},
+ {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"},
+ {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"},
+ {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"},
+ {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"},
+ {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"},
+ {OSS_GETVERSION, "OSS_GETVERSION"},
+ {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"},
+ {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"},
+ {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"},
+ {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"}
+};
+#endif
+
+static int vrc5477_ac97_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct vrc5477_ac97_state *s = (struct vrc5477_ac97_state *)file->private_data;
+ unsigned long flags;
+ audio_buf_info abinfo;
+ int count;
+ int val, ret;
+
+#ifdef CONFIG_LL_DEBUG
+ for (count=0; count<sizeof(ioctl_str)/sizeof(ioctl_str[0]); count++) {
+ if (ioctl_str[count].cmd == cmd)
+ break;
+ }
+ if (count < sizeof(ioctl_str)/sizeof(ioctl_str[0]))
+ printk(KERN_INFO PFX "ioctl %s\n", ioctl_str[count].str);
+ else
+ printk(KERN_INFO PFX "ioctl unknown, 0x%x\n", cmd);
+#endif
+
+ switch (cmd) {
+ case OSS_GETVERSION:
+ return put_user(SOUND_VERSION, (int *)arg);
+
+ case SNDCTL_DSP_SYNC:
+ if (file->f_mode & FMODE_WRITE)
+ return drain_dac(s, file->f_flags & O_NONBLOCK);
+ return 0;
+
+ case SNDCTL_DSP_SETDUPLEX:
+ return 0;
+
+ case SNDCTL_DSP_GETCAPS:
+ return put_user(DSP_CAP_DUPLEX, (int *)arg);
+
+ case SNDCTL_DSP_RESET:
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ synchronize_irq();
+ s->dma_dac.count = 0;
+ s->dma_dac.nextIn = s->dma_dac.nextOut = 0;
+ }
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ synchronize_irq();
+ s->dma_adc.count = 0;
+ s->dma_adc.nextIn = s->dma_adc.nextOut = 0;
+ }
+ return 0;
+
+ case SNDCTL_DSP_SPEED:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val >= 0) {
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ set_adc_rate(s, val);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ set_dac_rate(s, val);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ }
+ return put_user((file->f_mode & FMODE_READ) ?
+ s->adcRate : s->dacRate, (int *)arg);
+
+ case SNDCTL_DSP_STEREO:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ if (val)
+ s->adcChannels = 2;
+ else
+ s->adcChannels = 1;
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ if (val)
+ s->dacChannels = 2;
+ else
+ s->dacChannels = 1;
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ return 0;
+
+ case SNDCTL_DSP_CHANNELS:
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != 0) {
+ if ( (val != 1) && (val != 2)) val = 2;
+
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ s->dacChannels = val;
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ s->dacChannels = val;
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ }
+ return put_user(val, (int *)arg);
+
+ case SNDCTL_DSP_GETFMTS: /* Returns a mask */
+ return put_user(AFMT_S16_LE, (int *)arg);
+
+ case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ if (val != AFMT_QUERY) {
+ if (val != AFMT_S16_LE) return -EINVAL;
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ if ((ret = prog_dmabuf_adc(s)))
+ return ret;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ if ((ret = prog_dmabuf_dac(s)))
+ return ret;
+ }
+ } else {
+ val = AFMT_S16_LE;
+ }
+ return put_user(val, (int *)arg);
+
+ case SNDCTL_DSP_POST:
+ return 0;
+
+ case SNDCTL_DSP_GETTRIGGER:
+ case SNDCTL_DSP_SETTRIGGER:
+ /* NO trigger */
+ return -EINVAL;
+
+ case SNDCTL_DSP_GETOSPACE:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;
+ abinfo.fragsize = s->dma_dac.fragSize << (s->dacChannels-1);
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ abinfo.bytes = (s->dma_dac.fragTotalSize - count) <<
+ (s->dacChannels-1);
+ abinfo.fragstotal = s->dma_dac.numFrag;
+ abinfo.fragments = abinfo.bytes >> s->dma_dac.fragShift >>
+ (s->dacChannels-1);
+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+ case SNDCTL_DSP_GETISPACE:
+ if (!(file->f_mode & FMODE_READ))
+ return -EINVAL;
+ abinfo.fragsize = s->dma_adc.fragSize << (s->adcChannels-1);
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_adc.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ if (count < 0)
+ count = 0;
+ abinfo.bytes = count << (s->adcChannels-1);
+ abinfo.fragstotal = s->dma_adc.numFrag;
+ abinfo.fragments = (abinfo.bytes >> s->dma_adc.fragShift) >>
+ (s->adcChannels-1);
+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+ case SNDCTL_DSP_NONBLOCK:
+ file->f_flags |= O_NONBLOCK;
+ return 0;
+
+ case SNDCTL_DSP_GETODELAY:
+ if (!(file->f_mode & FMODE_WRITE))
+ return -EINVAL;
+ spin_lock_irqsave(&s->lock, flags);
+ count = s->dma_dac.count;
+ spin_unlock_irqrestore(&s->lock, flags);
+ return put_user(count, (int *)arg);
+
+ case SNDCTL_DSP_GETIPTR:
+ case SNDCTL_DSP_GETOPTR:
+ /* we cannot get DMA ptr */
+ return -EINVAL;
+
+ case SNDCTL_DSP_GETBLKSIZE:
+ if (file->f_mode & FMODE_WRITE)
+ return put_user(s->dma_dac.fragSize << (s->dacChannels-1), (int *)arg);
+ else
+ return put_user(s->dma_adc.fragSize << (s->adcChannels-1), (int *)arg);
+
+ case SNDCTL_DSP_SETFRAGMENT:
+ /* we ignore fragment size request */
+ return 0;
+
+ case SNDCTL_DSP_SUBDIVIDE:
+ /* what is this for? [jsun] */
+ return 0;
+
+ case SOUND_PCM_READ_RATE:
+ return put_user((file->f_mode & FMODE_READ) ?
+ s->adcRate : s->dacRate, (int *)arg);
+
+ case SOUND_PCM_READ_CHANNELS:
+ if (file->f_mode & FMODE_READ)
+ return put_user(s->adcChannels, (int *)arg);
+ else
+ return put_user(s->dacChannels ? 2 : 1, (int *)arg);
+
+ case SOUND_PCM_READ_BITS:
+ return put_user(16, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
+ case SOUND_PCM_READ_FILTER:
+ return -EINVAL;
+ }
+
+ return mixdev_ioctl(&s->codec, cmd, arg);
+}
+
+
+static int vrc5477_ac97_open(struct inode *inode, struct file *file)
+{
+ int minor = MINOR(inode->i_rdev);
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+ struct list_head *list;
+ struct vrc5477_ac97_state *s;
+ int ret=0;
+
+ for (list = devs.next; ; list = list->next) {
+ if (list == &devs)
+ return -ENODEV;
+ s = list_entry(list, struct vrc5477_ac97_state, devs);
+ if (!((s->dev_audio ^ minor) & ~0xf))
+ break;
+ }
+ file->private_data = s;
+
+ /* wait for device to become free */
+ down(&s->open_sem);
+ while (s->open_mode & file->f_mode) {
+
+ if (file->f_flags & O_NONBLOCK) {
+ up(&s->open_sem);
+ return -EBUSY;
+ }
+ add_wait_queue(&s->open_wait, &wait);
+ __set_current_state(TASK_INTERRUPTIBLE);
+ up(&s->open_sem);
+ schedule();
+ remove_wait_queue(&s->open_wait, &wait);
+ set_current_state(TASK_RUNNING);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ down(&s->open_sem);
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+
+ if (file->f_mode & FMODE_READ) {
+ /* set default settings */
+ set_adc_rate(s, 48000);
+ s->adcChannels = 2;
+
+ ret = prog_dmabuf_adc(s);
+ if (ret) goto bailout;
+ }
+ if (file->f_mode & FMODE_WRITE) {
+ /* set default settings */
+ set_dac_rate(s, 48000);
+ s->dacChannels = 2;
+
+ ret = prog_dmabuf_dac(s);
+ if (ret) goto bailout;
+ }
+
+ s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+
+ bailout:
+ spin_unlock_irqrestore(&s->lock, flags);
+
+ up(&s->open_sem);
+ return ret;
+}
+
+static int vrc5477_ac97_release(struct inode *inode, struct file *file)
+{
+ struct vrc5477_ac97_state *s =
+ (struct vrc5477_ac97_state *)file->private_data;
+
+ lock_kernel();
+ if (file->f_mode & FMODE_WRITE)
+ drain_dac(s, file->f_flags & O_NONBLOCK);
+ down(&s->open_sem);
+ if (file->f_mode & FMODE_WRITE) {
+ stop_dac(s);
+ dealloc_dmabuf(s, &s->dma_dac);
+ }
+ if (file->f_mode & FMODE_READ) {
+ stop_adc(s);
+ dealloc_dmabuf(s, &s->dma_adc);
+ }
+ s->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+ up(&s->open_sem);
+ wake_up(&s->open_wait);
+ unlock_kernel();
+ return 0;
+}
+
+static /*const*/ struct file_operations vrc5477_ac97_audio_fops = {
+ owner: THIS_MODULE,
+ llseek: vrc5477_ac97_llseek,
+ read: vrc5477_ac97_read,
+ write: vrc5477_ac97_write,
+ poll: vrc5477_ac97_poll,
+ ioctl: vrc5477_ac97_ioctl,
+ // mmap: vrc5477_ac97_mmap,
+ open: vrc5477_ac97_open,
+ release: vrc5477_ac97_release,
+};
+
+
+/* --------------------------------------------------------------------- */
+
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * for debugging purposes, we'll create a proc device that dumps the
+ * CODEC chipstate
+ */
+
+#ifdef CONFIG_LL_DEBUG
+
+struct {
+ const char *regname;
+ unsigned regaddr;
+} vrc5477_ac97_regs[] = {
+ {"VRC5477_INT_STATUS", VRC5477_INT_STATUS},
+ {"VRC5477_CODEC_WR", VRC5477_CODEC_WR},
+ {"VRC5477_CODEC_RD", VRC5477_CODEC_RD},
+ {"VRC5477_CTRL", VRC5477_CTRL},
+ {"VRC5477_ACLINK_CTRL", VRC5477_ACLINK_CTRL},
+ {"VRC5477_INT_MASK", VRC5477_INT_MASK},
+ {"VRC5477_DAC1_CTRL", VRC5477_DAC1_CTRL},
+ {"VRC5477_DAC1L", VRC5477_DAC1L},
+ {"VRC5477_DAC1_BADDR", VRC5477_DAC1_BADDR},
+ {"VRC5477_DAC2_CTRL", VRC5477_DAC2_CTRL},
+ {"VRC5477_DAC2L", VRC5477_DAC2L},
+ {"VRC5477_DAC2_BADDR", VRC5477_DAC2_BADDR},
+ {"VRC5477_DAC3_CTRL", VRC5477_DAC3_CTRL},
+ {"VRC5477_DAC3L", VRC5477_DAC3L},
+ {"VRC5477_DAC3_BADDR", VRC5477_DAC3_BADDR},
+ {"VRC5477_ADC1_CTRL", VRC5477_ADC1_CTRL},
+ {"VRC5477_ADC1L", VRC5477_ADC1L},
+ {"VRC5477_ADC1_BADDR", VRC5477_ADC1_BADDR},
+ {"VRC5477_ADC2_CTRL", VRC5477_ADC2_CTRL},
+ {"VRC5477_ADC2L", VRC5477_ADC2L},
+ {"VRC5477_ADC2_BADDR", VRC5477_ADC2_BADDR},
+ {"VRC5477_ADC3_CTRL", VRC5477_ADC3_CTRL},
+ {"VRC5477_ADC3L", VRC5477_ADC3L},
+ {"VRC5477_ADC3_BADDR", VRC5477_ADC3_BADDR},
+ {NULL, 0x0}
+};
+
+static int proc_vrc5477_ac97_dump (char *buf, char **start, off_t fpos,
+ int length, int *eof, void *data)
+{
+ struct vrc5477_ac97_state *s;
+ int cnt, len = 0;
+
+ if (list_empty(&devs))
+ return 0;
+ s = list_entry(devs.next, struct vrc5477_ac97_state, devs);
+
+ /* print out header */
+ len += sprintf(buf + len, "\n\t\tVrc5477 Audio Debug\n\n");
+
+ // print out digital controller state
+ len += sprintf (buf + len, "NEC Vrc5477 Audio Controller registers\n");
+ len += sprintf (buf + len, "---------------------------------\n");
+ for (cnt=0; vrc5477_ac97_regs[cnt].regname != NULL; cnt++) {
+ len+= sprintf (buf + len, "%-20s = %08x\n",
+ vrc5477_ac97_regs[cnt].regname,
+ inl(s->io + vrc5477_ac97_regs[cnt].regaddr));
+ }
+
+ /* print out driver state */
+ len += sprintf (buf + len, "NEC Vrc5477 Audio driver states\n");
+ len += sprintf (buf + len, "---------------------------------\n");
+ len += sprintf (buf + len, "dacChannels = %d\n", s->dacChannels);
+ len += sprintf (buf + len, "adcChannels = %d\n", s->adcChannels);
+ len += sprintf (buf + len, "dacRate = %d\n", s->dacRate);
+ len += sprintf (buf + len, "adcRate = %d\n", s->adcRate);
+
+ len += sprintf (buf + len, "dma_dac is %s ready\n",
+ s->dma_dac.ready? "" : "not");
+ if (s->dma_dac.ready) {
+ len += sprintf (buf + len, "dma_dac is %s stopped.\n",
+ s->dma_dac.stopped? "" : "not");
+ len += sprintf (buf + len, "dma_dac.fragSize = %x\n",
+ s->dma_dac.fragSize);
+ len += sprintf (buf + len, "dma_dac.fragShift = %x\n",
+ s->dma_dac.fragShift);
+ len += sprintf (buf + len, "dma_dac.numFrag = %x\n",
+ s->dma_dac.numFrag);
+ len += sprintf (buf + len, "dma_dac.fragTotalSize = %x\n",
+ s->dma_dac.fragTotalSize);
+ len += sprintf (buf + len, "dma_dac.nextIn = %x\n",
+ s->dma_dac.nextIn);
+ len += sprintf (buf + len, "dma_dac.nextOut = %x\n",
+ s->dma_dac.nextOut);
+ len += sprintf (buf + len, "dma_dac.count = %x\n",
+ s->dma_dac.count);
+ }
+
+ len += sprintf (buf + len, "dma_adc is %s ready\n",
+ s->dma_adc.ready? "" : "not");
+ if (s->dma_adc.ready) {
+ len += sprintf (buf + len, "dma_adc is %s stopped.\n",
+ s->dma_adc.stopped? "" : "not");
+ len += sprintf (buf + len, "dma_adc.fragSize = %x\n",
+ s->dma_adc.fragSize);
+ len += sprintf (buf + len, "dma_adc.fragShift = %x\n",
+ s->dma_adc.fragShift);
+ len += sprintf (buf + len, "dma_adc.numFrag = %x\n",
+ s->dma_adc.numFrag);
+ len += sprintf (buf + len, "dma_adc.fragTotalSize = %x\n",
+ s->dma_adc.fragTotalSize);
+ len += sprintf (buf + len, "dma_adc.nextIn = %x\n",
+ s->dma_adc.nextIn);
+ len += sprintf (buf + len, "dma_adc.nextOut = %x\n",
+ s->dma_adc.nextOut);
+ len += sprintf (buf + len, "dma_adc.count = %x\n",
+ s->dma_adc.count);
+ }
+
+ /* print out CODEC state */
+ len += sprintf (buf + len, "\nAC97 CODEC registers\n");
+ len += sprintf (buf + len, "----------------------\n");
+ for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
+ len+= sprintf (buf + len, "reg %02x = %04x\n",
+ cnt, rdcodec(&s->codec, cnt));
+
+ if (fpos >=len){
+ *start = buf;
+ *eof =1;
+ return 0;
+ }
+ *start = buf + fpos;
+ if ((len -= fpos) > length)
+ return length;
+ *eof =1;
+ return len;
+
+}
+#endif /* CONFIG_LL_DEBUG */
+
+/* --------------------------------------------------------------------- */
+
+/* maximum number of devices; only used for command line params */
+#define NR_DEVICE 5
+
+static unsigned int devindex = 0;
+
+MODULE_AUTHOR("Monta Vista Software, jsun@mvista.com or jsun@junsun.net");
+MODULE_DESCRIPTION("NEC Vrc5477 audio (AC97) Driver");
+
+/* --------------------------------------------------------------------- */
+extern void jsun_scan_pci_bus(void);
+extern void vrc5477_show_pci_regs(void);
+extern void vrc5477_show_pdar_regs(void);
+
+/* -------------------------------------------------------- */
+#define AC97_BASE 0xbb000000
+#define myinl(x) *(volatile u32*)(AC97_BASE + (x))
+#define myoutl(x,y) *(volatile u32*)(AC97_BASE + (y)) = (x)
+
+u16 myrdcodec(u8 addr)
+{
+ u32 result;
+
+ /* wait until we can access codec registers */
+ // while (inl(VRC5477_CODEC_WR) & 0x80000000);
+
+ /* write the address and "read" command to codec */
+ addr = addr & 0x7f;
+ myoutl((addr << 16) | VRC5477_CODEC_WR_RWC, VRC5477_CODEC_WR);
+
+ /* get the return result */
+ udelay(100); /* workaround hardware bug */
+ // dump_memory(0xbb000000, 48);
+ while ( ((result=myinl(VRC5477_CODEC_RD)) & 0xc0000000) != 0xc0000000);
+ MIPS_ASSERT(addr == ((result >> 16) & 0x7f) );
+ return result & 0xffff;
+}
+
+void mywrcodec(u8 addr, u16 data)
+{
+ /* wait until we can access codec registers */
+ while (myinl(VRC5477_CODEC_WR) & 0x80000000);
+
+ /* write the address and value to codec */
+ myoutl((addr << 16) | data, VRC5477_CODEC_WR);
+
+}
+
+
+void jsun_ac97_test(struct vrc5477_ac97_state *s)
+{
+ int i;
+
+ /* reset codec */
+ /*
+ wrcodec(&s->codec, 0, 0);
+ while (inl(s->io + VRC5477_CODEC_WR) & 0x80000000);
+ */
+ mywrcodec(0, 0);
+ while (myinl(VRC5477_CODEC_WR) & 0x80000000);
+
+ for (i=0; i< 0x40; i+=4) {
+ MIPS_ASSERT(inl(s->io+i) == myinl(i));
+ }
+
+ printk("codec registers : ");
+ for (i=0; i<= 0x3a; i+=2) {
+ if ( (i%0x10) == 0) {
+ printk("\n%02x\t", i);
+ }
+ // printk("%04x\t", rdcodec(&s->codec, i));
+ printk("%04x\t", myrdcodec(i));
+ }
+ printk("\n\n");
+ printk("codec registers : ");
+ for (i=0; i<= 0x3a; i+=2) {
+ if ( (i%0x10) == 0) {
+ printk("\n%02x\t", i);
+ }
+ printk("%04x\t", rdcodec(&s->codec, i));
+ }
+ printk("\n\n");
+}
+
+static int __devinit vrc5477_ac97_probe(struct pci_dev *pcidev,
+ const struct pci_device_id *pciid)
+{
+ struct vrc5477_ac97_state *s;
+ char proc_str[80];
+
+ MIPS_DEBUG(printk("vrc5477_ac97_probe() invoked\n"));
+
+ if (pcidev->irq == 0)
+ return -1;
+
+ if (!(s = kmalloc(sizeof(struct vrc5477_ac97_state), GFP_KERNEL))) {
+ printk(KERN_ERR PFX "alloc of device struct failed\n");
+ return -1;
+ }
+ memset(s, 0, sizeof(struct vrc5477_ac97_state));
+
+ init_waitqueue_head(&s->dma_adc.wait);
+ init_waitqueue_head(&s->dma_dac.wait);
+ init_waitqueue_head(&s->open_wait);
+ init_MUTEX(&s->open_sem);
+ spin_lock_init(&s->lock);
+
+ s->dev = pcidev;
+ s->io = pci_resource_start(pcidev, 0);
+ s->irq = pcidev->irq;
+
+ s->codec.private_data = s;
+ s->codec.id = 0;
+ s->codec.codec_read = rdcodec;
+ s->codec.codec_write = wrcodec;
+ s->codec.codec_wait = waitcodec;
+
+ /* setting some other default values such as
+ * adcChannels, adcRate is done in open() so that
+ * no persistent state across file opens.
+ */
+
+ if (!request_region(s->io, pci_resource_len(pcidev,0),
+ VRC5477_AC97_MODULE_NAME)) {
+ printk(KERN_ERR PFX "io ports %#lx->%#lx in use\n",
+ s->io, s->io + pci_resource_len(pcidev,0)-1);
+ goto err_region;
+ }
+ if (request_irq(s->irq, vrc5477_ac97_interrupt, SA_INTERRUPT,
+ VRC5477_AC97_MODULE_NAME, s)) {
+ printk(KERN_ERR PFX "irq %u in use\n", s->irq);
+ goto err_irq;
+ }
+
+ printk(KERN_INFO PFX "IO at %#lx, IRQ %d\n", s->io, s->irq);
+
+ /* register devices */
+ if ((s->dev_audio = register_sound_dsp(&vrc5477_ac97_audio_fops, -1)) < 0)
+ goto err_dev1;
+ if ((s->codec.dev_mixer =
+ register_sound_mixer(&vrc5477_ac97_mixer_fops, -1)) < 0)
+ goto err_dev2;
+
+#ifdef CONFIG_LL_DEBUG
+ /* intialize the debug proc device */
+ s->ps = create_proc_read_entry(VRC5477_AC97_MODULE_NAME, 0, NULL,
+ proc_vrc5477_ac97_dump, NULL);
+#endif /* CONFIG_LL_DEBUG */
+
+ /* enable pci io and bus mastering */
+ if (pci_enable_device(pcidev))
+ goto err_dev3;
+ pci_set_master(pcidev);
+
+/*
+jsun_scan_pci_bus();
+vrc5477_show_pci_regs();
+vrc5477_show_pdar_regs();
+*/
+
+ /* cold reset the AC97 */
+ outl(VRC5477_ACLINK_CTRL_RST_ON | VRC5477_ACLINK_CTRL_RST_TIME,
+ s->io + VRC5477_ACLINK_CTRL);
+ while (inl(s->io + VRC5477_ACLINK_CTRL) & VRC5477_ACLINK_CTRL_RST_ON);
+
+/*
+jsun_ac97_test(s);
+*/
+
+ /* codec init */
+ if (!ac97_probe_codec(&s->codec))
+ goto err_dev3;
+
+#ifdef CONFIG_LL_DEBUG
+ sprintf(proc_str, "driver/%s/%d/ac97",
+ VRC5477_AC97_MODULE_NAME, s->codec.id);
+ s->ac97_ps = create_proc_read_entry (proc_str, 0, NULL,
+ ac97_read_proc, &s->codec);
+ /* TODO : why this proc file does not show up? */
+#endif
+
+ /* let us get the default volumne louder */
+ wrcodec(&s->codec, 0x2, 0);
+ wrcodec(&s->codec, 0x18, 0x0707);
+ /* mute line in loopback to line out */
+ wrcodec(&s->codec, 0x10, 0x8000);
+
+ /* by default we select line in the input */
+ wrcodec(&s->codec, 0x1a, 0x0404);
+ /* pick middle value for record gain */
+ // wrcodec(&s->codec, 0x1c, 0x0707);
+ wrcodec(&s->codec, 0x1c, 0x0f0f);
+ wrcodec(&s->codec, 0x1e, 0x07);
+
+ /* enable the master interrupt but disable all others */
+ outl(VRC5477_INT_MASK_NMASK, s->io + VRC5477_INT_MASK);
+
+ /* store it in the driver field */
+ pci_set_drvdata(pcidev, s);
+ pcidev->dma_mask = 0xffffffff;
+ /* put it into driver list */
+ list_add_tail(&s->devs, &devs);
+ /* increment devindex */
+ if (devindex < NR_DEVICE-1)
+ devindex++;
+ return 0;
+
+ err_dev3:
+ unregister_sound_mixer(s->codec.dev_mixer);
+ err_dev2:
+ unregister_sound_dsp(s->dev_audio);
+ err_dev1:
+ printk(KERN_ERR PFX "cannot register misc device\n");
+ free_irq(s->irq, s);
+ err_irq:
+ release_region(s->io, pci_resource_len(pcidev,0));
+ err_region:
+ kfree(s);
+ return -1;
+}
+
+static void __devinit vrc5477_ac97_remove(struct pci_dev *dev)
+{
+ struct vrc5477_ac97_state *s = pci_get_drvdata(dev);
+
+ if (!s)
+ return;
+ list_del(&s->devs);
+#ifdef CONFIG_LL_DEBUG
+ if (s->ps)
+ remove_proc_entry(VRC5477_AC97_MODULE_NAME, NULL);
+#endif /* CONFIG_LL_DEBUG */
+ synchronize_irq();
+ free_irq(s->irq, s);
+ release_region(s->io, pci_resource_len(dev,0));
+ unregister_sound_dsp(s->dev_audio);
+ unregister_sound_mixer(s->codec.dev_mixer);
+ kfree(s);
+ pci_set_drvdata(dev, NULL);
+}
+
+
+#define PCI_VENDOR_ID_NEC 0x1033
+#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00A6
+static struct pci_device_id id_table[] __devinitdata = {
+ { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_VRC5477_AC97,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, id_table);
+
+static struct pci_driver vrc5477_ac97_driver = {
+ name: VRC5477_AC97_MODULE_NAME,
+ id_table: id_table,
+ probe: vrc5477_ac97_probe,
+ remove: vrc5477_ac97_remove
+};
+
+static int __init init_vrc5477_ac97(void)
+{
+ if (!pci_present()) /* No PCI bus in this machine! */
+ return -ENODEV;
+ printk("Vrc5477 AC97 driver: version v0.1 time " __TIME__ " " __DATE__ " by Jun Sun\n");
+ return pci_module_init(&vrc5477_ac97_driver);
+}
+
+static void __exit cleanup_vrc5477_ac97(void)
+{
+ printk(KERN_INFO PFX "unloading\n");
+ pci_unregister_driver(&vrc5477_ac97_driver);
+}
+
+module_init(init_vrc5477_ac97);
+module_exit(cleanup_vrc5477_ac97);
+
static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
{
- static const char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
+ static char __initdata sv_ddma_name[] = "S3 Inc. SonicVibes DDMA Controller";
struct sv_state *s;
mm_segment_t fs;
int i, val, ret;
/*
+ * OSS driver for Linux 2.4.x for
*
- * Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x
+ * Trident 4D-Wave
+ * SiS 7018
+ * ALi 5451
+ * Tvia/IGST CyberPro 5050
*
* Driver: Alan Cox <alan@redhat.com>
*
* Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
* Ching-Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support
* Matt Wu <mattwu@acersoftech.com.cn> ALi 5451 Audio Core Support
+ * Peter Wächtler <pwaechtler@loewe-komp.de> CyberPro5050 support
*
*
* This program is free software; you can redistribute it and/or modify
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* History
+ * v0.14.9c
+ * August 10 2001 Peter Wächtler <pwaechtler@loewe-komp.de>
+ * added support for Tvia (formerly Integraphics/IGST) CyberPro5050
+ * this chip is often found in settop boxes (combined video+audio)
* v0.14.9b
* Switch to static inline not extern inline (gcc 3)
* v0.14.9a
* Implement multi-channels and S/PDIF in support for ALi 1535+
* v0.14.6
* Nov 1 2000 Ching-Ling Lee
- * Fix the bug of memory leak when swithing 5.1-channels to 2 channels.
+ * Fix the bug of memory leak when switching 5.1-channels to 2 channels.
* Add lock protection into dynamic changing format of data.
* Oct 18 2000 Ching-Ling Lee
* 5.1-channels support for ALi
#include <linux/pm.h>
-#define DRIVER_VERSION "0.14.9b"
+#define DRIVER_VERSION "0.14.9c"
/* magic numbers to protect our data structures */
#define TRIDENT_CARD_MAGIC 0x5072696E /* "Prin" */
TRIDENT_4D_DX = 0,
TRIDENT_4D_NX,
SIS_7018,
- ALI_5451
+ ALI_5451,
+ CYBER5050
};
static char * card_names[] = {
"Trident 4DWave DX",
"Trident 4DWave NX",
"SiS 7018 PCI Audio",
- "ALi Audio Accelerator"
+ "ALi Audio Accelerator",
+ "Tvia/IGST CyberPro 5050"
};
static struct pci_device_id trident_pci_tbl [] __devinitdata = {
PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_7018},
{PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, ALI_5451},
+ { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5050,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, CYBER5050},
{0,}
};
case PCI_DEVICE_ID_ALI_5451:
case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
case PCI_DEVICE_ID_TRIDENT_4DWAVE_NX:
+ case PCI_DEVICE_ID_INTERG_5050:
global_control |= (ENDLP_IE | MIDLP_IE);
break;
default:
#ifdef DEBUG
printk("trident: Enable Loop Interrupts, globctl = 0x%08X\n",
- global_control);
+ inl(TRID_REG(card, T4D_LFO_GC_CIR)));
#endif
return (TRUE);
}
outl(reg, TRID_REG(card, addr));
#ifdef DEBUG
- reg = inl(TRID_REG(card, T4D_AINTEN_B));
- printk("trident: enabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
- channel, reg);
+ reg = inl(TRID_REG(card, addr));
+ printk("trident: enabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+ channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
#endif
}
outl(mask, TRID_REG(card, bank->addresses->aint));
#ifdef DEBUG
- reg = inl(TRID_REG(card, T4D_AINTEN_B));
- printk("trident: disabled IRQ on channel %d, AINTEN_B = 0x%08x\n",
- channel, reg);
+ reg = inl(TRID_REG(card, addr));
+ printk("trident: disabled IRQ on channel %d, %s = 0x%08x(addr:%X)\n",
+ channel, addr==T4D_AINTEN_B? "AINTEN_B":"AINTEN_A",reg,addr);
#endif
}
outl(mask, TRID_REG(card, addr));
#ifdef DEBUG
- reg = inl(TRID_REG(card, T4D_START_B));
- printk("trident: start voice on channel %d, START_B = 0x%08x\n",
- channel, reg);
+ reg = inl(TRID_REG(card, addr));
+ printk("trident: start voice on channel %d, %s = 0x%08x(addr:%X)\n",
+ channel, addr==T4D_START_B? "START_B":"START_A",reg,addr);
#endif
}
outl(mask, TRID_REG(card, addr));
#ifdef DEBUG
- reg = inl(TRID_REG(card, T4D_STOP_B));
- printk("trident: stop voice on channel %d, STOP_B = 0x%08x\n",
- channel, reg);
+ reg = inl(TRID_REG(card, addr));
+ printk("trident: stop voice on channel %d, %s = 0x%08x(addr:%X)\n",
+ channel, addr==T4D_STOP_B? "STOP_B":"STOP_A",reg,addr);
#endif
}
#ifdef DEBUG
if (reg & mask)
- printk("trident: channel %d has interrupt, AINT_B = 0x%08x\n",
- channel, reg);
+ printk("trident: channel %d has interrupt, %s = 0x%08x\n",
+ channel,reg==T4D_AINT_B? "AINT_B":"AINT_A", reg);
#endif
return (reg & mask) ? TRUE : FALSE;
}
}
}
- /* no more free channels avaliable */
+ /* no more free channels available */
printk(KERN_ERR "trident: no more channels available on Bank B.\n");
return NULL;
}
card->banks[bank].bitmap &= ~(1 << (channel));
}
-/* called with spin lock held */
+static struct trident_channel * cyber_alloc_pcm_channel(struct trident_card *card)
+{
+ struct trident_pcm_bank *bank;
+ int idx;
+
+ /* The cyberpro 5050 has only 32 voices and one bank */
+ /* .. at least they are not documented (if you want to call that
+ * crap documentation), perhaps broken ? */
+
+ bank = &card->banks[BANK_A];
+
+ for (idx = 31; idx >= 0; idx--) {
+ if (!(bank->bitmap & (1 << idx))) {
+ struct trident_channel *channel = &bank->channels[idx];
+ bank->bitmap |= 1 << idx;
+ channel->num = idx;
+ return channel;
+ }
+ }
+
+ /* no more free channels available */
+ printk(KERN_ERR "cyberpro5050: no more channels available on Bank A.\n");
+ return NULL;
+}
+
+static void cyber_free_pcm_channel(struct trident_card *card, unsigned int channel)
+{
+ if (channel > 31)
+ return;
+ card->banks[BANK_A].bitmap &= ~(1 << (channel));
+}
+
+static inline void cyber_outidx(int port,int idx,int data)
+{
+ outb(idx,port);
+ outb(data,port+1);
+}
+
+static inline int cyber_inidx(int port,int idx)
+{
+ outb(idx,port);
+ return inb(port+1);
+}
+
+static int cyber_init_ritual(struct trident_card *card)
+{
+ /* some black magic, taken from SDK samples */
+ /* remove this and nothing will work */
+ int portDat;
+ int ret = 0;
+ unsigned long flags;
+
+ /*
+ * Keep interrupts off for the configure - we don't want to
+ * clash with another cyberpro config event
+ */
+
+ save_flags(flags);
+ cli();
+ portDat = cyber_inidx(CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE);
+ /* enable, if it was disabled */
+ if( (portDat & CYBER_BMSK_AUENZ) != CYBER_BMSK_AUENZ_ENABLE ) {
+ printk(KERN_INFO "cyberpro5050: enabling audio controller\n" );
+ cyber_outidx( CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE,
+ portDat | CYBER_BMSK_AUENZ_ENABLE );
+ /* check again if hardware is enabled now */
+ portDat = cyber_inidx(CYBER_PORT_AUDIO, CYBER_IDX_AUDIO_ENABLE);
+ }
+ if( (portDat & CYBER_BMSK_AUENZ) != CYBER_BMSK_AUENZ_ENABLE )
+ {
+ printk(KERN_ERR "cyberpro5050: initAudioAccess: no success\n" );
+ ret = -1;
+ }
+ else
+ {
+ cyber_outidx( CYBER_PORT_AUDIO, CYBER_IDX_IRQ_ENABLE, CYBER_BMSK_AUDIO_INT_ENABLE );
+ cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x01 );
+ cyber_outidx( CYBER_PORT_AUDIO, 0xba, 0x20 );
+ cyber_outidx( CYBER_PORT_AUDIO, 0xbb, 0x08 );
+ cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x02 );
+ cyber_outidx( CYBER_PORT_AUDIO, 0xb3, 0x06 );
+ cyber_outidx( CYBER_PORT_AUDIO, 0xbf, 0x00 );
+ }
+ restore_flags(flags);
+ return ret;
+}
+
+/* called with spin lock held */
static int trident_load_channel_registers(struct trident_card *card, u32 *data, unsigned int channel)
{
continue;
outl(data[i], TRID_REG(card, CHANNEL_START + 4*i));
}
- if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
+ if (card->pci_id == PCI_DEVICE_ID_ALI_5451 ||
+ card->pci_id == PCI_DEVICE_ID_INTERG_5050) {
outl(ALI_EMOD_Still, TRID_REG(card, ALI_EBUF1));
outl(ALI_EMOD_Still, TRID_REG(card, ALI_EBUF2));
}
data[3] = 0;
break;
case PCI_DEVICE_ID_SI_7018:
+ case PCI_DEVICE_ID_INTERG_5050:
data[0] = 0; /* Current Sample Offset */
data[2] = (channel->eso << 16) | (channel->delta & 0xffff);
data[3] = (channel->attribute << 16) | (channel->fm_vol & 0xffff);
channel->control |= CHANNEL_STEREO;
#ifdef DEBUG
printk("trident: trident_play_setup, LBA = 0x%08x, "
- "Delat = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
+ "Delta = 0x%08x, ESO = 0x%08x, Control = 0x%08x\n",
channel->lba, channel->delta, channel->eso, channel->control);
#endif
trident_write_voice_regs(state);
/* enable and set record channel */
outb(0x80 | channel->num, TRID_REG(card, T4D_REC_CH));
break;
+ case PCI_DEVICE_ID_INTERG_5050:
+ /* don't know yet, using special channel 22 in GC1(0xd4)? */
+ break;
default:
return;
}
case PCI_DEVICE_ID_ALI_5451:
case PCI_DEVICE_ID_SI_7018:
case PCI_DEVICE_ID_TRIDENT_4DWAVE_DX:
+ case PCI_DEVICE_ID_INTERG_5050:
/* 16 bits ESO, CSO for 7018 and DX */
cso = inw(TRID_REG(state->card, CH_DX_CSO_ALPHA_FMS + 2));
break;
/* No matter how much data is left in the buffer, we have to wait until
CSO == ESO/2 or CSO == ESO when address engine interrupts */
- if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451)
+ if (state->card->pci_id == PCI_DEVICE_ID_ALI_5451 ||
+ state->card->pci_id == PCI_DEVICE_ID_INTERG_5050)
{
diff = dmabuf->swptr - trident_get_dma_addr(state) + dmabuf->dmasize ;
diff = diff % (dmabuf->dmasize);
ali_set_timer(card);
}
+static void cyber_address_interrupt(struct trident_card *card)
+{
+ int i,irq_status;
+ struct trident_state *state;
+
+ /* Update the pointers for all channels we are running. */
+ /* FIXED: read interrupt status only once */
+ irq_status=inl(TRID_REG(card, T4D_AINT_A) );
+#ifdef DEBUG
+ printk("cyber_address_interrupt: irq_status 0x%X\n",irq_status);
+#endif
+ for (i = 0; i < NR_HW_CH; i++) {
+ if (irq_status & ( 1 << (31 - i)) ) {
+
+ /* clear bit by writing a 1, zeroes are ignored */
+ outl( (1 <<(31-i)), TRID_REG(card, T4D_AINT_A));
+
+#ifdef DEBUG
+ printk("cyber_interrupt: channel %d\n", 31-i);
+#endif
+ if ((state = card->states[i]) != NULL) {
+ trident_update_ptr(state);
+ } else {
+ printk("cyber5050: spurious channel irq %d.\n",
+ 31 - i);
+ trident_stop_voice(card, 31 - i);
+ trident_disable_voice_irq(card, 31 - i);
+ }
+ }
+ }
+}
+
static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct trident_card *card = (struct trident_card *)dev_id;
drain_dac(state, file->f_flags & O_NONBLOCK);
}
+#ifdef DEBUG
+ printk(KERN_ERR "trident: closing virtual channel %d, hard channel %d\n",
+ state->virt, dmabuf->channel->num);
+#endif
+
/* stop DMA state machine and free DMA buffers/channels */
down(&card->open_sem);
mask |= NX_AC97_WRITE_SECONDARY;
busy = NX_AC97_BUSY_WRITE;
break;
+ case PCI_DEVICE_ID_INTERG_5050:
+ address = SI_AC97_WRITE;
+ mask = busy = SI_AC97_BUSY_WRITE;
+ if (codec->id)
+ mask |= SI_AC97_SECONDARY;
+ break;
}
spin_lock_irqsave(&card->lock, flags);
mask = NX_AC97_BUSY_READ;
busy = NX_AC97_BUSY_READ | NX_AC97_BUSY_DATA;
break;
+ case PCI_DEVICE_ID_INTERG_5050:
+ address = SI_AC97_READ;
+ mask = busy = SI_AC97_BUSY_READ;
+ if (codec->id)
+ mask |= SI_AC97_SECONDARY;
+ break;
}
data = (mask | (reg & AC97_REG_ADDR));
ready_2nd = inl(TRID_REG(card, NX_ACR0_AC97_COM_STAT));
ready_2nd &= NX_AC97_SECONDARY_READY;
break;
+ case PCI_DEVICE_ID_INTERG_5050:
+ /* disable AC97 GPIO interrupt */
+ outl(0x00, TRID_REG(card, SI_AC97_GPIO));
+ /* when power up, the AC link is in cold reset mode, so stop it */
+ outl(PCMOUT|SURROUT|CENTEROUT|LFEOUT,
+ TRID_REG(card, SI_SERIAL_INTF_CTRL));
+ /* it take a long time to recover from a cold reset (especially when you have
+ more than one codec) */
+ udelay(2000);
+ ready_2nd = inl(TRID_REG(card, SI_SERIAL_INTF_CTRL));
+ ready_2nd &= SI_AC97_SECONDARY_READY;
+ break;
}
for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
struct pci_dev *pci_dev_m1533 = NULL;
if (pci_enable_device(pci_dev))
- return -ENODEV;
+ return -ENODEV;
if (pci_set_dma_mask(pci_dev, TRIDENT_DMA_MASK)) {
printk(KERN_ERR "trident: architecture does not support"
}
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
- iobase = pci_resource_start(pci_dev, 0);
+ if (pci_id->device == PCI_DEVICE_ID_INTERG_5050)
+ iobase = pci_resource_start(pci_dev, 1);
+ else
+ iobase = pci_resource_start(pci_dev, 0);
+
if (check_region(iobase, 256)) {
printk(KERN_ERR "trident: can't allocate I/O space at 0x%4.4lx\n",
iobase);
pci_write_config_byte(pci_dev_m1533, 0x7b, bits);
}
}
- else {
+ else if(card->pci_id == PCI_DEVICE_ID_INTERG_5050)
+ {
+ card->alloc_pcm_channel = cyber_alloc_pcm_channel;
+ card->alloc_rec_pcm_channel = cyber_alloc_pcm_channel;
+ card->free_pcm_channel = cyber_free_pcm_channel;
+ card->address_interrupt = cyber_address_interrupt;
+ cyber_init_ritual(card);
+ }
+ else
+ {
card->alloc_pcm_channel = trident_alloc_pcm_channel;
card->alloc_rec_pcm_channel = trident_alloc_pcm_channel;
card->free_pcm_channel = trident_free_pcm_channel;
}
MODULE_AUTHOR("Alan Cox, Aaron Holtzman, Ollie Lho, Ching Ling Lee");
-MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 PCI Audio Driver");
+MODULE_DESCRIPTION("Trident 4DWave/SiS 7018/ALi 5451 and Tvia/IGST CyberPro5050 PCI Audio Driver");
#define TRIDENT_MODULE_NAME "trident"
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451 PCI Audio, version "
+ printk(KERN_INFO "Trident 4DWave/SiS 7018/ALi 5451,Tvia CyberPro 5050 PCI Audio, version "
DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
if (!pci_register_driver(&trident_pci_driver)) {
#define TRID_REG( trident, x ) ( (trident) -> iobase + (x) )
+#define CYBER_PORT_AUDIO 0x3CE
+#define CYBER_IDX_AUDIO_ENABLE 0x7B
+#define CYBER_BMSK_AUDIO_INT_ENABLE 0x09
+#define CYBER_BMSK_AUENZ 0x01
+#define CYBER_BMSK_AUENZ_ENABLE 0x00
+#define CYBER_IDX_IRQ_ENABLE 0x12
+
#define VALIDATE_MAGIC(FOO,MAG) \
-({ \
- if (!(FOO) || (FOO)->magic != MAG) { \
- printk(invalid_magic,__FUNCTION__); \
- return -ENXIO; \
- } \
+({ \
+ if (!(FOO) || (FOO)->magic != MAG) { \
+ printk(invalid_magic,__FUNCTION__); \
+ return -ENXIO; \
+ } \
})
#define VALIDATE_STATE(a) VALIDATE_MAGIC(a,TRIDENT_STATE_MAGIC)
#define VIA_MIN_FRAG_NUMBER 2
-#ifndef AC97_PCM_LR_ADC_RATE
-# define AC97_PCM_LR_ADC_RATE AC97_PCM_LR_DAC_RATE
-#endif
-
/* 82C686 function 5 (audio codec) PCI configuration registers */
#define VIA_ACLINK_CTRL 0x41
#define VIA_FUNC_ENABLE 0x42
tristate 'Linux telephony support' CONFIG_PHONE
dep_tristate 'QuickNet Internet LineJack/PhoneJack support' CONFIG_PHONE_IXJ $CONFIG_PHONE
+dep_tristate 'QuickNet Internet LineJack/PhoneJack PCMCIA support' CONFIG_PHONE_IXJ_PCMCIA $CONFIG_PHONE_IXJ
endmenu
obj-n :=
obj-m :=
obj- :=
-export-objs := phonedev.o
+export-objs := phonedev.o ixj.o
obj-$(CONFIG_PHONE) += phonedev.o
obj-$(CONFIG_PHONE_IXJ) += ixj.o
+obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
O_TARGET := telephony.o
--- /dev/null
+/* configuration management identifiers */
+#define IXJ_VER_MAJOR 1
+#define IXJ_VER_MINOR 0
+#define IXJ_BLD_VER 1
/****************************************************************************
* ixj.c
*
- * Device Driver for the Internet PhoneJACK and
- * Internet LineJACK Telephony Cards.
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
*
- * (c) Copyright 1999-2000 Quicknet Technologies, Inc.
+ * (c) Copyright 1999-2001 Quicknet Technologies, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* John Sellers, <jsellers@quicknet.net>
* Mike Preston, <mpreston@quicknet.net>
*
- * Fixes:
- * Marc Boucher, <marc@mbsi.ca>
- * David Huggins-Daines <dhd@cepstral.com>
- *
+ * Fixes: David Huggins-Daines, <dhd@cepstral.com>
+ * Fabio Ferrari, <fabio.ferrari@digitro.com.br>
+ * Artis Kugevics, <artis@mt.lv>
+ *
* More information about the hardware related to this driver can be found
* at our website: http://www.quicknet.net
*
* IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
- * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
*
***************************************************************************/
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.31 2000/04/14 19:24:47 jaugenst Exp $";
-static char ixj_c_revision[] = "$Revision: 3.31 $";
+static char ixj_c_rcsid[] = "$Id: ixj.c,v 4.7 2001/08/13 06:19:33 craigs Exp $";
+static char ixj_c_revision[] = "$Revision: 4.7 $";
+
+/*
+ * $Log: ixj.c,v $
+ * Revision 4.7 2001/08/13 06:19:33 craigs
+ * Added additional changes from Alan Cox and John Anderson for
+ * 2.2 to 2.4 cleanup and bounds checking
+ *
+ * Revision 4.6 2001/08/13 01:05:05 craigs
+ * Really fixed PHONE_QUERY_CODEC problem this time
+ *
+ * Revision 4.5 2001/08/13 00:11:03 craigs
+ * Fixed problem in handling of PHONE_QUERY_CODEC, thanks to Shane Anderson
+ *
+ * Revision 4.4 2001/08/07 07:58:12 craigs
+ * Changed back to three digit version numbers
+ * Added tagbuild target to allow automatic and easy tagging of versions
+ *
+ * Revision 4.3 2001/08/07 07:24:47 craigs
+ * Added ixj-ver.h to allow easy configuration management of driver
+ * Added display of version number in /prox/ixj
+ *
+ * Revision 4.2 2001/08/06 07:07:19 craigs
+ * Reverted IXJCTL_DSP_TYPE and IXJCTL_DSP_VERSION files to original
+ * behaviour of returning int rather than short *
+ *
+ * Revision 4.1 2001/08/05 00:17:37 craigs
+ * More changes for correct PCMCIA installation
+ * Start of changes for backward Linux compatibility
+ *
+ * Revision 4.0 2001/08/04 12:33:12 craigs
+ * New version using GNU autoconf
+ *
+ * Revision 3.105 2001/07/20 23:14:32 eokerson
+ * More work on CallerID generation when using ring cadences.
+ *
+ * Revision 3.104 2001/07/06 01:33:55 eokerson
+ * Some bugfixes from Robert Vojta <vojta@ipex.cz> and a few mods to the Makefile.
+ *
+ * Revision 3.103 2001/07/05 19:20:16 eokerson
+ * Updated HOWTO
+ * Changed mic gain to 30dB on Internet LineJACK mic/speaker port.
+ *
+ * Revision 3.102 2001/07/03 23:51:21 eokerson
+ * Un-mute mic on Internet LineJACK when in speakerphone mode.
+ *
+ * Revision 3.101 2001/07/02 19:26:56 eokerson
+ * Removed initialiazation of ixjdebug and ixj_convert_loaded so they will go in the .bss instead of the .data
+ *
+ * Revision 3.100 2001/07/02 19:18:27 eokerson
+ * Changed driver to make dynamic allocation possible. We now pass IXJ * between functions instead of array indexes.
+ * Fixed the way the POTS and PSTN ports interact during a PSTN call to allow local answering.
+ * Fixed speaker mode on Internet LineJACK.
+ *
+ * Revision 3.99 2001/05/09 14:11:16 eokerson
+ * Fixed kmalloc error in ixj_build_filter_cadence. Thanks David Chan <cat@waulogy.stanford.edu>.
+ *
+ * Revision 3.98 2001/05/08 19:55:33 eokerson
+ * Fixed POTS hookstate detection while it is connected to PSTN port.
+ *
+ * Revision 3.97 2001/05/08 00:01:04 eokerson
+ * Fixed kernel oops when sending caller ID data.
+ *
+ * Revision 3.96 2001/05/04 23:09:30 eokerson
+ * Now uses one kernel timer for each card, instead of one for the entire driver.
+ *
+ * Revision 3.95 2001/04/25 22:06:47 eokerson
+ * Fixed squawking at beginning of some G.723.1 calls.
+ *
+ * Revision 3.94 2001/04/03 23:42:00 eokerson
+ * Added linear volume ioctls
+ * Added raw filter load ioctl
+ *
+ * Revision 3.93 2001/02/27 01:00:06 eokerson
+ * Fixed blocking in CallerID.
+ * Reduced size of ixj structure for smaller driver footprint.
+ *
+ * Revision 3.92 2001/02/20 22:02:59 eokerson
+ * Fixed isapnp and pcmcia module compatibility for 2.4.x kernels.
+ * Improved PSTN ring detection.
+ * Fixed wink generation on POTS ports.
+ *
+ * Revision 3.91 2001/02/13 00:55:44 eokerson
+ * Turn AEC back on after changing frame sizes.
+ *
+ * Revision 3.90 2001/02/12 16:42:00 eokerson
+ * Added ALAW codec, thanks to Fabio Ferrari for the table based converters to make ALAW from ULAW.
+ *
+ * Revision 3.89 2001/02/12 15:41:16 eokerson
+ * Fix from Artis Kugevics - Tone gains were not being set correctly.
+ *
+ * Revision 3.88 2001/02/05 23:25:42 eokerson
+ * Fixed lockup bugs with deregister.
+ *
+ * Revision 3.87 2001/01/29 21:00:39 eokerson
+ * Fix from Fabio Ferrari <fabio.ferrari@digitro.com.br> to properly handle EAGAIN and EINTR during non-blocking write.
+ * Updated copyright date.
+ *
+ * Revision 3.86 2001/01/23 23:53:46 eokerson
+ * Fixes to G.729 compatibility.
+ *
+ * Revision 3.85 2001/01/23 21:30:36 eokerson
+ * Added verbage about cards supported.
+ * Removed commands that put the card in low power mode at some times that it should not be in low power mode.
+ *
+ * Revision 3.84 2001/01/22 23:32:10 eokerson
+ * Some bugfixes from David Huggins-Daines, <dhd@cepstral.com> and other cleanups.
+ *
+ * Revision 3.83 2001/01/19 14:51:41 eokerson
+ * Fixed ixj_WriteDSPCommand to decrement usage counter when command fails.
+ *
+ * Revision 3.82 2001/01/19 00:34:49 eokerson
+ * Added verbosity to write overlap errors.
+ *
+ * Revision 3.81 2001/01/18 23:56:54 eokerson
+ * Fixed PSTN line test functions.
+ *
+ * Revision 3.80 2001/01/18 22:29:27 eokerson
+ * Updated AEC/AGC values for different cards.
+ *
+ * Revision 3.79 2001/01/17 02:58:54 eokerson
+ * Fixed AEC reset after Caller ID.
+ * Fixed Codec lockup after Caller ID on Call Waiting when not using 30ms frames.
+ *
+ * Revision 3.78 2001/01/16 19:43:09 eokerson
+ * Added support for Linux 2.4.x kernels.
+ *
+ * Revision 3.77 2001/01/09 04:00:52 eokerson
+ * Linetest will now test the line, even if it has previously succeded.
+ *
+ * Revision 3.76 2001/01/08 19:27:00 eokerson
+ * Fixed problem with standard cable on Internet PhoneCARD.
+ *
+ * Revision 3.75 2000/12/22 16:52:14 eokerson
+ * Modified to allow hookstate detection on the POTS port when the PSTN port is selected.
+ *
+ * Revision 3.74 2000/12/08 22:41:50 eokerson
+ * Added capability for G729B.
+ *
+ * Revision 3.73 2000/12/07 23:35:16 eokerson
+ * Added capability to have different ring pattern before CallerID data.
+ * Added hookstate checks in CallerID routines to stop FSK.
+ *
+ * Revision 3.72 2000/12/06 19:31:31 eokerson
+ * Modified signal behavior to only send one signal per event.
+ *
+ * Revision 3.71 2000/12/06 03:23:08 eokerson
+ * Fixed CallerID on Call Waiting.
+ *
+ * Revision 3.70 2000/12/04 21:29:37 eokerson
+ * Added checking to Smart Cable gain functions.
+ *
+ * Revision 3.69 2000/12/04 21:05:20 eokerson
+ * Changed ixjdebug levels.
+ * Added ioctls to change gains in Internet Phone CARD Smart Cable.
+ *
+ * Revision 3.68 2000/12/04 00:17:21 craigs
+ * Changed mixer voice gain to +6dB rather than 0dB
+ *
+ * Revision 3.67 2000/11/30 21:25:51 eokerson
+ * Fixed write signal errors.
+ *
+ * Revision 3.66 2000/11/29 22:42:44 eokerson
+ * Fixed PSTN ring detect problems.
+ *
+ * Revision 3.65 2000/11/29 07:31:55 craigs
+ * Added new 425Hz filter co-efficients
+ * Added card-specific DTMF prescaler initialisation
+ *
+ * Revision 3.64 2000/11/28 14:03:32 craigs
+ * Changed certain mixer initialisations to be 0dB rather than 12dB
+ * Added additional information to /proc/ixj
+ *
+ * Revision 3.63 2000/11/28 11:38:41 craigs
+ * Added display of AEC modes in AUTO and AGC mode
+ *
+ * Revision 3.62 2000/11/28 04:05:44 eokerson
+ * Improved PSTN ring detection routine.
+ *
+ * Revision 3.61 2000/11/27 21:53:12 eokerson
+ * Fixed flash detection.
+ *
+ * Revision 3.60 2000/11/27 15:57:29 eokerson
+ * More work on G.729 load routines.
+ *
+ * Revision 3.59 2000/11/25 21:55:12 eokerson
+ * Fixed errors in G.729 load routine.
+ *
+ * Revision 3.58 2000/11/25 04:08:29 eokerson
+ * Added board locks around G.729 and TS85 load routines.
+ *
+ * Revision 3.57 2000/11/24 05:35:17 craigs
+ * Added ability to retrieve mixer values on LineJACK
+ * Added complete initialisation of all mixer values at startup
+ * Fixed spelling mistake
+ *
+ * Revision 3.56 2000/11/23 02:52:11 robertj
+ * Added cvs change log keyword.
+ * Fixed bug in capabilities list when using G.729 module.
+ *
+ */
+
+#include "ixj-ver.h"
-//#define PERFMON_STATS
+#define PERFMON_STATS
#define IXJDEBUG 0
#define MAXRINGS 5
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
-#include <pcmcia/ds.h>
-#endif
-
-#ifdef CONFIG_ISAPNP
#include <linux/isapnp.h>
-#endif
#include "ixj.h"
#define TYPE(dev) (MINOR(dev) >> 4)
#define NUM(dev) (MINOR(dev) & 0xf)
-static int ixjdebug = 0;
+static int ixjdebug;
static int hertz = HZ;
static int samplerate = 100;
MODULE_PARM(ixjdebug, "i");
-static IXJ* ixj[IXJMAX];
+/************************************************************************
+*
+* ixjdebug meanings are now bit mapped instead of level based
+* Values can be or'ed together to turn on multiple messages
+*
+* bit 0 (0x0001) = any failure
+* bit 1 (0x0002) = general messages
+* bit 2 (0x0004) = POTS ringing related
+* bit 3 (0x0008) = PSTN events
+* bit 4 (0x0010) = PSTN Cadence state details
+* bit 5 (0x0020) = Tone detection triggers
+* bit 6 (0x0040) = Tone detection cadence details
+* bit 7 (0x0080) = ioctl tracking
+* bit 8 (0x0100) = signal tracking
+* bit 9 (0x0200) = CallerID generation details
+*
+************************************************************************/
+
+#ifdef IXJ_DYN_ALLOC
+
+static IXJ *ixj[IXJMAX];
+#define get_ixj(b) ixj[(b)]
+
+/*
+ * Allocate a free IXJ device
+ */
+
+static IXJ *ixj_alloc()
+{
+ for(cnt=0; cnt<IXJMAX; cnt++)
+ {
+ if(ixj[cnt] == NULL || !ixj[cnt]->DSPbase)
+ {
+ j = kmalloc(sizeof(IXJ), GFP_KERNEL);
+ if (j == NULL)
+ return NULL;
+ ixj[cnt] = j;
+ return j;
+ }
+ }
+ return NULL;
+}
-static struct timer_list ixj_timer;
+static void ixj_fsk_free(IXJ *j)
+{
+ if(j->fskdata != NULL) {
+ kfree(j->fskdata);
+ j->fskdata = NULL;
+ }
+}
-int ixj_convert_loaded = 0;
+static void ixj_fsk_alloc(IXJ *j)
+{
+ if(!j->fskdata) {
+ j->fskdata = kmalloc(8000, GFP_KERNEL);
+ if (!j->fskdata) {
+ if(ixjdebug & 0x0200) {
+ printk("IXJ phone%d - allocate failed\n", j->board);
+ }
+ return;
+ } else {
+ j->fsksize = 8000;
+ if(ixjdebug & 0x0200) {
+ printk("IXJ phone%d - allocate succeded\n", j->board);
+ }
+ }
+ }
+}
+
+#else
+
+static IXJ ixj[IXJMAX];
+#define get_ixj(b) (&ixj[(b)])
+
+/*
+ * Allocate a free IXJ device
+ */
+
+static IXJ *ixj_alloc(void)
+{
+ int cnt;
+ for(cnt=0; cnt<IXJMAX; cnt++)
+ {
+ if(!ixj[cnt].DSPbase)
+ {
+ return &ixj[cnt];
+ }
+ }
+ return NULL;
+}
+
+static inline void ixj_fsk_free(IXJ *j) {;}
+
+static inline void ixj_fsk_alloc(IXJ *j)
+{
+ j->fsksize = 8000;
+}
+
+#endif
+
+#ifdef PERFMON_STATS
+#define ixj_perfmon(x) ((x)++)
+#else
+#deifne ixj_perfmon(x) do {} while(0);
+#endif
+
+static int ixj_convert_loaded;
+
+static int ixj_WriteDSPCommand(unsigned short, IXJ *j);
/************************************************************************
*
*
************************************************************************/
-static int Stub(IXJ * j, unsigned long arg)
+static int Stub(IXJ * J, unsigned long arg)
{
return 0;
}
static void ixj_read_frame(IXJ *j);
static void ixj_write_frame(IXJ *j);
-static void ixj_init_timer(void);
-static void ixj_add_timer(void);
+static void ixj_init_timer(IXJ *j);
+static void ixj_add_timer(IXJ * j);
static void ixj_timeout(unsigned long ptr);
static int read_filters(IXJ *j);
static int LineMonitor(IXJ *j);
static int ixj_record_start(IXJ *j);
static void ixj_record_stop(IXJ *j);
static void set_rec_volume(IXJ *j, int volume);
+static int get_rec_volume(IXJ *j);
+static int set_rec_codec(IXJ *j, int rate);
static void ixj_vad(IXJ *j, int arg);
static int ixj_play_start(IXJ *j);
static void ixj_play_stop(IXJ *j);
static int ixj_set_tone_on(unsigned short arg, IXJ *j);
static int ixj_set_tone_off(unsigned short, IXJ *j);
static int ixj_play_tone(IXJ *j, char tone);
+static void ixj_aec_start(IXJ *j, int level);
static int idle(IXJ *j);
static void ixj_ring_on(IXJ *j);
static void ixj_ring_off(IXJ *j);
static void ixj_dialtone(IXJ *j);
static void ixj_cpt_stop(IXJ *j);
static char daa_int_read(IXJ *j);
+static char daa_CR_read(IXJ *j, int cr);
static int daa_set_mode(IXJ *j, int mode);
static int ixj_linetest(IXJ *j);
static int ixj_daa_write(IXJ *j);
static void DAA_Coeff_Australia(IXJ *j);
static void DAA_Coeff_Japan(IXJ *j);
static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
-// Serial Control Interface funtions
+/* Serial Control Interface funtions */
static int SCI_Control(IXJ *j, int control);
static int SCI_Prepare(IXJ *j);
static int SCI_WaitHighSCI(IXJ *j);
static int SCI_WaitLowSCI(IXJ *j);
static DWORD PCIEE_GetSerialNumber(WORD wAddress);
static int ixj_PCcontrol_wait(IXJ *j);
+static void ixj_pre_cid(IXJ *j);
static void ixj_write_cid(IXJ *j);
static void ixj_write_cid_bit(IXJ *j, int bit);
static int set_base_frame(IXJ *j, int size);
static int set_play_codec(IXJ *j, int rate);
static void set_rec_depth(IXJ *j, int depth);
-static void set_play_depth(IXJ *j, int depth);
+static int ixj_mixer(long val, IXJ *j);
/************************************************************************
CT8020/CT8021 Host Programmers Model
8-9 Hardware Status Register Read Only
A-B Hardware Control Register Read Write
C-D Host Transmit (Write) Data Buffer Access Port (buffer input)Write Only
-E-F Host Receive (Read) Data Buffer Access Port (buffer input) Read Only
+E-F Host Recieve (Read) Data Buffer Access Port (buffer input) Read Only
************************************************************************/
-extern __inline__ void ixj_read_HSR(IXJ *j)
+static inline void ixj_read_HSR(IXJ *j)
{
j->hsr.bytes.low = inb_p(j->DSPbase + 8);
j->hsr.bytes.high = inb_p(j->DSPbase + 9);
}
-extern __inline__ int IsControlReady(IXJ *j)
+static inline int IsControlReady(IXJ *j)
{
ixj_read_HSR(j);
return j->hsr.bits.controlrdy ? 1 : 0;
}
-extern __inline__ int IsPCControlReady(IXJ *j)
+static inline int IsPCControlReady(IXJ *j)
{
j->pccr1.byte = inb_p(j->XILINXbase + 3);
return j->pccr1.bits.crr ? 1 : 0;
}
-extern __inline__ int IsStatusReady(IXJ *j)
+static inline int IsStatusReady(IXJ *j)
{
ixj_read_HSR(j);
return j->hsr.bits.statusrdy ? 1 : 0;
}
-extern __inline__ int IsRxReady(IXJ *j)
+static inline int IsRxReady(IXJ *j)
{
ixj_read_HSR(j);
-#ifdef PERFMON_STATS
- ++j->rxreadycheck;
-#endif
+ ixj_perfmon(j->rxreadycheck);
return j->hsr.bits.rxrdy ? 1 : 0;
}
-extern __inline__ int IsTxReady(IXJ *j)
+static inline int IsTxReady(IXJ *j)
{
ixj_read_HSR(j);
-#ifdef PERFMON_STATS
- ++j->txreadycheck;
-#endif
+ ixj_perfmon(j->txreadycheck);
return j->hsr.bits.txrdy ? 1 : 0;
}
-extern __inline__ void set_play_volume(IXJ *j, int volume)
+static inline void set_play_volume(IXJ *j, int volume)
{
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: /dev/phone%d Setting Play Volume to 0x%4.4x\n", j->board, volume);
ixj_WriteDSPCommand(0xCF02, j);
ixj_WriteDSPCommand(volume, j);
}
-extern __inline__ void set_play_depth(IXJ *j, int depth)
+static int set_play_volume_linear(IXJ *j, int volume)
+{
+ int newvolume, dspplaymax;
+
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Play Volume to 0x%4.4x\n", j->board, volume);
+ if(volume > 100 || volume < 0) {
+ return -1;
+ }
+
+ /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+ switch (j->cardtype) {
+ case QTI_PHONEJACK:
+ dspplaymax = 0x380;
+ break;
+ case QTI_LINEJACK:
+ if(j->port == PORT_PSTN) {
+ dspplaymax = 0x48;
+ } else {
+ dspplaymax = 0x100;
+ }
+ break;
+ case QTI_PHONEJACK_LITE:
+ dspplaymax = 0x380;
+ break;
+ case QTI_PHONEJACK_PCI:
+ dspplaymax = 0x6C;
+ break;
+ case QTI_PHONECARD:
+ dspplaymax = 0x50;
+ break;
+ default:
+ return -1;
+ }
+ newvolume = (dspplaymax * volume) / 100;
+ set_play_volume(j, newvolume);
+ return 0;
+}
+
+static inline void set_play_depth(IXJ *j, int depth)
{
if (depth > 60)
depth = 60;
ixj_WriteDSPCommand(0x5280 + depth, j);
}
-extern __inline__ int get_play_volume(IXJ *j)
+static inline int get_play_volume(IXJ *j)
{
ixj_WriteDSPCommand(0xCF00, j);
return j->ssr.high << 8 | j->ssr.low;
}
-extern __inline__ BYTE SLIC_GetState(IXJ *j)
+static int get_play_volume_linear(IXJ *j)
+{
+ int volume, newvolume, dspplaymax;
+
+ /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+ switch (j->cardtype) {
+ case QTI_PHONEJACK:
+ dspplaymax = 0x380;
+ break;
+ case QTI_LINEJACK:
+ if(j->port == PORT_PSTN) {
+ dspplaymax = 0x48;
+ } else {
+ dspplaymax = 0x100;
+ }
+ break;
+ case QTI_PHONEJACK_LITE:
+ dspplaymax = 0x380;
+ break;
+ case QTI_PHONEJACK_PCI:
+ dspplaymax = 0x6C;
+ break;
+ case QTI_PHONECARD:
+ dspplaymax = 100;
+ break;
+ default:
+ return -1;
+ }
+ volume = get_play_volume(j);
+ newvolume = (volume * 100) / dspplaymax;
+ if(newvolume > 100)
+ newvolume = 100;
+ return newvolume;
+}
+
+static inline BYTE SLIC_GetState(IXJ *j)
{
if (j->cardtype == QTI_PHONECARD) {
j->pccr1.byte = 0;
fRetVal = TRUE;
}
break;
- case PLD_SLIC_STATE_OHT: // On-hook transmit
+ case PLD_SLIC_STATE_OHT: /* On-hook transmit */
case PLD_SLIC_STATE_STANDBY:
case PLD_SLIC_STATE_ACTIVE:
j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
fRetVal = TRUE;
break;
- case PLD_SLIC_STATE_APR: // Active polarity reversal
+ case PLD_SLIC_STATE_APR: /* Active polarity reversal */
- case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
+ case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
default:
fRetVal = FALSE;
ixj_PCcontrol_wait(j);
}
} else {
- // Set the C1, C2, C3 & B2EN signals.
+ /* Set the C1, C2, C3 & B2EN signals. */
switch (byState) {
case PLD_SLIC_STATE_OC:
j->pld_slicw.bits.c1 = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
fRetVal = TRUE;
break;
- case PLD_SLIC_STATE_OHT: // On-hook transmit
+ case PLD_SLIC_STATE_OHT: /* On-hook transmit */
j->pld_slicw.bits.c1 = 1;
j->pld_slicw.bits.c2 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
fRetVal = TRUE;
break;
- case PLD_SLIC_STATE_APR: // Active polarity reversal
+ case PLD_SLIC_STATE_APR: /* Active polarity reversal */
j->pld_slicw.bits.c1 = 0;
j->pld_slicw.bits.c2 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
fRetVal = TRUE;
break;
- case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
+ case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
j->pld_slicw.bits.c1 = 1;
j->pld_slicw.bits.c2 = 1;
return fRetVal;
}
-int ixj_register(int index, IXJ_REGFUNC regfunc)
+static int ixj_wink(IXJ *j)
+{
+ BYTE slicnow;
+
+ slicnow = SLIC_GetState(j);
+
+ j->pots_winkstart = jiffies;
+ SLIC_SetState(PLD_SLIC_STATE_OC, j);
+
+ while (time_before(jiffies, j->pots_winkstart + j->winktime)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+
+ SLIC_SetState(slicnow, j);
+ return 0;
+}
+
+static int ixj_register(int index, IXJ_REGFUNC regfunc)
{
int cnt;
int retval = 0;
switch (index) {
case G729LOADER:
ixj_DownloadG729 = regfunc;
- for (cnt = 0; cnt < IXJMAX; cnt++)
- if (ixj[cnt] != NULL)
- ixj_DownloadG729(ixj[cnt], 0L);
+ for (cnt = 0; cnt < IXJMAX; cnt++) {
+ IXJ *j = get_ixj(cnt);
+ while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ ixj_DownloadG729(j, 0L);
+ clear_bit(cnt, &j->busyflags);
+ }
break;
case TS85LOADER:
ixj_DownloadTS85 = regfunc;
- for (cnt = 0; cnt < IXJMAX; cnt++)
- if (ixj[cnt] != NULL)
- ixj_DownloadTS85(ixj[cnt], 0L);
+ for (cnt = 0; cnt < IXJMAX; cnt++) {
+ IXJ *j = get_ixj(cnt);
+ while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ ixj_DownloadTS85(j, 0L);
+ clear_bit(cnt, &j->busyflags);
+ }
break;
case PRE_READ:
ixj_PreRead = regfunc;
return retval;
}
-int ixj_unregister(int index)
+EXPORT_SYMBOL(ixj_register);
+
+static int ixj_unregister(int index)
{
int retval = 0;
switch (index) {
return retval;
}
-static void ixj_init_timer(void)
+EXPORT_SYMBOL(ixj_unregister);
+
+static void ixj_init_timer(IXJ *j)
{
- init_timer(&ixj_timer);
- ixj_timer.function = ixj_timeout;
- ixj_timer.data = (int) NULL;
+ init_timer(&j->timer);
+ j->timer.function = ixj_timeout;
+ j->timer.data = (unsigned long)j;
}
-static void ixj_add_timer(void)
+static void ixj_add_timer(IXJ *j)
{
- ixj_timer.expires = jiffies + (hertz / samplerate);
- add_timer(&ixj_timer);
+ j->timer.expires = jiffies + (hertz / samplerate);
+ add_timer(&j->timer);
}
static void ixj_tone_timeout(IXJ *j)
}
}
-extern __inline__ void ixj_kill_fasync(IXJ *j, int band)
+static inline void ixj_kill_fasync(IXJ *j, IXJ_SIGEVENT event, int dir)
{
- kill_fasync(&j->async_queue, SIGIO, band);
+ if(j->ixj_signals[event]) {
+ if(ixjdebug & 0x0100)
+ printk("Sending signal for event %d\n", event);
+ /* Send apps notice of change */
+ /* see config.h for macro definition */
+ kill_fasync(&(j->async_queue), j->ixj_signals[event], dir);
+ }
}
-static void ixj_timeout(unsigned long ptr)
+static void ixj_pstn_state(IXJ *j)
{
- int board;
- unsigned long jifon;
+ int var;
+ union XOPXR0 XR0, daaint;
- for (board = 0; board < IXJMAX; board++) {
- IXJ *j = ixj[board];
+ var = 10;
- if (j == NULL)
- continue;
+ XR0.reg = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg;
+ daaint.reg = 0;
+ XR0.bitreg.RMR = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
- if (j->DSPbase) {
-#ifdef PERFMON_STATS
- j->timerchecks++;
-#endif
- if (j->tone_state) {
- if (!ixj_hookstate(j)) {
- ixj_cpt_stop(j);
- if (j->m_hook) {
- j->m_hook = 0;
- j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, POLL_PRI);
+ j->pld_scrr.byte = inb_p(j->XILINXbase);
+ if (j->pld_scrr.bits.daaflag) {
+ daa_int_read(j);
+ if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
+ if(time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+ daaint.bitreg.RING = 1;
+ if(ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ DAA Ring Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+ }
+ } else {
+ daa_set_mode(j, SOP_PU_RESET);
+ }
+ }
+ if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
+ daaint.bitreg.Caller_ID = 1;
+ j->pstn_cid_intr = 1;
+ j->pstn_cid_received = jiffies;
+ if(ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ DAA Caller_ID Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+ }
+ }
+ if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
+ daaint.bitreg.Cadence = 1;
+ if(ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ DAA Cadence Interrupt /dev/phone%d at %ld\n", j->board, jiffies);
+ }
+ }
+ if(j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK != XR0.bitreg.VDD_OK) {
+ daaint.bitreg.VDD_OK = 1;
+ daaint.bitreg.SI_0 = j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK;
+ }
+ }
+ daa_CR_read(j, 1);
+ if(j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR != XR0.bitreg.RMR && time_after(jiffies, j->pstn_sleeptil) && !(j->flags.pots_pstn && j->hookstate)) {
+ daaint.bitreg.RMR = 1;
+ daaint.bitreg.SI_1 = j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR;
+ if(ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ DAA RMR /dev/phone%d was %s for %ld\n", j->board, XR0.bitreg.RMR?"on":"off", jiffies - j->pstn_last_rmr);
+ }
+ j->pstn_prev_rmr = j->pstn_last_rmr;
+ j->pstn_last_rmr = jiffies;
+ }
+ switch(j->daa_mode) {
+ case SOP_PU_SLEEP:
+ if (daaint.bitreg.RING) {
+ if (!j->flags.pstn_ringing) {
+ if (j->daa_mode != SOP_PU_RINGING) {
+ j->pstn_ring_int = jiffies;
+ daa_set_mode(j, SOP_PU_RINGING);
}
- continue;
}
- if (j->tone_state == 1)
- jifon = (hertz * j->tone_on_time * 25 / 100000);
- else
- jifon = (hertz * j->tone_on_time * 25 / 100000) +
- (hertz * j->tone_off_time * 25 / 100000);
- if (time_before(jiffies, j->tone_start_jif + jifon)) {
- if (j->tone_state == 1) {
- ixj_play_tone(j, j->tone_index);
- if (j->dsp.low == 0x20) {
- continue;
+ }
+ break;
+ case SOP_PU_RINGING:
+ if (daaint.bitreg.RMR) {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence a state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+ }
+ if (daaint.bitreg.SI_1) { /* Rising edge of RMR */
+ j->flags.pstn_rmr = 1;
+ j->pstn_ring_start = jiffies;
+ j->pstn_ring_stop = 0;
+ j->ex.bits.pstn_ring = 0;
+ if (j->cadence_f[4].state == 0) {
+ j->cadence_f[4].state = 1;
+ j->cadence_f[4].on1min = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 - var)) / 10000);
+ j->cadence_f[4].on1dot = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100)) / 10000);
+ j->cadence_f[4].on1max = jiffies + (long)((j->cadence_f[4].on1 * hertz * (100 + var)) / 10000);
+ } else if (j->cadence_f[4].state == 2) {
+ if((time_after(jiffies, j->cadence_f[4].off1min) &&
+ time_before(jiffies, j->cadence_f[4].off1max))) {
+ if (j->cadence_f[4].on2) {
+ j->cadence_f[4].state = 3;
+ j->cadence_f[4].on2min = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[4].on2dot = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100)) / 10000));
+ j->cadence_f[4].on2max = jiffies + (long)((j->cadence_f[4].on2 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[4].state = 7;
+ }
+ } else {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+ j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+ j->cadence_f[4].off1);
+ }
+ j->cadence_f[4].state = 0;
}
- } else {
- ixj_play_tone(j, 0);
- if (j->dsp.low == 0x20) {
- continue;
+ } else if (j->cadence_f[4].state == 4) {
+ if((time_after(jiffies, j->cadence_f[4].off2min) &&
+ time_before(jiffies, j->cadence_f[4].off2max))) {
+ if (j->cadence_f[4].on3) {
+ j->cadence_f[4].state = 5;
+ j->cadence_f[4].on3min = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[4].on3dot = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100)) / 10000));
+ j->cadence_f[4].on3max = jiffies + (long)((j->cadence_f[4].on3 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[4].state = 7;
+ }
+ } else {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+ j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+ j->cadence_f[4].off2);
+ }
+ j->cadence_f[4].state = 0;
}
- }
- } else {
- ixj_tone_timeout(j);
- if (j->flags.dialtone) {
- ixj_dialtone(j);
- }
- if (j->flags.busytone) {
- ixj_busytone(j);
- if (j->dsp.low == 0x20) {
- continue;
+ } else if (j->cadence_f[4].state == 6) {
+ if((time_after(jiffies, j->cadence_f[4].off3min) &&
+ time_before(jiffies, j->cadence_f[4].off3max))) {
+ j->cadence_f[4].state = 7;
+ } else {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+ j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+ j->cadence_f[4].off3);
+ }
+ j->cadence_f[4].state = 0;
}
+ } else {
+ j->cadence_f[4].state = 0;
}
- if (j->flags.ringback) {
- ixj_ringback(j);
- if (j->dsp.low == 0x20) {
- continue;
+ } else { /* Falling edge of RMR */
+ j->pstn_ring_start = 0;
+ j->pstn_ring_stop = jiffies;
+ if (j->cadence_f[4].state == 1) {
+ if(!j->cadence_f[4].on1) {
+ j->cadence_f[4].state = 7;
+ } else if((time_after(jiffies, j->cadence_f[4].on1min) &&
+ time_before(jiffies, j->cadence_f[4].on1max))) {
+ if (j->cadence_f[4].off1) {
+ j->cadence_f[4].state = 2;
+ j->cadence_f[4].off1min = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[4].off1dot = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100)) / 10000));
+ j->cadence_f[4].off1max = jiffies + (long)((j->cadence_f[4].off1 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[4].state = 7;
+ }
+ } else {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+ j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+ j->cadence_f[4].on1);
+ }
+ j->cadence_f[4].state = 0;
+ }
+ } else if (j->cadence_f[4].state == 3) {
+ if((time_after(jiffies, j->cadence_f[4].on2min) &&
+ time_before(jiffies, j->cadence_f[4].on2max))) {
+ if (j->cadence_f[4].off2) {
+ j->cadence_f[4].state = 4;
+ j->cadence_f[4].off2min = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[4].off2dot = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100)) / 10000));
+ j->cadence_f[4].off2max = jiffies + (long)((j->cadence_f[4].off2 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[4].state = 7;
+ }
+ } else {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+ j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+ j->cadence_f[4].on2);
+ }
+ j->cadence_f[4].state = 0;
+ }
+ } else if (j->cadence_f[4].state == 5) {
+ if((time_after(jiffies, j->cadence_f[4].on3min) &&
+ time_before(jiffies, j->cadence_f[4].on3max))) {
+ if (j->cadence_f[4].off3) {
+ j->cadence_f[4].state = 6;
+ j->cadence_f[4].off3min = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[4].off3dot = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100)) / 10000));
+ j->cadence_f[4].off3max = jiffies + (long)((j->cadence_f[4].off3 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[4].state = 7;
+ }
+ } else {
+ j->cadence_f[4].state = 0;
}
+ } else {
+ if (ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring Cadence fail state = %d /dev/phone%d at %ld should be %d\n",
+ j->cadence_f[4].state, j->board, jiffies - j->pstn_prev_rmr,
+ j->cadence_f[4].on3);
+ }
+ j->cadence_f[4].state = 0;
}
- if (!j->tone_state) {
- if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
- idle(j);
- if (j->dsp.low == 0x20 && j->play_mode != -1)
- ixj_play_start(j);
- if (j->dsp.low == 0x20 && j->rec_mode != -1)
- ixj_record_start(j);
+ }
+ if (ixjdebug & 0x0010) {
+ printk(KERN_INFO "IXJ Ring Cadence b state = %d /dev/phone%d at %ld\n", j->cadence_f[4].state, j->board, jiffies);
+ }
+ if (ixjdebug & 0x0010) {
+ switch(j->cadence_f[4].state) {
+ case 1:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+ j->cadence_f[4].on1, j->cadence_f[4].on1min, j->cadence_f[4].on1dot, j->cadence_f[4].on1max);
+ break;
+ case 2:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+ j->cadence_f[4].off1, j->cadence_f[4].off1min, j->cadence_f[4].off1dot, j->cadence_f[4].off1max);
+ break;
+ case 3:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+ j->cadence_f[4].on2, j->cadence_f[4].on2min, j->cadence_f[4].on2dot, j->cadence_f[4].on2max);
+ break;
+ case 4:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+ j->cadence_f[4].off2, j->cadence_f[4].off2min, j->cadence_f[4].off2dot, j->cadence_f[4].off2max);
+ break;
+ case 5:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+ j->cadence_f[4].on3, j->cadence_f[4].on3min, j->cadence_f[4].on3dot, j->cadence_f[4].on3max);
+ break;
+ case 6:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Ring Cadence state at %u min %ld - %ld - max %ld\n", j->board,
+ j->cadence_f[4].off3, j->cadence_f[4].off3min, j->cadence_f[4].off3dot, j->cadence_f[4].off3max);
+ break;
}
}
}
- if (!(j->tone_state && j->dsp.low == 0x20)) {
- if (IsRxReady(j)) {
- ixj_read_frame(j);
+ if (j->cadence_f[4].state == 7) {
+ j->cadence_f[4].state = 0;
+ j->pstn_ring_stop = jiffies;
+ j->ex.bits.pstn_ring = 1;
+ ixj_kill_fasync(j, SIG_PSTN_RING, POLL_IN);
+ if(ixjdebug & 0x0008) {
+ printk(KERN_INFO "IXJ Ring int set /dev/phone%d at %ld\n", j->board, jiffies);
}
- if (IsTxReady(j) && !j->flags.cidplay) {
- ixj_write_frame(j);
+ }
+ if((j->pstn_ring_int != 0 && time_after(jiffies, j->pstn_ring_int + (hertz * 5)) && !j->flags.pstn_rmr) ||
+ (j->pstn_ring_stop != 0 && time_after(jiffies, j->pstn_ring_stop + (hertz * 5)))) {
+ if(ixjdebug & 0x0008) {
+ printk("IXJ DAA no ring in 5 seconds /dev/phone%d at %ld\n", j->board, jiffies);
+ printk("IXJ DAA pstn ring int /dev/phone%d at %ld\n", j->board, j->pstn_ring_int);
+ printk("IXJ DAA pstn ring stop /dev/phone%d at %ld\n", j->board, j->pstn_ring_stop);
}
+ j->pstn_ring_stop = j->pstn_ring_int = 0;
+ daa_set_mode(j, SOP_PU_SLEEP);
+ }
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+ if (j->pstn_cid_intr && time_after(jiffies, j->pstn_cid_received + hertz)) {
+ ixj_daa_cid_read(j);
+ j->ex.bits.caller_id = 1;
+ ixj_kill_fasync(j, SIG_CALLER_ID, POLL_IN);
+ j->pstn_cid_intr = 0;
}
- if (j->flags.cringing) {
- if (ixj_hookstate(j) & 1) {
- j->flags.cringing = 0;
- ixj_ring_off(j);
+ if (daaint.bitreg.Cadence) {
+ if(ixjdebug & 0x0008) {
+ printk("IXJ DAA Cadence interrupt going to sleep /dev/phone%d\n", j->board);
+ }
+ daa_set_mode(j, SOP_PU_SLEEP);
+ j->ex.bits.pstn_ring = 0;
+ }
+ break;
+ case SOP_PU_CONVERSATION:
+ if (daaint.bitreg.VDD_OK) {
+ if(!daaint.bitreg.SI_0) {
+ if (!j->pstn_winkstart) {
+ if(ixjdebug & 0x0008) {
+ printk("IXJ DAA possible wink /dev/phone%d %ld\n", j->board, jiffies);
+ }
+ j->pstn_winkstart = jiffies;
+ }
} else {
- if (jiffies - j->ring_cadence_jif >= (hertz/2)) {
- if (j->flags.cidring && !j->flags.cidsent) {
- j->flags.cidsent = 1;
- ixj_write_cid(j);
- j->flags.cidring = 0;
+ if (j->pstn_winkstart) {
+ if(ixjdebug & 0x0008) {
+ printk("IXJ DAA possible wink end /dev/phone%d %ld\n", j->board, jiffies);
}
- j->ring_cadence_t--;
- if (j->ring_cadence_t == -1)
- j->ring_cadence_t = 15;
- j->ring_cadence_jif = jiffies;
- }
- if (j->ring_cadence & 1 << j->ring_cadence_t) {
- ixj_ring_on(j);
- } else {
- ixj_ring_off(j);
- j->flags.cidring = 1;
+ j->pstn_winkstart = 0;
}
- continue;
}
}
- if (!j->flags.ringing) {
- if (ixj_hookstate(j)) {
- if (j->dsp.low != 0x20 &&
- SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
- SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
- }
- LineMonitor(j);
- read_filters(j);
- ixj_WriteDSPCommand(0x511B, j);
- j->proc_load = j->ssr.high << 8 | j->ssr.low;
- if (!j->m_hook) {
- j->m_hook = j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, POLL_PRI);
+ if (j->pstn_winkstart && time_after(jiffies, j->pstn_winkstart + ((hertz * j->winktime) / 1000))) {
+ if(ixjdebug & 0x0008) {
+ printk("IXJ DAA wink detected going to sleep /dev/phone%d %ld\n", j->board, jiffies);
+ }
+ daa_set_mode(j, SOP_PU_SLEEP);
+ j->pstn_winkstart = 0;
+ j->ex.bits.pstn_wink = 1;
+ ixj_kill_fasync(j, SIG_PSTN_WINK, POLL_IN);
+ }
+ break;
+ }
+}
+
+static void ixj_timeout(unsigned long ptr)
+{
+ int board;
+ unsigned long jifon;
+ IXJ *j = (IXJ *)ptr;
+ board = j->board;
+
+ if (j->DSPbase && atomic_read(&j->DSPWrite) == 0 && test_and_set_bit(board, (void *)&j->busyflags) == 0) {
+ ixj_perfmon(j->timerchecks);
+ j->hookstate = ixj_hookstate(j);
+ if (j->tone_state) {
+ if (!(j->hookstate)) {
+ ixj_cpt_stop(j);
+ if (j->m_hook) {
+ j->m_hook = 0;
+ j->ex.bits.hookstate = 1;
+ ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+ }
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
+ }
+ if (j->tone_state == 1)
+ jifon = ((hertz * j->tone_on_time) * 25 / 100000);
+ else
+ jifon = ((hertz * j->tone_on_time) * 25 / 100000) + ((hertz * j->tone_off_time) * 25 / 100000);
+ if (time_before(jiffies, j->tone_start_jif + jifon)) {
+ if (j->tone_state == 1) {
+ ixj_play_tone(j, j->tone_index);
+ if (j->dsp.low == 0x20) {
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
}
} else {
- if (j->dsp.low != 0x20 &&
- SLIC_GetState(j) == PLD_SLIC_STATE_ACTIVE)
- // Internet LineJACK
- {
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+ ixj_play_tone(j, 0);
+ if (j->dsp.low == 0x20) {
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
}
- if (j->ex.bits.dtmf_ready) {
- j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+ }
+ } else {
+ ixj_tone_timeout(j);
+ if (j->flags.dialtone) {
+ ixj_dialtone(j);
+ }
+ if (j->flags.busytone) {
+ ixj_busytone(j);
+ if (j->dsp.low == 0x20) {
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
}
- if (j->m_hook) {
- j->m_hook = 0;
- j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, POLL_PRI);
+ }
+ if (j->flags.ringback) {
+ ixj_ringback(j);
+ if (j->dsp.low == 0x20) {
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
}
}
+ if (!j->tone_state) {
+ ixj_cpt_stop(j);
+ }
}
- if (j->cardtype == 300 && !j->flags.incheck) {
- if (j->flags.pstn_present) {
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- if (j->pld_scrr.bits.daaflag) {
- daa_int_read(j);
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
- if (!j->flags.pstn_ringing) {
- j->flags.pstn_ringing = 1;
- if (j->daa_mode != SOP_PU_RINGING)
- daa_set_mode(j, SOP_PU_RINGING);
+ }
+ if (!(j->tone_state && j->dsp.low == 0x20)) {
+ if (IsRxReady(j)) {
+ ixj_read_frame(j);
+ }
+ if (IsTxReady(j)) {
+ ixj_write_frame(j);
+ }
+ }
+ if (j->flags.cringing) {
+ if (j->hookstate & 1) {
+ j->flags.cringing = 0;
+ ixj_ring_off(j);
+ } else if(j->cadence_f[5].enable && ((!j->cadence_f[5].en_filter) || (j->cadence_f[5].en_filter && j->flags.firstring))) {
+ switch(j->cadence_f[5].state) {
+ case 0:
+ j->cadence_f[5].on1dot = jiffies + (long)((j->cadence_f[5].on1 * (hertz * 100) / 10000));
+ if (time_before(jiffies, j->cadence_f[5].on1dot)) {
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+ }
+ ixj_ring_on(j);
+ }
+ j->cadence_f[5].state = 1;
+ break;
+ case 1:
+ if (time_after(jiffies, j->cadence_f[5].on1dot)) {
+ j->cadence_f[5].off1dot = jiffies + (long)((j->cadence_f[5].off1 * (hertz * 100) / 10000));
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
}
+ ixj_ring_off(j);
+ j->cadence_f[5].state = 2;
}
- if (time_after(jiffies, j->pstn_sleeptil) && j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
- j->pstn_winkstart = 0;
- j->pstn_ring_stop = 0;
- j->pld_scrw.bits.led1 = 1;
- if (j->flags.pstn_ringing && !j->pstn_envelope) {
- if (j->daa_mode != SOP_PU_RINGING) {
- j->flags.pstn_ringing = 0;
- } else {
- j->pld_scrw.bits.led2 = 0;
- j->pstn_envelope = 1;
- j->pstn_ring_start = jiffies;
- j->pstn_ring_stop = 0;
- }
- j->ex.bits.pstn_ring = 0;
+ break;
+ case 2:
+ if (time_after(jiffies, j->cadence_f[5].off1dot)) {
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
}
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- } else {
- j->pld_scrw.bits.led1 = 0;
- j->pld_scrw.bits.led2 = 1;
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- if (j->flags.pstn_ringing && j->pstn_envelope) {
- if(!j->pstn_ring_stop) {
- j->pstn_ring_stop = jiffies;
- } else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
- j->pstn_ring_stop = 0;
- j->ex.bits.pstn_ring = 1;
- j->pstn_envelope = 0;
- }
- } else if (j->daa_mode == SOP_PU_CONVERSATION) {
- if (!j->pstn_winkstart) {
- j->pstn_winkstart = jiffies;
- } else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
- daa_set_mode(j, SOP_PU_SLEEP);
- j->pstn_winkstart = 0;
- j->ex.bits.pstn_wink = 1;
- }
+ ixj_ring_on(j);
+ if (j->cadence_f[5].on2) {
+ j->cadence_f[5].on2dot = jiffies + (long)((j->cadence_f[5].on2 * (hertz * 100) / 10000));
+ j->cadence_f[5].state = 3;
} else {
- j->ex.bits.pstn_ring = 0;
+ j->cadence_f[5].state = 7;
}
}
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Cadence) {
- if (j->daa_mode == SOP_PU_RINGING) {
- daa_set_mode(j, SOP_PU_SLEEP);
- j->flags.pstn_ringing = 0;
- j->ex.bits.pstn_ring = 0;
+ break;
+ case 3:
+ if (time_after(jiffies, j->cadence_f[5].on2dot)) {
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
}
- }
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.Caller_ID) {
- if (j->daa_mode == SOP_PU_RINGING && j->flags.pstn_ringing) {
- j->pstn_cid_intr = 1;
- j->pstn_cid_received = jiffies;
+ ixj_ring_off(j);
+ if (j->cadence_f[5].off2) {
+ j->cadence_f[5].off2dot = jiffies + (long)((j->cadence_f[5].off2 * (hertz * 100) / 10000));
+ j->cadence_f[5].state = 4;
+ } else {
+ j->cadence_f[5].state = 7;
}
}
- } else {
- if (j->pld_scrr.bits.daaflag) {
- daa_int_read(j);
+ break;
+ case 4:
+ if (time_after(jiffies, j->cadence_f[5].off2dot)) {
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+ }
+ ixj_ring_on(j);
+ if (j->cadence_f[5].on3) {
+ j->cadence_f[5].on3dot = jiffies + (long)((j->cadence_f[5].on3 * (hertz * 100) / 10000));
+ j->cadence_f[5].state = 5;
+ } else {
+ j->cadence_f[5].state = 7;
+ }
}
- j->ex.bits.pstn_ring = 0;
- if (j->pstn_cid_intr && jiffies > j->pstn_cid_received + (hertz * 3)) {
- if (j->daa_mode == SOP_PU_RINGING) {
- ixj_daa_cid_read(j);
- j->ex.bits.caller_id = 1;
+ break;
+ case 5:
+ if (time_after(jiffies, j->cadence_f[5].on3dot)) {
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+ }
+ ixj_ring_off(j);
+ if (j->cadence_f[5].off3) {
+ j->cadence_f[5].off3dot = jiffies + (long)((j->cadence_f[5].off3 * (hertz * 100) / 10000));
+ j->cadence_f[5].state = 6;
+ } else {
+ j->cadence_f[5].state = 7;
}
- j->pstn_cid_intr = 0;
- } else {
- j->ex.bits.caller_id = 0;
}
- if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
- j->pld_scrw.bits.led1 = 0;
- j->pld_scrw.bits.led2 = 1;
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- if (j->flags.pstn_ringing && j->pstn_envelope) {
- if(!j->pstn_ring_stop) {
- j->pstn_ring_stop = jiffies;
- } else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
- j->pstn_ring_stop = 0;
- j->ex.bits.pstn_ring = 1;
- j->pstn_envelope = 0;
- }
- j->pld_scrw.bits.led1 = 0;
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- } else if (j->daa_mode == SOP_PU_CONVERSATION) {
- if (!j->pstn_winkstart) {
- j->pstn_winkstart = jiffies;
- } else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
- daa_set_mode(j, SOP_PU_SLEEP);
- j->pstn_winkstart = 0;
- j->ex.bits.pstn_wink = 1;
- }
+ break;
+ case 6:
+ if (time_after(jiffies, j->cadence_f[5].off3dot)) {
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
}
+ j->cadence_f[5].state = 7;
}
+ break;
+ case 7:
+ if(ixjdebug & 0x0004) {
+ printk("Ringing cadence state = %d - %ld\n", j->cadence_f[5].state, jiffies);
+ }
+ j->flags.cidring = 1;
+ j->cadence_f[5].state = 0;
+ break;
+ }
+ if (j->flags.cidring && !j->flags.cidsent) {
+ j->flags.cidsent = 1;
+ if(j->fskdcnt) {
+ SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+ ixj_pre_cid(j);
+ }
+ j->flags.cidring = 0;
+ }
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
+ } else {
+ if (time_after(jiffies, j->ring_cadence_jif + (hertz / 2))) {
+ if (j->flags.cidring && !j->flags.cidsent) {
+ j->flags.cidsent = 1;
+ if(j->fskdcnt) {
+ SLIC_SetState(PLD_SLIC_STATE_OHT, j);
+ ixj_pre_cid(j);
+ }
+ j->flags.cidring = 0;
+ }
+ j->ring_cadence_t--;
+ if (j->ring_cadence_t == -1)
+ j->ring_cadence_t = 15;
+ j->ring_cadence_jif = jiffies;
+
+ if (j->ring_cadence & 1 << j->ring_cadence_t) {
+ if(j->flags.cidsent && j->cadence_f[5].en_filter)
+ j->flags.firstring = 1;
+ else
+ ixj_ring_on(j);
+ } else {
+ ixj_ring_off(j);
+ if(!j->flags.cidsent)
+ j->flags.cidring = 1;
}
}
+ clear_bit(board, &j->busyflags);
+ ixj_add_timer(j);
+ return;
}
- if (j->ex.bytes) {
- wake_up_interruptible(&j->poll_q); // Wake any blocked selects
- ixj_kill_fasync(j, POLL_PRI);
+ }
+ if (!j->flags.ringing) {
+ if (j->hookstate) { /* & 1) { */
+ if (j->dsp.low != 0x20 &&
+ SLIC_GetState(j) != PLD_SLIC_STATE_ACTIVE) {
+ SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j);
+ }
+ LineMonitor(j);
+ read_filters(j);
+ ixj_WriteDSPCommand(0x511B, j);
+ j->proc_load = j->ssr.high << 8 | j->ssr.low;
+ if (!j->m_hook && (j->hookstate & 1)) {
+ j->m_hook = j->ex.bits.hookstate = 1;
+ ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+ }
+ } else {
+ if (j->ex.bits.dtmf_ready) {
+ j->dtmf_wp = j->dtmf_rp = j->ex.bits.dtmf_ready = 0;
+ }
+ if (j->m_hook) {
+ j->m_hook = 0;
+ j->ex.bits.hookstate = 1;
+ ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
+ }
}
- } else {
- break;
}
+ if (j->cardtype == QTI_LINEJACK && !j->flags.pstncheck && j->flags.pstn_present) {
+ ixj_pstn_state(j);
+ }
+ if (j->ex.bytes) {
+ wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
+ }
+ clear_bit(board, &j->busyflags);
}
- ixj_add_timer();
+ ixj_add_timer(j);
}
static int ixj_status_wait(IXJ *j)
{
unsigned long jif;
- jif = jiffies;
+ jif = jiffies + ((60 * hertz) / 100);
while (!IsStatusReady(j)) {
- if (jiffies - jif > (60 * (hertz / 100))) {
+ ixj_perfmon(j->statuswait);
+ if (time_after(jiffies, jif)) {
+ ixj_perfmon(j->statuswaitfail);
return -1;
}
}
{
unsigned long jif;
- jif = jiffies;
+ jif = jiffies + ((60 * hertz) / 100);
while (!IsPCControlReady(j)) {
- if (jiffies - jif > (60 * (hertz / 100))) {
+ ixj_perfmon(j->pcontrolwait);
+ if (time_after(jiffies, jif)) {
+ ixj_perfmon(j->pcontrolwaitfail);
return -1;
}
}
return 0;
}
-int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
+static int ixj_WriteDSPCommand(unsigned short cmd, IXJ *j)
{
BYTES bytes;
unsigned long jif;
+ atomic_inc(&j->DSPWrite);
+ if(atomic_read(&j->DSPWrite) > 1) {
+ printk("IXJ %d DSP write overlap attempting command 0x%4.4x\n", j->board, cmd);
+ return -1;
+ }
bytes.high = (cmd & 0xFF00) >> 8;
bytes.low = cmd & 0x00FF;
- jif = jiffies;
+ jif = jiffies + ((60 * hertz) / 100);
while (!IsControlReady(j)) {
- if (jiffies - jif > (60 * (hertz / 100))) {
+ ixj_perfmon(j->iscontrolready);
+ if (time_after(jiffies, jif)) {
+ ixj_perfmon(j->iscontrolreadyfail);
+ atomic_dec(&j->DSPWrite);
+ if(atomic_read(&j->DSPWrite) > 0) {
+ printk("IXJ %d DSP overlaped command 0x%4.4x during control ready failure.\n", j->board, cmd);
+ while(atomic_read(&j->DSPWrite) > 0) {
+ atomic_dec(&j->DSPWrite);
+ }
+ }
return -1;
}
}
- outb_p(bytes.low, j->DSPbase + 6);
- outb_p(bytes.high, j->DSPbase + 7);
+ outb(bytes.low, j->DSPbase + 6);
+ outb(bytes.high, j->DSPbase + 7);
if (ixj_status_wait(j)) {
j->ssr.low = 0xFF;
j->ssr.high = 0xFF;
+ atomic_dec(&j->DSPWrite);
+ if(atomic_read(&j->DSPWrite) > 0) {
+ printk("IXJ %d DSP overlaped command 0x%4.4x during status wait failure.\n", j->board, cmd);
+ while(atomic_read(&j->DSPWrite) > 0) {
+ atomic_dec(&j->DSPWrite);
+ }
+ }
return -1;
}
/* Read Software Status Register */
j->ssr.low = inb_p(j->DSPbase + 2);
j->ssr.high = inb_p(j->DSPbase + 3);
+ atomic_dec(&j->DSPWrite);
+ if(atomic_read(&j->DSPWrite) > 0) {
+ printk("IXJ %d DSP overlaped command 0x%4.4x\n", j->board, cmd);
+ while(atomic_read(&j->DSPWrite) > 0) {
+ atomic_dec(&j->DSPWrite);
+ }
+ }
return 0;
}
* General Purpose IO Register read routine
*
***************************************************************************/
-extern __inline__ int ixj_gpio_read(IXJ *j)
+static inline int ixj_gpio_read(IXJ *j)
{
if (ixj_WriteDSPCommand(0x5143, j))
return -1;
return 0;
}
-extern __inline__ void LED_SetState(int state, IXJ *j)
+static inline void LED_SetState(int state, IXJ *j)
{
if (j->cardtype == QTI_LINEJACK) {
j->pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
j->pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
j->pld_scrw.bits.led4 = state & 0x8 ? 1 : 0;
- outb_p(j->pld_scrw.byte, j->XILINXbase);
+ outb(j->pld_scrw.byte, j->XILINXbase);
}
}
case QTI_PHONEJACK_PCI:
j->pld_slicw.pcib.mic = 0;
j->pld_slicw.pcib.spk = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
break;
case QTI_LINEJACK:
- ixj_set_pots(j, 0);
+ ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */
if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to
Software Control Register */
return 2;
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
- outb_p(j->pld_scrw.byte, j->XILINXbase);
+ outb(j->pld_scrw.byte, j->XILINXbase);
j->pld_clock.byte = 0;
- outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
+ outb(j->pld_clock.byte, j->XILINXbase + 0x04);
j->pld_slicw.bits.rly1 = 1;
j->pld_slicw.bits.spken = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ ixj_mixer(0x1200, j); /* Turn Off MIC switch on mixer left */
+ ixj_mixer(0x1401, j); /* Turn On Mono1 switch on mixer left */
+ ixj_mixer(0x1300, j); /* Turn Off MIC switch on mixer right */
+ ixj_mixer(0x1501, j); /* Turn On Mono1 switch on mixer right */
+ ixj_mixer(0x0E80, j); /*Mic mute */
+ ixj_mixer(0x0F00, j); /* Set mono out (SLIC) to 0dB */
+ ixj_mixer(0x0080, j); /* Mute Master Left volume */
+ ixj_mixer(0x0180, j); /* Mute Master Right volume */
SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
break;
case QTI_PHONEJACK:
j->gpio.bytes.high = 0x0B;
j->pld_slicw.bits.rly3 = 0;
j->pld_slicw.bits.rly1 = 1;
j->pld_slicw.bits.spken = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
j->port = PORT_PSTN;
} else {
return 4;
case QTI_PHONEJACK_PCI:
j->pld_slicw.pcib.mic = 1;
j->pld_slicw.pcib.spk = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
break;
case QTI_LINEJACK:
- ixj_set_pots(j, 0);
+ ixj_set_pots(j, 0); /* Disconnect POTS/PSTN relay */
+ if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to
+ Software Control Register */
+ return 2;
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
+
+ outb(j->pld_scrw.byte, j->XILINXbase);
+ j->pld_clock.byte = 0;
+ outb(j->pld_clock.byte, j->XILINXbase + 0x04);
+ j->pld_slicw.bits.rly1 = 1;
+ j->pld_slicw.bits.spken = 1;
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ ixj_mixer(0x1201, j); /* Turn On MIC switch on mixer left */
+ ixj_mixer(0x1400, j); /* Turn Off Mono1 switch on mixer left */
+ ixj_mixer(0x1301, j); /* Turn On MIC switch on mixer right */
+ ixj_mixer(0x1500, j); /* Turn Off Mono1 switch on mixer right */
+ ixj_mixer(0x0E06, j); /*Mic un-mute 0dB */
+ ixj_mixer(0x0F80, j); /* Mute mono out (SLIC) */
+ ixj_mixer(0x0000, j); /* Set Master Left volume to 0dB */
+ ixj_mixer(0x0100, j); /* Set Master Right volume to 0dB */
break;
case QTI_PHONEJACK:
j->gpio.bytes.high = 0x0B;
}
break;
case PORT_HANDSET:
- if (j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONEJACK_PCI) {
+ if (j->cardtype != QTI_PHONEJACK) {
return 5;
} else {
j->gpio.bytes.high = 0x0B;
if (arg) {
if (j->port == PORT_PSTN) {
j->pld_slicw.bits.rly1 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ j->flags.pots_pstn = 1;
return 1;
} else {
+ j->flags.pots_pstn = 0;
return 0;
}
} else {
j->pld_slicw.bits.rly1 = 1;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ outb(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ j->flags.pots_pstn = 0;
return 1;
}
} else {
static void ixj_ring_on(IXJ *j)
{
- if (j->dsp.low == 0x20) { // Internet PhoneJACK
+ if (j->dsp.low == 0x20) /* Internet PhoneJACK */
+ {
+ if (ixjdebug & 0x0004)
+ printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
+
j->gpio.bytes.high = 0x0B;
j->gpio.bytes.low = 0x00;
j->gpio.bits.gpio1 = 1;
j->gpio.bits.gpio2 = 1;
j->gpio.bits.gpio5 = 0;
ixj_WriteDSPCommand(j->gpio.word, j); /* send the ring signal */
- } else { // Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
+ } else /* Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI */
+ {
+ if (ixjdebug & 0x0004)
+ printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", j->board);
+
SLIC_SetState(PLD_SLIC_STATE_RINGING, j);
}
}
+static int ixj_siadc(IXJ *j, int val)
+{
+ if(j->cardtype == QTI_PHONECARD){
+ if(j->flags.pcmciascp){
+ if(val == -1)
+ return j->siadc.bits.rxg;
+
+ if(val < 0 || val > 0x1F)
+ return -1;
+
+ j->siadc.bits.hom = 0; /* Handset Out Mute */
+ j->siadc.bits.lom = 0; /* Line Out Mute */
+ j->siadc.bits.rxg = val; /*(0xC000 - 0x41C8) / 0x4EF; RX PGA Gain */
+ j->psccr.bits.addr = 6; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
+ j->psccr.bits.dev = 0;
+ outb(j->siadc.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(j);
+ return j->siadc.bits.rxg;
+ }
+ }
+ return -1;
+}
+
+static int ixj_sidac(IXJ *j, int val)
+{
+ if(j->cardtype == QTI_PHONECARD){
+ if(j->flags.pcmciascp){
+ if(val == -1)
+ return j->sidac.bits.txg;
+
+ if(val < 0 || val > 0x1F)
+ return -1;
+
+ j->sidac.bits.srm = 1; /* Speaker Right Mute */
+ j->sidac.bits.slm = 1; /* Speaker Left Mute */
+ j->sidac.bits.txg = val; /* (0xC000 - 0x45E4) / 0x5D3; TX PGA Gain */
+ j->psccr.bits.addr = 7; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
+ j->psccr.bits.dev = 0;
+ outb(j->sidac.byte, j->XILINXbase + 0x00);
+ outb(j->psccr.byte, j->XILINXbase + 0x01);
+ ixj_PCcontrol_wait(j);
+ return j->sidac.bits.txg;
+ }
+ }
+ return -1;
+}
+
static int ixj_pcmcia_cable_check(IXJ *j)
{
j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
} else if (j->flags.pcmciastate == 3) {
j->pccr2.bits.pwr = 0;
j->pccr2.bits.rstc = 1;
- outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
- j->checkwait = jiffies + hertz * 2;
+ outb(j->pccr2.byte, j->XILINXbase + 0x02);
+ j->checkwait = jiffies + (hertz * 2);
j->flags.incheck = 1;
j->flags.pcmciastate = 2;
return 0;
j->psccr.bits.rw = 1;
outb_p(j->psccr.byte, j->XILINXbase + 0x01);
ixj_PCcontrol_wait(j);
- j->flags.pcmciascp = 1; // Set Cable Present Flag
+ j->flags.pcmciascp = 1; /* Set Cable Present Flag */
- j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; // Get Cable Type
+ j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03; /* Get Cable Type */
if (j->flags.pcmciasct == 3) {
j->flags.pcmciastate = 4;
} else {
j->port = PORT_POTS;
}
- j->sic1.bits.cpd = 0; // Chip Power Down
-
- j->sic1.bits.mpd = 0; // MIC Bias Power Down
-
- j->sic1.bits.hpd = 0; // Handset Bias Power Down
-
- j->sic1.bits.lpd = 0; // Line Bias Power Down
-
- j->sic1.bits.spd = 1; // Speaker Drive Power Down
-
- j->psccr.bits.addr = 1; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
-
+ j->sic1.bits.cpd = 0; /* Chip Power Down */
+ j->sic1.bits.mpd = 0; /* MIC Bias Power Down */
+ j->sic1.bits.hpd = 0; /* Handset Bias Power Down */
+ j->sic1.bits.lpd = 0; /* Line Bias Power Down */
+ j->sic1.bits.spd = 1; /* Speaker Drive Power Down */
+ j->psccr.bits.addr = 1; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
j->psccr.bits.dev = 0;
outb(j->sic1.byte, j->XILINXbase + 0x00);
outb(j->psccr.byte, j->XILINXbase + 0x01);
ixj_PCcontrol_wait(j);
- j->sic2.bits.al = 0; // Analog Loopback DAC analog -> ADC analog
-
- j->sic2.bits.dl2 = 0; // Digital Loopback DAC -> ADC one bit
-
- j->sic2.bits.dl1 = 0; // Digital Loopback ADC -> DAC one bit
-
- j->sic2.bits.pll = 0; // 1 = div 10, 0 = div 5
-
- j->sic2.bits.hpd = 0; // HPF disable
-
- j->psccr.bits.addr = 2; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
+ j->sic2.bits.al = 0; /* Analog Loopback DAC analog -> ADC analog */
+ j->sic2.bits.dl2 = 0; /* Digital Loopback DAC -> ADC one bit */
+ j->sic2.bits.dl1 = 0; /* Digital Loopback ADC -> DAC one bit */
+ j->sic2.bits.pll = 0; /* 1 = div 10, 0 = div 5 */
+ j->sic2.bits.hpd = 0; /* HPF disable */
+ j->psccr.bits.addr = 2; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
j->psccr.bits.dev = 0;
outb(j->sic2.byte, j->XILINXbase + 0x00);
outb(j->psccr.byte, j->XILINXbase + 0x01);
ixj_PCcontrol_wait(j);
- j->psccr.bits.addr = 3; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
+ j->psccr.bits.addr = 3; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
j->psccr.bits.dev = 0;
- outb(0x00, j->XILINXbase + 0x00); // PLL Divide N1
-
+ outb(0x00, j->XILINXbase + 0x00); /* PLL Divide N1 */
outb(j->psccr.byte, j->XILINXbase + 0x01);
ixj_PCcontrol_wait(j);
- j->psccr.bits.addr = 4; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
+ j->psccr.bits.addr = 4; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
j->psccr.bits.dev = 0;
- outb(0x09, j->XILINXbase + 0x00); // PLL Multiply M1
-
+ outb(0x09, j->XILINXbase + 0x00); /* PLL Multiply M1 */
outb(j->psccr.byte, j->XILINXbase + 0x01);
ixj_PCcontrol_wait(j);
- j->sirxg.bits.lig = 1; // Line In Gain
-
- j->sirxg.bits.lim = 1; // Line In Mute
-
- j->sirxg.bits.mcg = 0; // MIC In Gain // was 3
-
- j->sirxg.bits.mcm = 0; // MIC In Mute
-
- j->sirxg.bits.him = 0; // Handset In Mute
-
- j->sirxg.bits.iir = 1; // IIR
-
- j->psccr.bits.addr = 5; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
+ j->sirxg.bits.lig = 1; /* Line In Gain */
+ j->sirxg.bits.lim = 1; /* Line In Mute */
+ j->sirxg.bits.mcg = 0; /* MIC In Gain was 3 */
+ j->sirxg.bits.mcm = 0; /* MIC In Mute */
+ j->sirxg.bits.him = 0; /* Handset In Mute */
+ j->sirxg.bits.iir = 1; /* IIR */
+ j->psccr.bits.addr = 5; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
j->psccr.bits.dev = 0;
outb(j->sirxg.byte, j->XILINXbase + 0x00);
outb(j->psccr.byte, j->XILINXbase + 0x01);
ixj_PCcontrol_wait(j);
- j->siadc.bits.hom = 0; // Handset Out Mute
-
- j->siadc.bits.lom = 0; // Line Out Mute
-
- j->siadc.bits.rxg = 23; //(0xC000 - 0x41C8) / 0x4EF; // RX PGA Gain
- j->psccr.bits.addr = 6; // R/W Smart Cable Register Address
+ ixj_siadc(j, 0x17);
+ ixj_sidac(j, 0x1D);
- j->psccr.bits.rw = 0; // Read / Write flag
-
- j->psccr.bits.dev = 0;
- outb(j->siadc.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
- j->sidac.bits.srm = 1; // Speaker Right Mute
-
- j->sidac.bits.slm = 1; // Speaker Left Mute
-
- j->sidac.bits.txg = (0xC000 - 0x45E4) / 0x5D3; // TX PGA Gain
-
- j->psccr.bits.addr = 7; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
-
- j->psccr.bits.dev = 0;
- outb(j->sidac.byte, j->XILINXbase + 0x00);
- outb(j->psccr.byte, j->XILINXbase + 0x01);
- ixj_PCcontrol_wait(j);
j->siaatt.bits.sot = 0;
- j->psccr.bits.addr = 9; // R/W Smart Cable Register Address
-
- j->psccr.bits.rw = 0; // Read / Write flag
-
+ j->psccr.bits.addr = 9; /* R/W Smart Cable Register Address */
+ j->psccr.bits.rw = 0; /* Read / Write flag */
j->psccr.bits.dev = 0;
outb(j->siaatt.byte, j->XILINXbase + 0x00);
outb(j->psccr.byte, j->XILINXbase + 0x01);
case QTI_PHONEJACK_LITE:
case QTI_PHONEJACK_PCI:
SLIC_GetState(j);
- if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
- j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
- if (j->flags.ringing) {
- if (!in_interrupt()) {
- det = jiffies + (hertz / 50);
- while (time_before(jiffies, det)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
+ if(j->cardtype == QTI_LINEJACK && j->flags.pots_pstn == 1 && (j->readers || j->writers)) {
+ fOffHook = j->pld_slicr.bits.potspstn ? 1 : 0;
+ if(fOffHook != j->p_hook) {
+ if(!j->checkwait) {
+ j->checkwait = jiffies;
+ }
+ if(time_before(jiffies, j->checkwait + 2)) {
+ fOffHook ^= 1;
+ } else {
+ j->checkwait = 0;
}
- SLIC_GetState(j);
- if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
- ixj_ring_on(j);
+ j->p_hook = fOffHook;
+ printk("IXJ : /dev/phone%d pots-pstn hookstate check %d at %ld\n", j->board, fOffHook, jiffies);
+ }
+ } else {
+ if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
+ j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
+ if (j->flags.ringing || j->flags.cringing) {
+ if (!in_interrupt()) {
+ det = jiffies + (hertz / 50);
+ while (time_before(jiffies, det)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ }
+ SLIC_GetState(j);
+ if (j->pld_slicr.bits.state == PLD_SLIC_STATE_RINGING) {
+ ixj_ring_on(j);
+ }
}
+ if (j->cardtype == QTI_PHONEJACK_PCI) {
+ j->pld_scrr.byte = inb_p(j->XILINXbase);
+ fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
+ } else
+ fOffHook = j->pld_slicr.bits.det ? 1 : 0;
}
- if (j->cardtype == QTI_PHONEJACK_PCI) {
- j->pld_scrr.byte = inb_p(j->XILINXbase);
- fOffHook = j->pld_scrr.pcib.det ? 1 : 0;
- } else
- fOffHook = j->pld_slicr.bits.det ? 1 : 0;
}
break;
case QTI_PHONECARD:
}
if (j->r_hook != fOffHook) {
j->r_hook = fOffHook;
- if (j->port != PORT_POTS) {
+ if (j->port == PORT_SPEAKER || j->port == PORT_HANDSET) { // || (j->port == PORT_PSTN && j->flags.pots_pstn == 0)) {
j->ex.bits.hookstate = 1;
- ixj_kill_fasync(j, POLL_PRI);
+ ixj_kill_fasync(j, SIG_HOOKSTATE, POLL_IN);
} else if (!fOffHook) {
- j->flash_end = jiffies + (hertz / 10 * 6);
+ j->flash_end = jiffies + ((60 * hertz) / 100);
+ }
+ }
+ if (fOffHook) {
+ if(time_before(jiffies, j->flash_end)) {
+ j->ex.bits.flash = 1;
+ j->flash_end = 0;
+ ixj_kill_fasync(j, SIG_FLASH, POLL_IN);
+ }
+ } else {
+ if(time_before(jiffies, j->flash_end)) {
+ fOffHook = 1;
}
}
+
if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
fOffHook |= 2;
- if (j->port == PORT_SPEAKER)
- fOffHook |= 2;
+ if (j->port == PORT_SPEAKER) {
+ if(j->cardtype == QTI_PHONECARD) {
+ if(j->flags.pcmciascp && j->flags.pcmciasct) {
+ fOffHook |= 2;
+ }
+ } else {
+ fOffHook |= 2;
+ }
+ }
if (j->port == PORT_HANDSET)
fOffHook |= 2;
- if (fOffHook && time_before(jiffies, j->flash_end))
- return 0;
- else
- return fOffHook;
+ return fOffHook;
}
static void ixj_ring_off(IXJ *j)
{
-
- if (j->dsp.low == 0x20) // Internet PhoneJACK
+ if (j->dsp.low == 0x20) /* Internet PhoneJACK */
{
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0004)
printk(KERN_INFO "IXJ Ring Off\n");
j->gpio.bytes.high = 0x0B;
j->gpio.bytes.low = 0x00;
j->gpio.bits.gpio2 = 1;
j->gpio.bits.gpio5 = 0;
ixj_WriteDSPCommand(j->gpio.word, j);
- } else // Internet LineJACK
- {
- if (ixjdebug > 0)
+ } else /* Internet LineJACK */
+ {
+ if (ixjdebug & 0x0004)
printk(KERN_INFO "IXJ Ring Off\n");
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+ if(!j->flags.cidplay)
+ SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
SLIC_GetState(j);
}
static void ixj_ring_start(IXJ *j)
{
j->flags.cringing = 1;
+ if (ixjdebug & 0x0004)
+ printk(KERN_INFO "IXJ Cadence Ringing Start /dev/phone%d\n", j->board);
if (ixj_hookstate(j) & 1) {
if (j->port == PORT_POTS)
ixj_ring_off(j);
j->flags.cringing = 0;
+ if (ixjdebug & 0x0004)
+ printk(KERN_INFO "IXJ Cadence Ringing Stopped /dev/phone%d off hook\n", j->board);
+ } else if(j->cadence_f[5].enable && (!j->cadence_f[5].en_filter)) {
+ j->ring_cadence_jif = jiffies;
+ j->flags.cidsent = j->flags.cidring = 0;
+ j->cadence_f[5].state = 0;
+ if(j->cadence_f[5].on1)
+ ixj_ring_on(j);
} else {
j->ring_cadence_jif = jiffies;
j->ring_cadence_t = 15;
} else {
ixj_ring_off(j);
}
+ j->flags.cidsent = j->flags.cidring = j->flags.firstring = 0;
}
}
return 0;
}
-int ixj_open(struct phone_device *p, struct file *file_p)
+static int ixj_open(struct phone_device *p, struct file *file_p)
{
- IXJ *j = file_p->private_data = ixj[p->board];
-
- if (j == NULL)
- return -ENODEV;
+ IXJ *j = get_ixj(p->board);
+ file_p->private_data = j;
if (!j->DSPbase)
return -ENODEV;
ixj_PCcontrol_wait(j);
}
- if (ixjdebug > 0)
+ j->flags.cidplay = 0;
+ j->flags.cidcw_ack = 0;
+
+ MOD_INC_USE_COUNT;
+
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Opening board %d\n", p->board);
j->framesread = j->frameswritten = 0;
IXJ_TONE ti;
int cnt;
IXJ *j = file_p->private_data;
+ int board = j->p.board;
- if (ixjdebug > 0)
+ /*
+ * Set up locks to ensure that only one process is talking to the DSP at a time.
+ * This is necessary to keep the DSP from locking up.
+ */
+ while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
if (j->cardtype == QTI_PHONECARD)
ixj_set_port(j, PORT_SPEAKER);
else
ixj_set_port(j, PORT_POTS);
+
aec_stop(j);
ixj_play_stop(j);
ixj_record_stop(j);
set_rec_volume(j, 0x100);
ixj_ring_off(j);
- // Restore the tone table to default settings.
+ /* Restore the tone table to default settings. */
ti.tone_index = 10;
ti.gain0 = 1;
ti.freq0 = hz941;
ti.gain1 = 0;
ti.freq1 = hz1209;
+ ixj_init_tone(j, &ti);
ti.tone_index = 11;
ti.gain0 = 1;
ti.freq0 = hz941;
ti.gain1 = 0;
ti.freq1 = hz1336;
+ ixj_init_tone(j, &ti);
ti.tone_index = 12;
ti.gain0 = 1;
ti.freq0 = hz941;
ti.gain1 = 0;
ti.freq1 = hz1477;
+ ixj_init_tone(j, &ti);
ti.tone_index = 13;
ti.gain0 = 1;
ti.freq0 = hz800;
ti.freq1 = hz620;
ixj_init_tone(j, &ti);
- set_rec_depth(j, 2); // Set Record Channel Limit to 2 frames
+ set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */
- set_play_depth(j, 2); // Set Playback Channel Limit to 2 frames
+ set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */
j->ex.bits.dtmf_ready = 0;
j->dtmf_state = 0;
j->flags.ringing = 0;
j->maxrings = MAXRINGS;
j->ring_cadence = USA_RING_CADENCE;
+ if(j->cadence_f[5].enable) {
+ j->cadence_f[5].enable = j->cadence_f[5].en_filter = j->cadence_f[5].state = 0;
+ }
j->drybuffer = 0;
j->winktime = 320;
j->flags.dtmf_oob = 0;
j->rec_codec = j->play_codec = 0;
j->rec_frame_size = j->play_frame_size = 0;
j->flags.cidsent = j->flags.cidring = 0;
- ixj_fasync(-1, file_p, 0); // remove from list of async notification
+ ixj_fasync(-1, file_p, 0); /* remove from list of async notification */
if(j->cardtype == QTI_LINEJACK && !j->readers && !j->writers) {
ixj_set_port(j, PORT_PSTN);
daa_set_mode(j, SOP_PU_SLEEP);
ixj_set_pots(j, 1);
}
- ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
+ ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */
+
+ /* Set up the default signals for events */
+ for (cnt = 0; cnt < 35; cnt++)
+ j->ixj_signals[cnt] = SIGIO;
+
+ /* Set the excetion signal enable flags */
+ j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring =
+ j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 =
+ j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
file_p->private_data = NULL;
+ clear_bit(board, &j->busyflags);
+ MOD_DEC_USE_COUNT;
return 0;
}
static int read_filters(IXJ *j)
{
- unsigned short fc, cnt;
+ unsigned short fc, cnt, trg;
int var;
- if (ixj_WriteDSPCommand(0x5144, j))
+ trg = 0;
+ if (ixj_WriteDSPCommand(0x5144, j)) {
+ if(ixjdebug & 0x0001) {
+ printk(KERN_INFO "Read Frame Counter failed!\n");
+ }
return -1;
-
+ }
fc = j->ssr.high << 8 | j->ssr.low;
if (fc == j->frame_count)
return 1;
var = 10;
for (cnt = 0; cnt < 4; cnt++) {
- if (ixj_WriteDSPCommand(0x5154 + cnt, j))
+ if (ixj_WriteDSPCommand(0x5154 + cnt, j)) {
+ if(ixjdebug & 0x0001) {
+ printk(KERN_INFO "Select Filter %d failed!\n", cnt);
+ }
return -1;
-
- if (ixj_WriteDSPCommand(0x515C, j))
+ }
+ if (ixj_WriteDSPCommand(0x515C, j)) {
+ if(ixjdebug & 0x0001) {
+ printk(KERN_INFO "Read Filter History %d failed!\n", cnt);
+ }
return -1;
-
+ }
j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
if (j->cadence_f[cnt].enable) {
if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
if (j->cadence_f[cnt].state == 0) {
j->cadence_f[cnt].state = 1;
- j->cadence_f[cnt].on1min = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 - var) / 10000);
- j->cadence_f[cnt].on1dot = jiffies + (j->cadence_f[cnt].on1 * hertz * (100) / 10000);
- j->cadence_f[cnt].on1max = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 + var) / 10000);
+ j->cadence_f[cnt].on1min = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[cnt].on1dot = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100)) / 10000));
+ j->cadence_f[cnt].on1max = jiffies + (long)((j->cadence_f[cnt].on1 * (hertz * (100 + var)) / 10000));
} else if (j->cadence_f[cnt].state == 2 &&
(time_after(jiffies, j->cadence_f[cnt].off1min) &&
time_before(jiffies, j->cadence_f[cnt].off1max))) {
if (j->cadence_f[cnt].on2) {
j->cadence_f[cnt].state = 3;
- j->cadence_f[cnt].on2min = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 - var) / 10000);
- j->cadence_f[cnt].on2dot = jiffies + (j->cadence_f[cnt].on2 * hertz * (100) / 10000);
- j->cadence_f[cnt].on2max = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 + var) / 10000);
+ j->cadence_f[cnt].on2min = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[cnt].on2dot = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100)) / 10000));
+ j->cadence_f[cnt].on2max = jiffies + (long)((j->cadence_f[cnt].on2 * (hertz * (100 + var)) / 10000));
} else {
- j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].state = 7;
}
} else if (j->cadence_f[cnt].state == 4 &&
(time_after(jiffies, j->cadence_f[cnt].off2min) &&
time_before(jiffies, j->cadence_f[cnt].off2max))) {
- if (j->cadence_f[cnt].on2) {
+ if (j->cadence_f[cnt].on3) {
j->cadence_f[cnt].state = 5;
- j->cadence_f[cnt].on3min = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 - var) / 10000);
- j->cadence_f[cnt].on3dot = jiffies + (j->cadence_f[cnt].on3 * hertz * (100) / 10000);
- j->cadence_f[cnt].on3max = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 + var) / 10000);
+ j->cadence_f[cnt].on3min = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[cnt].on3dot = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100)) / 10000));
+ j->cadence_f[cnt].on3max = jiffies + (long)((j->cadence_f[cnt].on3 * (hertz * (100 + var)) / 10000));
} else {
- j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].state = 7;
}
} else {
j->cadence_f[cnt].state = 0;
}
} else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
- if (j->cadence_f[cnt].state == 1 &&
- (time_after(jiffies, j->cadence_f[cnt].on1min) &&
- time_before(jiffies, j->cadence_f[cnt].on1max))) {
- j->cadence_f[cnt].state = 2;
- j->cadence_f[cnt].off1min = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 - var) / 10000);
- j->cadence_f[cnt].off1max = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 + var) / 10000);
- } else if (j->cadence_f[cnt].state == 3 &&
- (time_after(jiffies, j->cadence_f[cnt].on2min) &&
+ if (j->cadence_f[cnt].state == 1) {
+ if(!j->cadence_f[cnt].on1) {
+ j->cadence_f[cnt].state = 7;
+ } else if((time_after(jiffies, j->cadence_f[cnt].on1min) &&
+ time_before(jiffies, j->cadence_f[cnt].on1max))) {
+ if(j->cadence_f[cnt].off1) {
+ j->cadence_f[cnt].state = 2;
+ j->cadence_f[cnt].off1min = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[cnt].off1dot = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100)) / 10000));
+ j->cadence_f[cnt].off1max = jiffies + (long)((j->cadence_f[cnt].off1 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[cnt].state = 7;
+ }
+ } else {
+ j->cadence_f[cnt].state = 0;
+ }
+ } else if (j->cadence_f[cnt].state == 3) {
+ if((time_after(jiffies, j->cadence_f[cnt].on2min) &&
time_before(jiffies, j->cadence_f[cnt].on2max))) {
- j->cadence_f[cnt].state = 4;
- j->cadence_f[cnt].off2min = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 - var) / 10000);
- j->cadence_f[cnt].off2max = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 + var) / 10000);
- } else if (j->cadence_f[cnt].state == 5 &&
- (time_after(jiffies, j->cadence_f[cnt].on3min) &&
+ if(j->cadence_f[cnt].off2) {
+ j->cadence_f[cnt].state = 4;
+ j->cadence_f[cnt].off2min = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[cnt].off2dot = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100)) / 10000));
+ j->cadence_f[cnt].off2max = jiffies + (long)((j->cadence_f[cnt].off2 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[cnt].state = 7;
+ }
+ } else {
+ j->cadence_f[cnt].state = 0;
+ }
+ } else if (j->cadence_f[cnt].state == 5) {
+ if ((time_after(jiffies, j->cadence_f[cnt].on3min) &&
time_before(jiffies, j->cadence_f[cnt].on3max))) {
- j->cadence_f[cnt].state = 6;
- j->cadence_f[cnt].off3min = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 - var) / 10000);
- j->cadence_f[cnt].off3max = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 + var) / 10000);
+ if(j->cadence_f[cnt].off3) {
+ j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].off3min = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 - var)) / 10000));
+ j->cadence_f[cnt].off3dot = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100)) / 10000));
+ j->cadence_f[cnt].off3max = jiffies + (long)((j->cadence_f[cnt].off3 * (hertz * (100 + var)) / 10000));
+ } else {
+ j->cadence_f[cnt].state = 7;
+ }
+ } else {
+ j->cadence_f[cnt].state = 0;
+ }
} else {
j->cadence_f[cnt].state = 0;
}
!j->cadence_f[cnt].off1 &&
!j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
!j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].state = 7;
}
break;
case 3:
if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
!j->cadence_f[cnt].off2 &&
!j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].state = 7;
}
break;
case 5:
if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
!j->cadence_f[cnt].off3) {
- j->cadence_f[cnt].state = 6;
+ j->cadence_f[cnt].state = 7;
}
break;
}
}
+
+ if (ixjdebug & 0x0040) {
+ printk(KERN_INFO "IXJ Tone Cadence state = %d /dev/phone%d at %ld\n", j->cadence_f[cnt].state, j->board, jiffies);
+ switch(j->cadence_f[cnt].state) {
+ case 0:
+ printk(KERN_INFO "IXJ /dev/phone%d No Tone detected\n", j->board);
+ break;
+ case 1:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %u %ld - %ld - %ld\n", j->board,
+ j->cadence_f[cnt].on1, j->cadence_f[cnt].on1min, j->cadence_f[cnt].on1dot, j->cadence_f[cnt].on1max);
+ break;
+ case 2:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off1min,
+ j->cadence_f[cnt].off1max);
+ break;
+ case 3:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on2min,
+ j->cadence_f[cnt].on2max);
+ break;
+ case 4:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off2min,
+ j->cadence_f[cnt].off2max);
+ break;
+ case 5:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].on3min,
+ j->cadence_f[cnt].on3max);
+ break;
+ case 6:
+ printk(KERN_INFO "IXJ /dev/phone%d Next Tone Cadence state at %ld - %ld\n", j->board, j->cadence_f[cnt].off3min,
+ j->cadence_f[cnt].off3max);
+ break;
+ }
+ }
}
- if (j->cadence_f[cnt].state == 6) {
+ if (j->cadence_f[cnt].state == 7) {
j->cadence_f[cnt].state = 0;
if (j->cadence_f[cnt].enable == 1)
j->cadence_f[cnt].enable = 0;
switch (cnt) {
case 0:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter Cadence 0 triggered %ld\n", jiffies);
+ }
j->ex.bits.fc0 = 1;
+ ixj_kill_fasync(j, SIG_FC0, POLL_IN);
break;
case 1:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter Cadence 1 triggered %ld\n", jiffies);
+ }
j->ex.bits.fc1 = 1;
+ ixj_kill_fasync(j, SIG_FC1, POLL_IN);
break;
case 2:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter Cadence 2 triggered %ld\n", jiffies);
+ }
j->ex.bits.fc2 = 1;
+ ixj_kill_fasync(j, SIG_FC2, POLL_IN);
break;
case 3:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter Cadence 3 triggered %ld\n", jiffies);
+ }
j->ex.bits.fc3 = 1;
+ ixj_kill_fasync(j, SIG_FC3, POLL_IN);
break;
}
}
if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
(j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
+ if((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12))) {
+ trg = 1;
+ } else if((j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3))) {
+ trg = 0;
+ }
switch (cnt) {
case 0:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter 0 triggered %d at %ld\n", trg, jiffies);
+ }
j->ex.bits.f0 = 1;
+ ixj_kill_fasync(j, SIG_F0, POLL_IN);
break;
case 1:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter 1 triggered %d at %ld\n", trg, jiffies);
+ }
j->ex.bits.f1 = 1;
+ ixj_kill_fasync(j, SIG_F1, POLL_IN);
break;
case 2:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter 2 triggered %d at %ld\n", trg, jiffies);
+ }
j->ex.bits.f2 = 1;
+ ixj_kill_fasync(j, SIG_F2, POLL_IN);
break;
case 3:
+ if(ixjdebug & 0x0020) {
+ printk(KERN_INFO "Filter 3 triggered %d at %ld\n", trg, jiffies);
+ }
j->ex.bits.f3 = 1;
+ ixj_kill_fasync(j, SIG_F3, POLL_IN);
break;
}
}
}
j->dtmf_proc = 1;
- if (ixj_WriteDSPCommand(0x7000, j)) // Line Monitor
+ if (ixj_WriteDSPCommand(0x7000, j)) /* Line Monitor */
return -1;
j->dtmf.bytes.high = j->ssr.high;
j->dtmf_state = 1;
j->dtmf_current = j->dtmf.bits.digit;
}
- if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) // && j->dtmf_wp != j->dtmf_rp)
+ if (j->dtmf_state && !j->dtmf.bits.dtmf_valid) /* && j->dtmf_wp != j->dtmf_rp) */
{
- if(!j->flags.cidplay) {
+ if(!j->cidcw_wait) {
j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
j->dtmf_wp++;
if (j->dtmf_wp == 79)
j->dtmf_wp = 0;
j->ex.bits.dtmf_ready = 1;
+ if(j->ex_sig.bits.dtmf_ready) {
+ ixj_kill_fasync(j, SIG_DTMF_READY, POLL_IN);
+ }
}
- else if(j->dtmf_current == 25 || j->dtmf_current == 31) {
+ else if(j->dtmf_current == 0x00 || j->dtmf_current == 0x0D) {
+ if(ixjdebug & 0x0020) {
+ printk("IXJ phone%d saw CIDCW Ack DTMF %d from display at %ld\n", j->board, j->dtmf_current, jiffies);
+ }
j->flags.cidcw_ack = 1;
}
j->dtmf_state = 0;
return 0;
}
-ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
+/************************************************************************
+*
+* Functions to allow alaw <-> ulaw conversions.
+*
+************************************************************************/
+
+static void ulaw2alaw(unsigned char *buff, unsigned long len)
+{
+ static unsigned char table_ulaw2alaw[] =
+ {
+ 0x2A, 0x2B, 0x28, 0x29, 0x2E, 0x2F, 0x2C, 0x2D,
+ 0x22, 0x23, 0x20, 0x21, 0x26, 0x27, 0x24, 0x25,
+ 0x3A, 0x3B, 0x38, 0x39, 0x3E, 0x3F, 0x3C, 0x3D,
+ 0x32, 0x33, 0x30, 0x31, 0x36, 0x37, 0x34, 0x35,
+ 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D, 0x02,
+ 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05, 0x1A,
+ 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D, 0x12,
+ 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15, 0x6B,
+ 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D, 0x62, 0x63,
+ 0x60, 0x61, 0x66, 0x67, 0x64, 0x65, 0x7B, 0x79,
+ 0x7E, 0x7F, 0x7C, 0x7D, 0x72, 0x73, 0x70, 0x71,
+ 0x76, 0x77, 0x74, 0x75, 0x4B, 0x49, 0x4F, 0x4D,
+ 0x42, 0x43, 0x40, 0x41, 0x46, 0x47, 0x44, 0x45,
+ 0x5A, 0x5B, 0x58, 0x59, 0x5E, 0x5F, 0x5C, 0x5D,
+ 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51,
+ 0x56, 0x56, 0x57, 0x57, 0x54, 0x54, 0x55, 0xD5,
+ 0xAA, 0xAB, 0xA8, 0xA9, 0xAE, 0xAF, 0xAC, 0xAD,
+ 0xA2, 0xA3, 0xA0, 0xA1, 0xA6, 0xA7, 0xA4, 0xA5,
+ 0xBA, 0xBB, 0xB8, 0xB9, 0xBE, 0xBF, 0xBC, 0xBD,
+ 0xB2, 0xB3, 0xB0, 0xB1, 0xB6, 0xB7, 0xB4, 0xB5,
+ 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D, 0x82,
+ 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85, 0x9A,
+ 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D, 0x92,
+ 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95, 0xEB,
+ 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED, 0xE2, 0xE3,
+ 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5, 0xFB, 0xF9,
+ 0xFE, 0xFF, 0xFC, 0xFD, 0xF2, 0xF3, 0xF0, 0xF1,
+ 0xF6, 0xF7, 0xF4, 0xF5, 0xCB, 0xC9, 0xCF, 0xCD,
+ 0xC2, 0xC3, 0xC0, 0xC1, 0xC6, 0xC7, 0xC4, 0xC5,
+ 0xDA, 0xDB, 0xD8, 0xD9, 0xDE, 0xDF, 0xDC, 0xDD,
+ 0xD2, 0xD2, 0xD3, 0xD3, 0xD0, 0xD0, 0xD1, 0xD1,
+ 0xD6, 0xD6, 0xD7, 0xD7, 0xD4, 0xD4, 0xD5, 0xD5
+ };
+
+ while (len--)
+ *buff++ = table_ulaw2alaw[*(unsigned char *)buff];
+}
+
+static void alaw2ulaw(unsigned char *buff, unsigned long len)
+{
+ static unsigned char table_alaw2ulaw[] =
+ {
+ 0x29, 0x2A, 0x27, 0x28, 0x2D, 0x2E, 0x2B, 0x2C,
+ 0x21, 0x22, 0x1F, 0x20, 0x25, 0x26, 0x23, 0x24,
+ 0x39, 0x3A, 0x37, 0x38, 0x3D, 0x3E, 0x3B, 0x3C,
+ 0x31, 0x32, 0x2F, 0x30, 0x35, 0x36, 0x33, 0x34,
+ 0x0A, 0x0B, 0x08, 0x09, 0x0E, 0x0F, 0x0C, 0x0D,
+ 0x02, 0x03, 0x00, 0x01, 0x06, 0x07, 0x04, 0x05,
+ 0x1A, 0x1B, 0x18, 0x19, 0x1E, 0x1F, 0x1C, 0x1D,
+ 0x12, 0x13, 0x10, 0x11, 0x16, 0x17, 0x14, 0x15,
+ 0x62, 0x63, 0x60, 0x61, 0x66, 0x67, 0x64, 0x65,
+ 0x5D, 0x5D, 0x5C, 0x5C, 0x5F, 0x5F, 0x5E, 0x5E,
+ 0x74, 0x76, 0x70, 0x72, 0x7C, 0x7E, 0x78, 0x7A,
+ 0x6A, 0x6B, 0x68, 0x69, 0x6E, 0x6F, 0x6C, 0x6D,
+ 0x48, 0x49, 0x46, 0x47, 0x4C, 0x4D, 0x4A, 0x4B,
+ 0x40, 0x41, 0x3F, 0x3F, 0x44, 0x45, 0x42, 0x43,
+ 0x56, 0x57, 0x54, 0x55, 0x5A, 0x5B, 0x58, 0x59,
+ 0x4F, 0x4F, 0x4E, 0x4E, 0x52, 0x53, 0x50, 0x51,
+ 0xA9, 0xAA, 0xA7, 0xA8, 0xAD, 0xAE, 0xAB, 0xAC,
+ 0xA1, 0xA2, 0x9F, 0xA0, 0xA5, 0xA6, 0xA3, 0xA4,
+ 0xB9, 0xBA, 0xB7, 0xB8, 0xBD, 0xBE, 0xBB, 0xBC,
+ 0xB1, 0xB2, 0xAF, 0xB0, 0xB5, 0xB6, 0xB3, 0xB4,
+ 0x8A, 0x8B, 0x88, 0x89, 0x8E, 0x8F, 0x8C, 0x8D,
+ 0x82, 0x83, 0x80, 0x81, 0x86, 0x87, 0x84, 0x85,
+ 0x9A, 0x9B, 0x98, 0x99, 0x9E, 0x9F, 0x9C, 0x9D,
+ 0x92, 0x93, 0x90, 0x91, 0x96, 0x97, 0x94, 0x95,
+ 0xE2, 0xE3, 0xE0, 0xE1, 0xE6, 0xE7, 0xE4, 0xE5,
+ 0xDD, 0xDD, 0xDC, 0xDC, 0xDF, 0xDF, 0xDE, 0xDE,
+ 0xF4, 0xF6, 0xF0, 0xF2, 0xFC, 0xFE, 0xF8, 0xFA,
+ 0xEA, 0xEB, 0xE8, 0xE9, 0xEE, 0xEF, 0xEC, 0xED,
+ 0xC8, 0xC9, 0xC6, 0xC7, 0xCC, 0xCD, 0xCA, 0xCB,
+ 0xC0, 0xC1, 0xBF, 0xBF, 0xC4, 0xC5, 0xC2, 0xC3,
+ 0xD6, 0xD7, 0xD4, 0xD5, 0xDA, 0xDB, 0xD8, 0xD9,
+ 0xCF, 0xCF, 0xCE, 0xCE, 0xD2, 0xD3, 0xD0, 0xD1
+ };
+
+ while (len--)
+ *buff++ = table_alaw2ulaw[*(unsigned char *)buff];
+}
+
+static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
{
unsigned long i = *ppos;
- IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
- DECLARE_WAITQUEUE(wait, current);
+ IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ DECLARE_WAITQUEUE(wait, current);
if (j->flags.inread)
return -EALREADY;
while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
++j->read_wait;
- if(j->tone_state) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->read_q, &wait);
- j->flags.inread = 0;
- return -EAGAIN;
- }
if (file_p->f_flags & O_NONBLOCK) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&j->read_q, &wait);
remove_wait_queue(&j->read_q, &wait);
set_current_state(TASK_RUNNING);
/* Don't ever copy more than the user asks */
- i = copy_to_user(buf, j->read_buffer,
- min(unsigned int, length, j->read_buffer_size));
+ if(j->rec_codec == ALAW)
+ ulaw2alaw(j->read_buffer, min(length, j->read_buffer_size));
+ i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
j->read_buffer_ready = 0;
if (i) {
j->flags.inread = 0;
return -EFAULT;
} else {
j->flags.inread = 0;
- return min(unsigned int, length, j->read_buffer_size);
+ return min(length, j->read_buffer_size);
}
}
-ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
+static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
loff_t * ppos)
{
int pre_retval;
ssize_t read_retval = 0;
- IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
pre_retval = ixj_PreRead(j, 0L);
switch (pre_retval) {
return read_retval;
}
-ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
{
unsigned long i = *ppos;
IXJ *j = file_p->private_data;
- DECLARE_WAITQUEUE(wait, current);
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ DECLARE_WAITQUEUE(wait, current);
if (j->flags.inwrite)
return -EALREADY;
while (!j->write_buffers_empty) {
++j->write_wait;
- if(j->tone_state) {
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&j->write_q, &wait);
- j->flags.inwrite = 0;
- return -EAGAIN;
- }
if (file_p->f_flags & O_NONBLOCK) {
set_current_state(TASK_RUNNING);
remove_wait_queue(&j->write_q, &wait);
remove_wait_queue(&j->write_q, &wait);
if (j->write_buffer_wp + count >= j->write_buffer_end)
j->write_buffer_wp = j->write_buffer;
- i = copy_from_user(j->write_buffer_wp, buf,
- min(unsigned int, count, j->write_buffer_size));
+ i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
if (i) {
j->flags.inwrite = 0;
return -EFAULT;
}
+ if(j->play_codec == ALAW)
+ alaw2ulaw(j->write_buffer_wp, min(count, j->write_buffer_size));
j->flags.inwrite = 0;
- return min(unsigned int, count, j->write_buffer_size);
+ return min(count, j->write_buffer_size);
}
-ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
{
int pre_retval;
ssize_t write_retval = 0;
- IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
pre_retval = ixj_PreWrite(j, 0L);
switch (pre_retval) {
case NORMAL:
write_retval = ixj_write(file_p, buf, count, ppos);
- if (write_retval != -EFAULT) {
+ if (write_retval > 0) {
ixj_PostWrite(j, 0L);
j->write_buffer_wp += write_retval;
j->write_buffers_empty--;
break;
case NOPOST:
write_retval = ixj_write(file_p, buf, count, ppos);
- if (write_retval != -EFAULT) {
+ if (write_retval > 0) {
j->write_buffer_wp += write_retval;
j->write_buffers_empty--;
}
udelay(10);
}
}
- // Throw away word 0 of the 8021 compressed format to get standard G.729.
- if (j->rec_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
+ /* Throw away word 0 of the 8021 compressed format to get standard G.729. */
+ if (j->rec_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
inb_p(j->DSPbase + 0x0E);
inb_p(j->DSPbase + 0x0F);
}
}
++j->framesread;
if (j->intercom != -1) {
- IXJ *icom = ixj[j->intercom];
-
- if (icom == NULL) { /* shouldn't happen! */
- printk(KERN_ERR "ixj_read_frame(): j->intercom = %d = NULL!",
- j->intercom);
- return;
- }
-
- if (IsTxReady(icom)) {
+ if (IsTxReady(get_ixj(j->intercom))) {
for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
if (!(cnt % 16) && !IsTxReady(j)) {
dly = 0;
udelay(10);
}
}
- outb_p(*(j->read_buffer + cnt), icom->DSPbase + 0x0C);
- outb_p(*(j->read_buffer + cnt + 1), icom->DSPbase + 0x0D);
+ outb_p(*(j->read_buffer + cnt), get_ixj(j->intercom)->DSPbase + 0x0C);
+ outb_p(*(j->read_buffer + cnt + 1), get_ixj(j->intercom)->DSPbase + 0x0D);
}
- ++icom->frameswritten;
+ get_ixj(j->intercom)->frameswritten++;
}
} else {
j->read_buffer_ready = 1;
- wake_up_interruptible(&j->read_q); // Wake any blocked readers
+ wake_up_interruptible(&j->read_q); /* Wake any blocked readers */
- wake_up_interruptible(&j->poll_q); // Wake any blocked selects
+ wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
- ixj_kill_fasync(j, POLL_IN);
+ if(j->ixj_signals[SIG_READ_READY])
+ ixj_kill_fasync(j, SIG_READ_READY, POLL_OUT);
}
}
}
static void ixj_write_cid_bit(IXJ *j, int bit)
{
- int dly;
- IXJ_WORD dat;
-
while (j->fskcnt < 20) {
- if (!IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- // break;
- // printk("CID delay\n");
- }
- udelay(10);
- }
- }
- dat.word = j->fskdata[j->fskdcnt++] =
- fsk[bit][j->fskz][j->fskcnt];
- outb_p(dat.bytes.low, j->DSPbase + 0x0C);
- outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+ if(j->fskdcnt < (j->fsksize - 1))
+ j->fskdata[j->fskdcnt++] = fsk[bit][j->fskz][j->fskcnt];
+
j->fskcnt += 3;
}
j->fskcnt %= 20;
}
-static void ixj_write_cid_byte(IXJ *board, char byte)
+static void ixj_write_cid_byte(IXJ *j, char byte)
{
IXJ_CBYTE cb;
-// printk("Writing CID data %x - %c\n", byte, byte);
- cb.cbyte = byte;
- ixj_write_cid_bit(board, 0);
- ixj_write_cid_bit(board, cb.cbits.b0 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b1 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b2 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b3 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b4 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b5 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b6 ? 1 : 0);
- ixj_write_cid_bit(board, cb.cbits.b7 ? 1 : 0);
- ixj_write_cid_bit(board, 1);
+ cb.cbyte = byte;
+ ixj_write_cid_bit(j, 0);
+ ixj_write_cid_bit(j, cb.cbits.b0 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b1 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b2 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b3 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b4 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b5 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b6 ? 1 : 0);
+ ixj_write_cid_bit(j, cb.cbits.b7 ? 1 : 0);
+ ixj_write_cid_bit(j, 1);
}
-static void ixj_write_cid_seize(IXJ *board)
+static void ixj_write_cid_seize(IXJ *j)
{
int cnt;
for (cnt = 0; cnt < 150; cnt++) {
- ixj_write_cid_bit(board, 0);
- ixj_write_cid_bit(board, 1);
+ ixj_write_cid_bit(j, 0);
+ ixj_write_cid_bit(j, 1);
}
for (cnt = 0; cnt < 180; cnt++) {
- ixj_write_cid_bit(board, 1);
+ ixj_write_cid_bit(j, 1);
}
}
-static void ixj_write_cidcw_seize(IXJ *board)
+static void ixj_write_cidcw_seize(IXJ *j)
{
int cnt;
for (cnt = 0; cnt < 80; cnt++) {
- ixj_write_cid_bit(board, 1);
+ ixj_write_cid_bit(j, 1);
}
}
-static int ixj_write_cid_string(IXJ *board, char *s, int checksum)
+static int ixj_write_cid_string(IXJ *j, char *s, int checksum)
{
int cnt;
for (cnt = 0; cnt < strlen(s); cnt++) {
- ixj_write_cid_byte(board, s[cnt]);
+ ixj_write_cid_byte(j, s[cnt]);
checksum = (checksum + s[cnt]);
}
return checksum;
static void ixj_pad_fsk(IXJ *j, int pad)
{
- int cnt, dly;
+ int cnt;
for (cnt = 0; cnt < pad; cnt++) {
- if (!IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- }
- udelay(10);
- }
- }
- outb_p(0x00, j->DSPbase + 0x0C);
- outb_p(0x00, j->DSPbase + 0x0D);
+ if(j->fskdcnt < (j->fsksize - 1))
+ j->fskdata[j->fskdcnt++] = 0x0000;
}
for (cnt = 0; cnt < 720; cnt++) {
- if (!IsTxReady(j)) {
- dly = 0;
- while (!IsTxReady(j)) {
- if (dly++ > 5) {
- dly = 0;
- }
- udelay(10);
- }
- }
- outb_p(0x00, j->DSPbase + 0x0C);
- outb_p(0x00, j->DSPbase + 0x0D);
+ if(j->fskdcnt < (j->fsksize - 1))
+ j->fskdata[j->fskdcnt++] = 0x0000;
+ }
+}
+
+static void ixj_pre_cid(IXJ *j)
+{
+ j->cid_play_codec = j->play_codec;
+ j->cid_play_frame_size = j->play_frame_size;
+ j->cid_play_volume = get_play_volume(j);
+ j->cid_play_flag = j->flags.playing;
+
+ j->cid_rec_codec = j->rec_codec;
+ j->cid_rec_volume = get_rec_volume(j);
+ j->cid_rec_flag = j->flags.recording;
+
+ j->cid_play_aec_level = j->aec_level;
+
+ switch(j->baseframe.low) {
+ case 0xA0:
+ j->cid_base_frame_size = 20;
+ break;
+ case 0x50:
+ j->cid_base_frame_size = 10;
+ break;
+ case 0xF0:
+ j->cid_base_frame_size = 30;
+ break;
+ }
+
+ ixj_play_stop(j);
+ ixj_cpt_stop(j);
+
+ j->flags.cidplay = 1;
+
+ set_base_frame(j, 30);
+ set_play_codec(j, LINEAR16);
+ set_play_volume(j, 0x1B);
+ ixj_play_start(j);
+}
+
+static void ixj_post_cid(IXJ *j)
+{
+ ixj_play_stop(j);
+
+ if(j->cidsize > 5000) {
+ SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+ }
+ j->flags.cidplay = 0;
+ if(ixjdebug & 0x0200) {
+ printk("IXJ phone%d Finished Playing CallerID data %ld\n", j->board, jiffies);
+ }
+
+ ixj_fsk_free(j);
+
+ j->fskdcnt = 0;
+ set_base_frame(j, j->cid_base_frame_size);
+ set_play_codec(j, j->cid_play_codec);
+ ixj_aec_start(j, j->cid_play_aec_level);
+ set_play_volume(j, j->cid_play_volume);
+
+ set_rec_codec(j, j->cid_rec_codec);
+ set_rec_volume(j, j->cid_rec_volume);
+
+ if(j->cid_rec_flag)
+ ixj_record_start(j);
+
+ if(j->cid_play_flag)
+ ixj_play_start(j);
+
+ if(j->cid_play_flag) {
+ wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
}
}
int checksum = 0;
- if (j->dsp.low == 0x20)
+ if (j->dsp.low == 0x20 || j->flags.cidplay)
return;
- j->fskz = j->fskphase = j->fskcnt =
- j->fskdcnt = 0;
+ j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+ j->cidsize = j->cidcnt = 0;
- j->flags.cidplay = 1;
+ ixj_fsk_alloc(j);
strcpy(sdmf1, j->cid_send.month);
strcat(sdmf1, j->cid_send.day);
len3 = strlen(sdmf3);
mdmflen = len1 + len2 + len3 + 6;
- set_base_frame(j, 30);
- set_play_codec(j, LINEAR16);
-
- if (j->port == PORT_POTS)
- if(!j->r_hook)
- SLIC_SetState(PLD_SLIC_STATE_OHT, j);
-
- set_play_volume(j, 0x1B);
- ixj_play_start(j);
- ixj_write_cid_seize(j);
+ while(1){
+ ixj_write_cid_seize(j);
- ixj_write_cid_byte(j, 0x80);
- checksum = 0x80;
- ixj_write_cid_byte(j, mdmflen);
- checksum = checksum + mdmflen;
+ ixj_write_cid_byte(j, 0x80);
+ checksum = 0x80;
+ ixj_write_cid_byte(j, mdmflen);
+ checksum = checksum + mdmflen;
- ixj_write_cid_byte(j, 0x01);
- checksum = checksum + 0x01;
- ixj_write_cid_byte(j, len1);
- checksum = checksum + len1;
- checksum = ixj_write_cid_string(j, sdmf1, checksum);
+ ixj_write_cid_byte(j, 0x01);
+ checksum = checksum + 0x01;
+ ixj_write_cid_byte(j, len1);
+ checksum = checksum + len1;
+ checksum = ixj_write_cid_string(j, sdmf1, checksum);
+ if(ixj_hookstate(j) & 1)
+ break;
- ixj_write_cid_byte(j, 0x02);
- checksum = checksum + 0x02;
- ixj_write_cid_byte(j, len2);
- checksum = checksum + len2;
- checksum = ixj_write_cid_string(j, sdmf2, checksum);
+ ixj_write_cid_byte(j, 0x02);
+ checksum = checksum + 0x02;
+ ixj_write_cid_byte(j, len2);
+ checksum = checksum + len2;
+ checksum = ixj_write_cid_string(j, sdmf2, checksum);
+ if(ixj_hookstate(j) & 1)
+ break;
- ixj_write_cid_byte(j, 0x07);
- checksum = checksum + 0x07;
- ixj_write_cid_byte(j, len3);
- checksum = checksum + len3;
- checksum = ixj_write_cid_string(j, sdmf3, checksum);
+ ixj_write_cid_byte(j, 0x07);
+ checksum = checksum + 0x07;
+ ixj_write_cid_byte(j, len3);
+ checksum = checksum + len3;
+ checksum = ixj_write_cid_string(j, sdmf3, checksum);
+ if(ixj_hookstate(j) & 1)
+ break;
- checksum %= 256;
- checksum ^= 0xFF;
- checksum += 1;
+ checksum %= 256;
+ checksum ^= 0xFF;
+ checksum += 1;
- ixj_write_cid_byte(j, (char) checksum);
+ ixj_write_cid_byte(j, (char) checksum);
- pad = j->fskdcnt % 240;
- if (pad) {
- pad = 240 - pad;
+ pad = j->fskdcnt % 240;
+ if (pad) {
+ pad = 240 - pad;
+ }
+ ixj_pad_fsk(j, pad);
+ break;
}
- ixj_pad_fsk(j, pad);
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
- j->flags.cidplay = 0;
- ixj_play_stop(j);
+
+ ixj_write_frame(j);
}
static void ixj_write_cidcw(IXJ *j)
int checksum = 0;
- if (j->dsp.low == 0x20)
+ if (j->dsp.low == 0x20 || j->flags.cidplay)
return;
j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+ j->cidsize = j->cidcnt = 0;
- j->flags.cidplay = 1;
+ ixj_fsk_alloc(j);
+
+ j->flags.cidcw_ack = 0;
ti.tone_index = 23;
ti.gain0 = 1;
ti.freq1 = 0;
ixj_init_tone(j, &ti);
+ ixj_set_tone_on(1500, j);
+ ixj_set_tone_off(32, j);
+ if(ixjdebug & 0x0200) {
+ printk("IXJ cidcw phone%d first tone start at %ld\n", j->board, jiffies);
+ }
+ ixj_play_tone(j, 23);
+
+ clear_bit(j->board, &j->busyflags);
+ while(j->tone_state) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ if(ixjdebug & 0x0200) {
+ printk("IXJ cidcw phone%d first tone end at %ld\n", j->board, jiffies);
+ }
+
ti.tone_index = 24;
ti.gain0 = 1;
ti.freq0 = hz2130;
ti.freq1 = hz2750;
ixj_init_tone(j, &ti);
- ixj_set_tone_on(1200, j);
- ixj_play_tone(j, 23);
+ ixj_set_tone_off(10, j);
+ ixj_set_tone_on(600, j);
+ if(ixjdebug & 0x0200) {
+ printk("IXJ cidcw phone%d second tone start at %ld\n", j->board, jiffies);
+ }
+ ixj_play_tone(j, 24);
+ clear_bit(j->board, &j->busyflags);
while(j->tone_state) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
-
- ixj_set_tone_on(320, j);
- ixj_play_tone(j, 24);
-
- while(j->tone_state) {
+ while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
+ if(ixjdebug & 0x0200) {
+ printk("IXJ cidcw phone%d sent second tone at %ld\n", j->board, jiffies);
+ }
- j->cidcw_wait = jiffies + (200 * hertz / 100000);
+ j->cidcw_wait = jiffies + ((50 * hertz) / 100);
+ clear_bit(j->board, &j->busyflags);
while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
-
- if(!j->flags.cidcw_ack) {
- return;
+ while(test_and_set_bit(j->board, (void *)&j->busyflags) != 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
}
-
- strcpy(sdmf1, j->cid_send.month);
- strcat(sdmf1, j->cid_send.day);
- strcat(sdmf1, j->cid_send.hour);
- strcat(sdmf1, j->cid_send.min);
- strcpy(sdmf2, j->cid_send.number);
- strcpy(sdmf3, j->cid_send.name);
-
- len1 = strlen(sdmf1);
- len2 = strlen(sdmf2);
- len3 = strlen(sdmf3);
- mdmflen = len1 + len2 + len3 + 6;
-
- j->cid_play_codec = j->play_codec;
- ixj_play_stop(j);
-
- switch(j->baseframe.low) {
- case 0xA0:
- j->cid_base_frame_size = 20;
- break;
- case 0x50:
- j->cid_base_frame_size = 10;
- break;
- default:
- j->cid_base_frame_size = 30;
- break;
+ j->cidcw_wait = 0;
+ if(!j->flags.cidcw_ack) {
+ if(ixjdebug & 0x0200) {
+ printk("IXJ cidcw phone%d did not recieve ACK from display %ld\n", j->board, jiffies);
+ }
+ ixj_post_cid(j);
+ if(j->cid_play_flag) {
+ wake_up_interruptible(&j->write_q); /* Wake any blocked readers */
+ }
+ return;
+ } else {
+ ixj_pre_cid(j);
}
- set_base_frame(j, 30);
- set_play_codec(j, LINEAR16);
+ j->flags.cidcw_ack = 0;
+ strcpy(sdmf1, j->cid_send.month);
+ strcat(sdmf1, j->cid_send.day);
+ strcat(sdmf1, j->cid_send.hour);
+ strcat(sdmf1, j->cid_send.min);
+ strcpy(sdmf2, j->cid_send.number);
+ strcpy(sdmf3, j->cid_send.name);
+
+ len1 = strlen(sdmf1);
+ len2 = strlen(sdmf2);
+ len3 = strlen(sdmf3);
+ mdmflen = len1 + len2 + len3 + 6;
- set_play_volume(j, 0x1B);
- ixj_play_start(j);
ixj_write_cidcw_seize(j);
ixj_write_cid_byte(j, 0x80);
pad = 240 - pad;
}
ixj_pad_fsk(j, pad);
- j->flags.cidplay = 0;
- ixj_play_stop(j);
-
- set_base_frame(j, j->cid_base_frame_size);
- set_play_codec(j, j->cid_play_codec);
+ if(ixjdebug & 0x0200) {
+ printk("IXJ cidcw phone%d sent FSK data at %ld\n", j->board, jiffies);
+ }
}
static void ixj_write_vmwi(IXJ *j, int msg)
int checksum = 0;
- if (j->dsp.low == 0x20)
+ if (j->dsp.low == 0x20 || j->flags.cidplay)
return;
j->fskz = j->fskphase = j->fskcnt = j->fskdcnt = 0;
+ j->cidsize = j->cidcnt = 0;
- j->flags.cidplay = 1;
+ ixj_fsk_alloc(j);
mdmflen = 3;
- set_base_frame(j, 30);
- set_play_codec(j, LINEAR16);
-
if (j->port == PORT_POTS)
SLIC_SetState(PLD_SLIC_STATE_OHT, j);
- set_play_volume(j, 0x1B);
- ixj_play_start(j);
ixj_write_cid_seize(j);
ixj_write_cid_byte(j, 0x82);
pad = 240 - pad;
}
ixj_pad_fsk(j, pad);
- SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
- j->flags.cidplay = 0;
- ixj_play_stop(j);
}
static void ixj_write_frame(IXJ *j)
{
int cnt, frame_count, dly;
+ IXJ_WORD dat;
BYTES blankword;
frame_count = 0;
- if (j->write_buffer && j->write_buffers_empty < 2) {
+ if(j->flags.cidplay) {
+ for(cnt = 0; cnt < 480; cnt++) {
+ if (!(cnt % 16) && !IsTxReady(j)) {
+ dly = 0;
+ while (!IsTxReady(j)) {
+ if (dly++ > 5) {
+ dly = 0;
+ break;
+ }
+ udelay(10);
+ }
+ }
+ dat.word = j->fskdata[j->cidcnt++];
+ outb_p(dat.bytes.low, j->DSPbase + 0x0C);
+ outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+ cnt++;
+ }
+ if(j->cidcnt >= j->fskdcnt) {
+ ixj_post_cid(j);
+ }
+ /* This may seem rude, but if we just played one frame of FSK data for CallerID
+ and there is real audio data in the buffer, we need to throw it away because
+ we just used it's time slot */
+ if (j->write_buffer_rp > j->write_buffer_wp) {
+ j->write_buffer_rp += j->cid_play_frame_size * 2;
+ if (j->write_buffer_rp >= j->write_buffer_end) {
+ j->write_buffer_rp = j->write_buffer;
+ }
+ j->write_buffers_empty++;
+ wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
+
+ wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
+ }
+ } else if (j->write_buffer && j->write_buffers_empty < 1) {
if (j->write_buffer_wp > j->write_buffer_rp) {
frame_count =
(j->write_buffer_wp - j->write_buffer_rp) / (j->play_frame_size * 2);
outb_p((blankword.high), j->DSPbase + 0x0D);
}
j->flags.play_first_frame = 0;
+ } else if (j->play_codec == G723_63 && j->flags.play_first_frame) {
+ for (cnt = 0; cnt < 24; cnt++) {
+ if(cnt == 12) {
+ blankword.low = 0x02;
+ blankword.high = 0x00;
+ }
+ else {
+ blankword.low = blankword.high = 0x00;
+ }
+ if (!(cnt % 16) && !IsTxReady(j)) {
+ dly = 0;
+ while (!IsTxReady(j)) {
+ if (dly++ > 5) {
+ dly = 0;
+ break;
+ }
+ udelay(10);
+ }
+ }
+ outb_p((blankword.low), j->DSPbase + 0x0C);
+ outb_p((blankword.high), j->DSPbase + 0x0D);
+ }
+ j->flags.play_first_frame = 0;
}
for (cnt = 0; cnt < j->play_frame_size * 2; cnt += 2) {
if (!(cnt % 16) && !IsTxReady(j)) {
udelay(10);
}
}
-// Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG
- // so all frames are type 1.
- if (j->play_codec == G729 && (cnt == 0 || cnt == 5 || cnt == 10)) {
- outb_p(0x01, j->DSPbase + 0x0C);
- outb_p(0x00, j->DSPbase + 0x0D);
+ /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */
+ if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) {
+ if(j->write_buffer_rp + cnt == 0 && j->write_buffer_rp + cnt + 1 == 0 && j->write_buffer_rp + cnt + 2 == 0 &&
+ j->write_buffer_rp + cnt + 3 == 0 && j->write_buffer_rp + cnt + 4 == 0 && j->write_buffer_rp + cnt + 5 == 0 &&
+ j->write_buffer_rp + cnt + 6 == 0 && j->write_buffer_rp + cnt + 7 == 0 && j->write_buffer_rp + cnt + 8 == 0 &&
+ j->write_buffer_rp + cnt + 9 == 0) {
+ /* someone is trying to write silence lets make this a type 0 frame. */
+ outb_p(0x00, j->DSPbase + 0x0C);
+ outb_p(0x00, j->DSPbase + 0x0D);
+ } else {
+ /* so all other frames are type 1. */
+ outb_p(0x01, j->DSPbase + 0x0C);
+ outb_p(0x00, j->DSPbase + 0x0D);
+ }
}
outb_p(*(j->write_buffer_rp + cnt), j->DSPbase + 0x0C);
outb_p(*(j->write_buffer_rp + cnt + 1), j->DSPbase + 0x0D);
j->write_buffer_rp = j->write_buffer;
}
j->write_buffers_empty++;
- wake_up_interruptible(&j->write_q); // Wake any blocked writers
+ wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
- wake_up_interruptible(&j->poll_q); // Wake any blocked selects
+ wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
- ixj_kill_fasync(j, POLL_OUT);
++j->frameswritten;
}
} else {
j->drybuffer++;
}
+ if(j->ixj_signals[SIG_WRITE_READY]) {
+ ixj_kill_fasync(j, SIG_WRITE_READY, POLL_OUT);
+ }
}
static int idle(IXJ *j)
{
- if (ixj_WriteDSPCommand(0x0000, j)) // DSP Idle
+ if (ixj_WriteDSPCommand(0x0000, j)) /* DSP Idle */
return 0;
- if (j->ssr.high || j->ssr.low)
+
+ if (j->ssr.high || j->ssr.low) {
return 0;
- else
+ } else {
+ j->play_mode = -1;
+ j->flags.playing = 0;
+ j->rec_mode = -1;
+ j->flags.recording = 0;
return 1;
+ }
}
static int set_base_frame(IXJ *j, int size)
unsigned short cmd;
int cnt;
+ idle(j);
+ j->cid_play_aec_level = j->aec_level;
aec_stop(j);
for (cnt = 0; cnt < 10; cnt++) {
if (idle(j))
} else {
j->baseframe.high = j->ssr.high;
j->baseframe.low = j->ssr.low;
+ /* If the status returned is 0x0000 (pg9-9 8021) the call failed */
+ if(j->baseframe.high == 0x00 && j->baseframe.low == 0x00) {
+ return -1;
+ }
}
+ ixj_aec_start(j, j->cid_play_aec_level);
return size;
}
retval = 1;
}
break;
+ case G729B:
+ if (j->dsp.low != 0x20) {
+ if (!j->flags.g729_loaded) {
+ retval = 1;
+ break;
+ }
+ switch (j->baseframe.low) {
+ case 0xA0:
+ j->rec_frame_size = 12;
+ break;
+ case 0x50:
+ j->rec_frame_size = 6;
+ break;
+ default:
+ j->rec_frame_size = 18;
+ break;
+ }
+ j->rec_mode = 0;
+ } else {
+ retval = 1;
+ }
+ break;
case ULAW:
switch (j->baseframe.low) {
case 0xA0:
ixj_record_stop(j);
}
j->flags.recording = 1;
- ixj_WriteDSPCommand(0x0FE0, j); // Put the DSP in full power mode.
+ ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
+
+ if(ixjdebug & 0x0002)
+ printk("IXJ %d Starting Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
if (!j->rec_mode) {
switch (j->rec_codec) {
cmd = 0x5132;
break;
case TS85:
- cmd = 0x5130; // TrueSpeech 8.5
+ cmd = 0x5130; /* TrueSpeech 8.5 */
break;
case TS48:
- cmd = 0x5133; // TrueSpeech 4.8
+ cmd = 0x5133; /* TrueSpeech 4.8 */
break;
case TS41:
- cmd = 0x5134; // TrueSpeech 4.1
+ cmd = 0x5134; /* TrueSpeech 4.1 */
break;
case G728:
cmd = 0x5135;
break;
case G729:
+ case G729B:
cmd = 0x5136;
break;
default:
if (!j->read_buffer)
j->read_buffer = kmalloc(j->rec_frame_size * 2, GFP_ATOMIC);
if (!j->read_buffer) {
- printk("Read buffer allocation for ixj board %d failed!\n",
- j->p.board);
+ printk("Read buffer allocation for ixj board %d failed!\n", j->board);
return -ENOMEM;
}
}
j->read_buffer_size = j->rec_frame_size * 2;
- if (ixj_WriteDSPCommand(0x5102, j)) // Set Poll sync mode
+ if (ixj_WriteDSPCommand(0x5102, j)) /* Set Poll sync mode */
return -1;
switch (j->rec_mode) {
case 0:
- cmd = 0x1C03; // Record C1
+ cmd = 0x1C03; /* Record C1 */
break;
case 4:
if (j->ver.low == 0x12) {
- cmd = 0x1E03; // Record C1
+ cmd = 0x1E03; /* Record C1 */
} else {
- cmd = 0x1E01; // Record C1
+ cmd = 0x1E01; /* Record C1 */
}
break;
case 5:
if (j->ver.low == 0x12) {
- cmd = 0x1E83; // Record C1
+ cmd = 0x1E83; /* Record C1 */
} else {
- cmd = 0x1E81; // Record C1
+ cmd = 0x1E81; /* Record C1 */
}
break;
case 6:
if (j->ver.low == 0x12) {
- cmd = 0x1F03; // Record C1
+ cmd = 0x1F03; /* Record C1 */
} else {
- cmd = 0x1F01; // Record C1
+ cmd = 0x1F01; /* Record C1 */
}
break;
case 7:
if (j->ver.low == 0x12) {
- cmd = 0x1F83; // Record C1
-
+ cmd = 0x1F83; /* Record C1 */
} else {
- cmd = 0x1F81; // Record C1
-
+ cmd = 0x1F81; /* Record C1 */
}
break;
}
if (ixj_WriteDSPCommand(cmd, j))
return -1;
+ if (j->flags.playing) {
+ ixj_aec_start(j, j->aec_level);
+ }
return 0;
}
static void ixj_record_stop(IXJ *j)
{
+ if(ixjdebug & 0x0002)
+ printk("IXJ %d Stopping Record Codec %d at %ld\n", j->board, j->rec_codec, jiffies);
+
if (j->read_buffer) {
kfree(j->read_buffer);
j->read_buffer = NULL;
j->rec_mode = -1;
}
j->flags.recording = 0;
- if (!j->flags.playing)
- ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
-
}
static void ixj_vad(IXJ *j, int arg)
{
ixj_WriteDSPCommand(0x5180 + depth, j);
}
-static void set_rec_volume(IXJ *j, int volume)
+static void set_dtmf_prescale(IXJ *j, int volume)
{
- ixj_WriteDSPCommand(0xCF03, j);
+ ixj_WriteDSPCommand(0xCF07, j);
ixj_WriteDSPCommand(volume, j);
}
-static int get_rec_volume(IXJ *j)
+static int get_dtmf_prescale(IXJ *j)
{
- ixj_WriteDSPCommand(0xCF01, j);
+ ixj_WriteDSPCommand(0xCF05, j);
return j->ssr.high << 8 | j->ssr.low;
}
+static void set_rec_volume(IXJ *j, int volume)
+{
+ if(j->aec_level == AEC_AGC) {
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: /dev/phone%d Setting AGC Threshold to 0x%4.4x\n", j->board, volume);
+ ixj_WriteDSPCommand(0xCF96, j);
+ ixj_WriteDSPCommand(volume, j);
+ } else {
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: /dev/phone %d Setting Record Volume to 0x%4.4x\n", j->board, volume);
+ ixj_WriteDSPCommand(0xCF03, j);
+ ixj_WriteDSPCommand(volume, j);
+ }
+}
+
+static int set_rec_volume_linear(IXJ *j, int volume)
+{
+ int newvolume, dsprecmax;
+
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: /dev/phone %d Setting Linear Record Volume to 0x%4.4x\n", j->board, volume);
+ if(volume > 100 || volume < 0) {
+ return -1;
+ }
+
+ /* This should normalize the perceived volumes between the different cards caused by differences in the hardware */
+ switch (j->cardtype) {
+ case QTI_PHONEJACK:
+ dsprecmax = 0x440;
+ break;
+ case QTI_LINEJACK:
+ dsprecmax = 0x180;
+ ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */
+ ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */
+ ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */
+ break;
+ case QTI_PHONEJACK_LITE:
+ dsprecmax = 0x4C0;
+ break;
+ case QTI_PHONEJACK_PCI:
+ dsprecmax = 0x100;
+ break;
+ case QTI_PHONECARD:
+ dsprecmax = 0x400;
+ break;
+ default:
+ return -1;
+ }
+ newvolume = (dsprecmax * volume) / 100;
+ set_rec_volume(j, newvolume);
+ return 0;
+}
+
+static int get_rec_volume(IXJ *j)
+{
+ if(j->aec_level == AEC_AGC) {
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "Getting AGC Threshold\n");
+ ixj_WriteDSPCommand(0xCF86, j);
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "AGC Threshold is 0x%2.2x%2.2x\n", j->ssr.high, j->ssr.low);
+ return j->ssr.high << 8 | j->ssr.low;
+ } else {
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "Getting Record Volume\n");
+ ixj_WriteDSPCommand(0xCF01, j);
+ return j->ssr.high << 8 | j->ssr.low;
+ }
+}
+
+static int get_rec_volume_linear(IXJ *j)
+{
+ int volume, newvolume, dsprecmax;
+
+ switch (j->cardtype) {
+ case QTI_PHONEJACK:
+ dsprecmax = 0x440;
+ break;
+ case QTI_LINEJACK:
+ dsprecmax = 0x180;
+ break;
+ case QTI_PHONEJACK_LITE:
+ dsprecmax = 0x4C0;
+ break;
+ case QTI_PHONEJACK_PCI:
+ dsprecmax = 0x100;
+ break;
+ case QTI_PHONECARD:
+ dsprecmax = 0x400;
+ break;
+ default:
+ return -1;
+ }
+ volume = get_rec_volume(j);
+ newvolume = (volume * 100) / dsprecmax;
+ if(newvolume > 100)
+ newvolume = 100;
+ return newvolume;
+}
+
static int get_rec_level(IXJ *j)
{
int retval;
static void ixj_aec_start(IXJ *j, int level)
{
j->aec_level = level;
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "AGC set = 0x%2.2x\n", j->aec_level);
if (!level) {
aec_stop(j);
} else {
- if (j->rec_codec == G729 || j->play_codec == G729) {
- ixj_WriteDSPCommand(0xE022, j); // Move AEC filter buffer
+ if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+ ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer */
ixj_WriteDSPCommand(0x0300, j);
}
- ixj_WriteDSPCommand(0xB001, j); // AEC On
+ ixj_WriteDSPCommand(0xB001, j); /* AEC On */
- ixj_WriteDSPCommand(0xE013, j); // Advanced AEC C1
+ ixj_WriteDSPCommand(0xE013, j); /* Advanced AEC C1 */
switch (level) {
case AEC_LOW:
- ixj_WriteDSPCommand(0x0000, j); // Advanced AEC C2 = off
+ ixj_WriteDSPCommand(0x0000, j); /* Advanced AEC C2 = off */
ixj_WriteDSPCommand(0xE011, j);
ixj_WriteDSPCommand(0xFFFF, j);
+
+ ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+ ixj_WriteDSPCommand(0x0000, j); /* to off */
+
break;
case AEC_MED:
- ixj_WriteDSPCommand(0x0600, j); // Advanced AEC C2 = on medium
+ ixj_WriteDSPCommand(0x0600, j); /* Advanced AEC C2 = on medium */
ixj_WriteDSPCommand(0xE011, j);
ixj_WriteDSPCommand(0x0080, j);
+
+ ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+ ixj_WriteDSPCommand(0x0000, j); /* to off */
+
break;
case AEC_HIGH:
- ixj_WriteDSPCommand(0x0C00, j); // Advanced AEC C2 = on high
+ ixj_WriteDSPCommand(0x0C00, j); /* Advanced AEC C2 = on high */
ixj_WriteDSPCommand(0xE011, j);
ixj_WriteDSPCommand(0x0080, j);
+
+ ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+ ixj_WriteDSPCommand(0x0000, j); /* to off */
+
+ break;
+
+ case AEC_AGC:
+ /* First we have to put the AEC into advance auto mode so that AGC will not conflict with it */
+ ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */
+
+ ixj_WriteDSPCommand(0xE011, j);
+ ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */
+
+ ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */
+
+ if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+ ixj_WriteDSPCommand(0x0224, j);
+ else
+ ixj_WriteDSPCommand(0x1224, j);
+
+ ixj_WriteDSPCommand(0xE014, j);
+ ixj_WriteDSPCommand(0x0003, j); /* Lock threashold at 3dB */
+
+ ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */
+
+ /* Now we can set the AGC initial parameters and turn it on */
+ ixj_WriteDSPCommand(0xCF90, j); /* Set AGC Minumum gain */
+ ixj_WriteDSPCommand(0x0020, j); /* to 0.125 (-18dB) */
+
+ ixj_WriteDSPCommand(0xCF91, j); /* Set AGC Maximum gain */
+ ixj_WriteDSPCommand(0x1000, j); /* to 16 (24dB) */
+
+ ixj_WriteDSPCommand(0xCF92, j); /* Set AGC start gain */
+ ixj_WriteDSPCommand(0x0800, j); /* to 8 (+18dB) */
+
+ ixj_WriteDSPCommand(0xCF93, j); /* Set AGC hold time */
+ ixj_WriteDSPCommand(0x1F40, j); /* to 2 seconds (units are 250us) */
+
+ ixj_WriteDSPCommand(0xCF94, j); /* Set AGC Attack Time Constant */
+ ixj_WriteDSPCommand(0x0005, j); /* to 8ms */
+
+ ixj_WriteDSPCommand(0xCF95, j); /* Set AGC Decay Time Constant */
+ ixj_WriteDSPCommand(0x000D, j); /* to 4096ms */
+
+ ixj_WriteDSPCommand(0xCF96, j); /* Set AGC Attack Threshold */
+ ixj_WriteDSPCommand(0x1200, j); /* to 25% */
+
+ ixj_WriteDSPCommand(0xCF97, j); /* Set AGC Enable */
+ ixj_WriteDSPCommand(0x0001, j); /* to on */
+
break;
case AEC_AUTO:
- ixj_WriteDSPCommand(0x0002, j); // Attenuation scaling factor of 2
+ ixj_WriteDSPCommand(0x0002, j); /* Attenuation scaling factor of 2 */
ixj_WriteDSPCommand(0xE011, j);
- ixj_WriteDSPCommand(0x0100, j); // Higher Threshold Floor
+ ixj_WriteDSPCommand(0x0100, j); /* Higher Threshold Floor */
- ixj_WriteDSPCommand(0xE012, j); // Set Train and Lock
+ ixj_WriteDSPCommand(0xE012, j); /* Set Train and Lock */
- ixj_WriteDSPCommand(0x0023, j);
+ if(j->cardtype == QTI_LINEJACK || j->cardtype == QTI_PHONECARD)
+ ixj_WriteDSPCommand(0x0224, j);
+ else
+ ixj_WriteDSPCommand(0x1224, j);
ixj_WriteDSPCommand(0xE014, j);
- ixj_WriteDSPCommand(0x0003, j); // Lock threashold at 3dB
+ ixj_WriteDSPCommand(0x0003, j); /* Lock threashold at 3dB */
+
+ ixj_WriteDSPCommand(0xE338, j); /* Set Echo Suppresser Attenuation to 0dB */
break;
}
static void aec_stop(IXJ *j)
{
- if (j->rec_codec == G729 || j->play_codec == G729) {
- ixj_WriteDSPCommand(0xE022, j); // Move AEC filter buffer back
+ j->aec_level = AEC_OFF;
+ if (j->rec_codec == G729 || j->play_codec == G729 || j->rec_codec == G729B || j->play_codec == G729B) {
+ ixj_WriteDSPCommand(0xE022, j); /* Move AEC filter buffer back */
ixj_WriteDSPCommand(0x0700, j);
}
if (j->play_mode != -1 && j->rec_mode != -1)
{
- ixj_WriteDSPCommand(0xB002, j); // AEC Stop
-
+ ixj_WriteDSPCommand(0xB002, j); /* AEC Stop */
}
}
retval = 1;
}
break;
+ case G729B:
+ if (j->dsp.low != 0x20) {
+ if (!j->flags.g729_loaded) {
+ retval = 1;
+ break;
+ }
+ switch (j->baseframe.low) {
+ case 0xA0:
+ j->play_frame_size = 12;
+ break;
+ case 0x50:
+ j->play_frame_size = 6;
+ break;
+ default:
+ j->play_frame_size = 18;
+ break;
+ }
+ j->play_mode = 0;
+ } else {
+ retval = 1;
+ }
+ break;
case ULAW:
switch (j->baseframe.low) {
case 0xA0:
if (j->write_buffer) {
ixj_play_stop(j);
}
+
+ if(ixjdebug & 0x0002)
+ printk("IXJ %d Starting Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
j->flags.playing = 1;
- ixj_WriteDSPCommand(0x0FE0, j); // Put the DSP in full power mode.
+ ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
j->flags.play_first_frame = 1;
j->drybuffer = 0;
cmd = 0x5232;
break;
case TS85:
- cmd = 0x5230; // TrueSpeech 8.5
+ cmd = 0x5230; /* TrueSpeech 8.5 */
break;
case TS48:
- cmd = 0x5233; // TrueSpeech 4.8
+ cmd = 0x5233; /* TrueSpeech 4.8 */
break;
case TS41:
- cmd = 0x5234; // TrueSpeech 4.1
+ cmd = 0x5234; /* TrueSpeech 4.1 */
break;
case G728:
cmd = 0x5235;
break;
case G729:
+ case G729B:
cmd = 0x5236;
break;
default:
}
j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
if (!j->write_buffer) {
- printk("Write buffer allocation for ixj board %d failed!\n",
- j->p.board);
+ printk("Write buffer allocation for ixj board %d failed!\n", j->board);
return -ENOMEM;
}
- j->write_buffers_empty = 2;
+/* j->write_buffers_empty = 2; */
+ j->write_buffers_empty = 1;
j->write_buffer_size = j->play_frame_size * 2;
j->write_buffer_end = j->write_buffer + j->play_frame_size * 2;
j->write_buffer_rp = j->write_buffer_wp = j->write_buffer;
- if (ixj_WriteDSPCommand(0x5202, j)) // Set Poll sync mode
+ if (ixj_WriteDSPCommand(0x5202, j)) /* Set Poll sync mode */
return -1;
if (ixj_WriteDSPCommand(cmd, j))
return -1;
- if (ixj_WriteDSPCommand(0x2000, j)) // Playback C2
-
+ if (ixj_WriteDSPCommand(0x2000, j)) /* Playback C2 */
return -1;
- if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j)) // Playback C3
-
+ if (ixj_WriteDSPCommand(0x2000 + j->play_frame_size, j)) /* Playback C3 */
return -1;
+ if (j->flags.recording) {
+ ixj_aec_start(j, j->aec_level);
+ }
- ixj_kill_fasync(j, POLL_OUT);
return 0;
}
static void ixj_play_stop(IXJ *j)
{
+ if(ixjdebug & 0x0002)
+ printk("IXJ %d Stopping Play Codec %d at %ld\n", j->board, j->play_codec, jiffies);
+
if (j->write_buffer) {
kfree(j->write_buffer);
j->write_buffer = NULL;
j->write_buffer_size = 0;
}
if (j->play_mode > -1) {
- ixj_WriteDSPCommand(0x5221, j); // Stop playback and flush buffers. 8022 reference page 9-40
+ ixj_WriteDSPCommand(0x5221, j); /* Stop playback and flush buffers. 8022 reference page 9-40 */
j->play_mode = -1;
}
j->flags.playing = 0;
- if (!j->flags.recording)
- ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
-
}
-extern __inline__ int get_play_level(IXJ *j)
+static inline int get_play_level(IXJ *j)
{
int retval;
- ixj_WriteDSPCommand(0xCF8F, j); // 8022 Reference page 9-38
+ ixj_WriteDSPCommand(0xCF8F, j); /* 8022 Reference page 9-38 */
return j->ssr.high << 8 | j->ssr.low;
retval = j->ssr.high << 8 | j->ssr.low;
retval = (retval * 256) / 240;
static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
{
unsigned int mask = 0;
- IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
poll_wait(file_p, &(j->poll_q), wait);
if (j->read_buffer_ready > 0)
static int ixj_play_tone(IXJ *j, char tone)
{
- if (!j->tone_state && j->dsp.low == 0x20)
- idle(j);
-
- j->tone_index = tone;
- if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
- return -1;
-
if (!j->tone_state) {
+ if(ixjdebug & 0x0002) {
+ printk("IXJ %d starting tone %d at %ld\n", j->board, tone, jiffies);
+ }
+ if (j->dsp.low == 0x20) {
+ idle(j);
+ }
j->tone_start_jif = jiffies;
j->tone_state = 1;
}
+
+ j->tone_index = tone;
+ if (ixj_WriteDSPCommand(0x6000 + j->tone_index, j))
+ return -1;
+
return 0;
}
{
j->tone_on_time = arg;
- if (ixj_WriteDSPCommand(0x6E04, j)) // Set Tone On Period
+ if (ixj_WriteDSPCommand(0x6E04, j)) /* Set Tone On Period */
return -1;
if ((j->pld_scrr.bits.sci))
return 1;
}
- if (ixjdebug > 1)
+ if (ixjdebug & 0x0001)
printk(KERN_INFO "SCI Wait High failed %x\n", j->pld_scrr.byte);
return 0;
} else
if (!(j->pld_scrr.bits.sci))
return 1;
}
- if (ixjdebug > 1)
+ if (ixjdebug & 0x0001)
printk(KERN_INFO "SCI Wait Low failed %x\n", j->pld_scrr.byte);
return 0;
} else
{
switch (control) {
case SCI_End:
- j->pld_scrw.bits.c0 = 0; // Set PLD Serial control interface
+ j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */
- j->pld_scrw.bits.c1 = 0; // to no selection
+ j->pld_scrw.bits.c1 = 0; /* to no selection */
break;
case SCI_Enable_DAA:
- j->pld_scrw.bits.c0 = 1; // Set PLD Serial control interface
+ j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */
- j->pld_scrw.bits.c1 = 0; // to write to DAA
+ j->pld_scrw.bits.c1 = 0; /* to write to DAA */
break;
case SCI_Enable_Mixer:
- j->pld_scrw.bits.c0 = 0; // Set PLD Serial control interface
+ j->pld_scrw.bits.c0 = 0; /* Set PLD Serial control interface */
- j->pld_scrw.bits.c1 = 1; // to write to mixer
+ j->pld_scrw.bits.c1 = 1; /* to write to mixer */
break;
case SCI_Enable_EEPROM:
- j->pld_scrw.bits.c0 = 1; // Set PLD Serial control interface
+ j->pld_scrw.bits.c0 = 1; /* Set PLD Serial control interface */
- j->pld_scrw.bits.c1 = 1; // to write to EEPROM
+ j->pld_scrw.bits.c1 = 1; /* to write to EEPROM */
break;
default:
return 1;
}
+static int ixj_get_mixer(long val, IXJ *j)
+{
+ int reg = (val & 0x1F00) >> 8;
+ return j->mix.vol[reg];
+}
+
static int ixj_mixer(long val, IXJ *j)
{
BYTES bytes;
- bytes.high = (val & 0xFF00) >> 8;
+ bytes.high = (val & 0x1F00) >> 8;
bytes.low = val & 0x00FF;
- outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); // Load Mixer Address
+ /* save mixer value so we can get back later on */
+ j->mix.vol[bytes.high] = bytes.low;
+
+ outb_p(bytes.high & 0x1F, j->XILINXbase + 0x03); /* Load Mixer Address */
- outb_p(bytes.low, j->XILINXbase + 0x02); // Load Mixer Data
+ outb_p(bytes.low, j->XILINXbase + 0x02); /* Load Mixer Data */
SCI_Control(j, SCI_Enable_Mixer);
if (!daa_load(&bytes, j))
return 0;
-
- if (!SCI_Prepare(j))
+
+ if (!SCI_Prepare(j))
+ return 0;
+
+ return 1;
+}
+
+static char daa_int_read(IXJ *j)
+{
+ BYTES bytes;
+
+ if (!SCI_Prepare(j))
+ return 0;
+
+ bytes.high = 0x38;
+ bytes.low = 0x00;
+ outb_p(bytes.high, j->XILINXbase + 0x03);
+ outb_p(bytes.low, j->XILINXbase + 0x02);
+
+ if (!SCI_Control(j, SCI_Enable_DAA))
+ return 0;
+
+ bytes.high = inb_p(j->XILINXbase + 0x03);
+ bytes.low = inb_p(j->XILINXbase + 0x02);
+ if (bytes.low != ALISDAA_ID_BYTE) {
+ if (ixjdebug & 0x0001)
+ printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
+ return 0;
+ }
+ if (!SCI_Control(j, SCI_Enable_DAA))
+ return 0;
+ if (!SCI_Control(j, SCI_End))
return 0;
+ bytes.high = inb_p(j->XILINXbase + 0x03);
+ bytes.low = inb_p(j->XILINXbase + 0x02);
+
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
+
return 1;
}
-static char daa_int_read(IXJ *j)
+static char daa_CR_read(IXJ *j, int cr)
{
+ IXJ_WORD wdata;
BYTES bytes;
if (!SCI_Prepare(j))
return 0;
- bytes.high = 0x38;
+ switch (j->daa_mode) {
+ case SOP_PU_SLEEP:
+ bytes.high = 0x30 + cr;
+ break;
+ case SOP_PU_RINGING:
+ bytes.high = 0x70 + cr;
+ break;
+ case SOP_PU_CONVERSATION:
+ bytes.high = 0xB0 + cr;
+ break;
+ case SOP_PU_PULSEDIALING:
+ bytes.high = 0xF0 + cr;
+ break;
+ }
+
bytes.low = 0x00;
+
outb_p(bytes.high, j->XILINXbase + 0x03);
outb_p(bytes.low, j->XILINXbase + 0x02);
bytes.high = inb_p(j->XILINXbase + 0x03);
bytes.low = inb_p(j->XILINXbase + 0x02);
if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0001)
printk("Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
return 0;
}
if (!SCI_Control(j, SCI_End))
return 0;
- bytes.high = inb_p(j->XILINXbase + 0x03);
- bytes.low = inb_p(j->XILINXbase + 0x02);
+ wdata.word = inw_p(j->XILINXbase + 0x02);
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg = bytes.high;
+ switch(cr){
+ case 5:
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = wdata.bytes.high;
+ break;
+ case 4:
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = wdata.bytes.high;
+ break;
+ case 3:
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = wdata.bytes.high;
+ break;
+ case 2:
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = wdata.bytes.high;
+ break;
+ case 1:
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = wdata.bytes.high;
+ break;
+ case 0:
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = wdata.bytes.high;
+ break;
+ default:
+ return 0;
+ }
return 1;
}
int i;
BYTES bytes;
+ if (ixjdebug & 0x0002)
+ printk("DAA Clearing CID ram\n");
+
if (!SCI_Prepare(j))
return 0;
if (!SCI_Control(j, SCI_End))
return 0;
+ if (ixjdebug & 0x0002)
+ printk("DAA CID ram cleared\n");
+
return 1;
}
bytes.high = inb_p(j->XILINXbase + 0x03);
bytes.low = inb_p(j->XILINXbase + 0x02);
if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0001)
printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
return 0;
}
bytes.high = inb_p(j->XILINXbase + 0x03);
bytes.low = inb_p(j->XILINXbase + 0x02);
if (bytes.low != ALISDAA_ID_BYTE) {
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0001)
printk("DAA Get Version Cannot read DAA ID Byte high = %d low = %d\n", bytes.high, bytes.low);
return 0;
}
bytes.high = inb_p(j->XILINXbase + 0x03);
bytes.low = inb_p(j->XILINXbase + 0x02);
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk("DAA CR5 Byte high = 0x%x low = 0x%x\n", bytes.high, bytes.low);
j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg = bytes.high;
return bytes.high;
static int daa_set_mode(IXJ *j, int mode)
{
- // NOTE:
- // The DAA *MUST* be in the conversation mode if the
- // PSTN line is to be seized (PSTN line off-hook).
- // Taking the PSTN line off-hook while the DAA is in
- // a mode other than conversation mode will cause a
- // hardware failure of the ALIS-A part.
+ /* NOTE:
+ The DAA *MUST* be in the conversation mode if the
+ PSTN line is to be seized (PSTN line off-hook).
+ Taking the PSTN line off-hook while the DAA is in
+ a mode other than conversation mode will cause a
+ hardware failure of the ALIS-A part.
- // NOTE:
- // The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
- // if the PSTN line is on-hook. Failure to have the PSTN line
- // in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
- // ALIS-A part.
- //
+ NOTE:
+ The DAA can only go to SLEEP, RINGING or PULSEDIALING modes
+ if the PSTN line is on-hook. Failure to have the PSTN line
+ in the on-hook state WILL CAUSE A HARDWARE FAILURE OF THE
+ ALIS-A part.
+ */
BYTES bytes;
+ j->flags.pstn_rmr = 0;
+
if (!SCI_Prepare(j))
return 0;
switch (mode) {
+ case SOP_PU_RESET:
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
+
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+ j->pld_slicw.bits.rly2 = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ bytes.high = 0x10;
+ bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+ daa_load(&bytes, j);
+ if (!SCI_Prepare(j))
+ return 0;
+
+ j->daa_mode = SOP_PU_SLEEP;
+ break;
case SOP_PU_SLEEP:
- if(j->daa_mode == SOP_PU_CONVERSATION)
+ if(j->daa_mode == SOP_PU_SLEEP)
+ {
+ break;
+ }
+ if (ixjdebug & 0x0008)
+ printk(KERN_INFO "phone DAA: SOP_PU_SLEEP at %ld\n", jiffies);
+/* if(j->daa_mode == SOP_PU_CONVERSATION) */
{
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
j->pld_slicw.bits.rly2 = 0;
if (!SCI_Prepare(j))
return 0;
}
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
j->pld_slicw.bits.rly2 = 0;
j->daa_mode = SOP_PU_SLEEP;
j->flags.pstn_ringing = 0;
j->ex.bits.pstn_ring = 0;
- j->pstn_sleeptil = jiffies + (hertz / 2);
- wake_up_interruptible(&j->read_q); // Wake any blocked readers
- wake_up_interruptible(&j->write_q); // Wake any blocked writers
- wake_up_interruptible(&j->poll_q); // Wake any blocked selects
+ j->pstn_sleeptil = jiffies + (hertz / 4);
+ wake_up_interruptible(&j->read_q); /* Wake any blocked readers */
+ wake_up_interruptible(&j->write_q); /* Wake any blocked writers */
+ wake_up_interruptible(&j->poll_q); /* Wake any blocked selects */
break;
case SOP_PU_RINGING:
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ if (ixjdebug & 0x0008)
+ printk(KERN_INFO "phone DAA: SOP_PU_RINGING at %ld\n", jiffies);
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
j->pld_slicw.bits.rly2 = 0;
j->daa_mode = SOP_PU_RINGING;
break;
case SOP_PU_CONVERSATION:
+ if (ixjdebug & 0x0008)
+ printk(KERN_INFO "phone DAA: SOP_PU_CONVERSATION at %ld\n", jiffies);
bytes.high = 0x90;
bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
daa_load(&bytes, j);
return 0;
j->pld_slicw.bits.rly2 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->pld_scrw.bits.led1 = 0;
- j->pld_scrw.bits.led2 = 1;
- j->pld_scrw.bits.daafsyncen = 1; // Turn on DAA Frame Sync
+ j->pld_scrw.bits.daafsyncen = 1; /* Turn on DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
j->daa_mode = SOP_PU_CONVERSATION;
j->flags.pstn_ringing = 0;
j->ex.bits.pstn_ring = 0;
+ j->pstn_sleeptil = jiffies;
+ j->pstn_ring_start = j->pstn_ring_stop = j->pstn_ring_int = 0;
break;
case SOP_PU_PULSEDIALING:
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ if (ixjdebug & 0x0008)
+ printk(KERN_INFO "phone DAA: SOP_PU_PULSEDIALING at %ld\n", jiffies);
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
j->pld_slicw.bits.rly2 = 0;
{
BYTES bytes;
+ j->flags.pstncheck = 1;
+
+ daa_set_mode(j, SOP_PU_SLEEP);
+
if (!SCI_Prepare(j))
return 0;
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+
bytes.high = 0x14;
bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg;
if (!daa_load(&bytes, j))
if (!SCI_Control(j, SCI_End))
return 0;
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+
+ if (ixjdebug & 0x0002)
+ printk("DAA Coefficients Loaded\n");
+
+ j->flags.pstncheck = 0;
return 1;
}
int ixj_set_tone_off(unsigned short arg, IXJ *j)
{
j->tone_off_time = arg;
- if (ixj_WriteDSPCommand(0x6E05, j)) // Set Tone Off Period
+ if (ixj_WriteDSPCommand(0x6E05, j)) /* Set Tone Off Period */
return -1;
if (ixj_WriteDSPCommand(arg, j))
static int ixj_get_tone_on(IXJ *j)
{
- if (ixj_WriteDSPCommand(0x6E06, j)) // Get Tone On Period
+ if (ixj_WriteDSPCommand(0x6E06, j)) /* Get Tone On Period */
return -1;
return 0;
static int ixj_get_tone_off(IXJ *j)
{
- if (ixj_WriteDSPCommand(0x6E07, j)) // Get Tone Off Period
+ if (ixj_WriteDSPCommand(0x6E07, j)) /* Get Tone Off Period */
+
return -1;
return 0;
}
static void ixj_cpt_stop(IXJ *j)
{
- if(j->tone_state)
+ if(j->tone_state || j->tone_cadence_state)
{
j->flags.dialtone = 0;
j->flags.busytone = 0;
ixj_set_tone_on(0x0001, j);
ixj_set_tone_off(0x0000, j);
ixj_play_tone(j, 0);
- j->tone_state = 0;
+ j->tone_state = j->tone_cadence_state = 0;
if (j->cadence_t) {
if (j->cadence_t->ce) {
kfree(j->cadence_t->ce);
lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
if (lcp == NULL)
return -ENOMEM;
- if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) ||
- (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) )
- {
- kfree(lcp);
- return -EFAULT;
- }
+ if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE) )
+ {
+ kfree(lcp);
+ return -EFAULT;
+ }
lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
if (lcep == NULL) {
kfree(lcp);
static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
{
IXJ_FILTER_CADENCE *lcp;
-
lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL);
- if (lcp == NULL)
+ if (lcp == NULL) {
+ if(ixjdebug & 0x0001) {
+ printk(KERN_INFO "Could not allocate memory for cadence\n");
+ }
return -ENOMEM;
- if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
- {
- kfree(lcp);
+ }
+ if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) {
+ if(ixjdebug & 0x0001) {
+ printk(KERN_INFO "Could not copy cadence to kernel\n");
+ }
return -EFAULT;
}
- if (lcp->filter >= 4)
- {
- kfree(lcp);
+ if (lcp->filter > 5) {
+ if(ixjdebug & 0x0001) {
+ printk(KERN_INFO "Cadence out of range\n");
+ }
return -1;
}
j->cadence_f[lcp->filter].state = 0;
j->cadence_f[lcp->filter].off3min = 0;
j->cadence_f[lcp->filter].off3max = 0;
kfree(lcp);
+ if(ixjdebug & 0x0002) {
+ printk(KERN_INFO "Cadence %d loaded\n", lcp->filter);
+ }
return 0;
}
j->caplist[j->caps].cap = pots;
j->caplist[j->caps].handle = j->caps++;
- // add devices that can do speaker/mic
+ /* add devices that can do speaker/mic */
switch (j->cardtype) {
case QTI_PHONEJACK:
case QTI_LINEJACK:
break;
}
- // add devices that can do handset
+ /* add devices that can do handset */
switch (j->cardtype) {
case QTI_PHONEJACK:
strcpy(j->caplist[j->caps].desc, "HANDSET");
break;
}
- // add devices that can do PSTN
+ /* add devices that can do PSTN */
switch (j->cardtype) {
case QTI_LINEJACK:
strcpy(j->caplist[j->caps].desc, "PSTN");
break;
}
- // add codecs - all cards can do uLaw, linear 8/16, and Windows sound system
+ /* add codecs - all cards can do uLaw, linear 8/16, and Windows sound system */
strcpy(j->caplist[j->caps].desc, "ULAW");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = ULAW;
j->caplist[j->caps].cap = WSS;
j->caplist[j->caps].handle = j->caps++;
- // version 12 of the 8020 does the following codecs in a broken way
+ /* software ALAW codec, made from ULAW */
+ strcpy(j->caplist[j->caps].desc, "ALAW");
+ j->caplist[j->caps].captype = codec;
+ j->caplist[j->caps].cap = ALAW;
+ j->caplist[j->caps].handle = j->caps++;
+
+ /* version 12 of the 8020 does the following codecs in a broken way */
if (j->dsp.low != 0x20 || j->ver.low != 0x12) {
- strcpy(j->caplist[j->caps].desc, "G.723.1 6.3Kbps");
+ strcpy(j->caplist[j->caps].desc, "G.723.1 6.3kbps");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = G723_63;
j->caplist[j->caps].handle = j->caps++;
- strcpy(j->caplist[j->caps].desc, "G.723.1 5.3Kbps");
+ strcpy(j->caplist[j->caps].desc, "G.723.1 5.3kbps");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = G723_53;
j->caplist[j->caps].handle = j->caps++;
- strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8Kbps");
+ strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.8kbps");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = TS48;
j->caplist[j->caps].handle = j->caps++;
- strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1Kbps");
+ strcpy(j->caplist[j->caps].desc, "TrueSpeech 4.1kbps");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = TS41;
j->caplist[j->caps].handle = j->caps++;
}
- // 8020 chips can do TS8.5 native, and 8021/8022 can load it
+ /* 8020 chips can do TS8.5 native, and 8021/8022 can load it */
if (j->dsp.low == 0x20 || j->flags.ts85_loaded) {
- strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5Kbps");
+ strcpy(j->caplist[j->caps].desc, "TrueSpeech 8.5kbps");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = TS85;
j->caplist[j->caps].handle = j->caps++;
}
- // 8021 chips can do G728
+ /* 8021 chips can do G728 */
if (j->dsp.low == 0x21) {
- strcpy(j->caplist[j->caps].desc, "G.728 16Kbps");
+ strcpy(j->caplist[j->caps].desc, "G.728 16kbps");
j->caplist[j->caps].captype = codec;
j->caplist[j->caps].cap = G728;
j->caplist[j->caps].handle = j->caps++;
}
- // 8021/8022 chips can do G729 if loaded
+ /* 8021/8022 chips can do G729 if loaded */
if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
- strcpy(j->caplist[j->caps].desc, "G.729A/B");
+ strcpy(j->caplist[j->caps].desc, "G.729A 8kbps");
j->caplist[j->caps].captype = codec;
- j->caplist[j->caps].cap = G728;
+ j->caplist[j->caps].cap = G729;
+ j->caplist[j->caps].handle = j->caps++;
+ }
+ if (j->dsp.low != 0x20 && j->flags.g729_loaded) {
+ strcpy(j->caplist[j->caps].desc, "G.729B 8kbps");
+ j->caplist[j->caps].captype = codec;
+ j->caplist[j->caps].cap = G729B;
j->caplist[j->caps].handle = j->caps++;
}
}
-static int capabilities_check(IXJ *j, struct phone_capability *u_pcreq)
+static int capabilities_check(IXJ *j, struct phone_capability *pcreq)
{
int cnt;
int retval = 0;
- struct phone_capability pcreq;
-
- if(copy_from_user(&pcreq, u_pcreq, sizeof(struct phone_capability)))
- return -EFAULT;
-
for (cnt = 0; cnt < j->caps; cnt++) {
- if (pcreq.captype == j->caplist[cnt].captype
- && pcreq.cap == j->caplist[cnt].cap) {
+ if (pcreq->captype == j->caplist[cnt].captype
+ && pcreq->cap == j->caplist[cnt].cap) {
retval = 1;
break;
}
return retval;
}
-int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
+static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
{
IXJ_TONE ti;
IXJ_FILTER jf;
+ IXJ_FILTER_RAW jfr;
+
+ unsigned int raise, mant;
unsigned int minor = MINOR(inode->i_rdev);
- unsigned int board = NUM(inode->i_rdev);
- IXJ *j = ixj[board];
- int retval = 0;
+ int board = NUM(inode->i_rdev);
- if (ixjdebug > 1)
- printk(KERN_DEBUG "phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
- if (minor >= IXJMAX)
- return -ENODEV;
+ IXJ *j = get_ixj(NUM(inode->i_rdev));
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ int retval = 0;
+ /*
+ * Set up locks to ensure that only one process is talking to the DSP at a time.
+ * This is necessary to keep the DSP from locking up.
+ */
+ while(test_and_set_bit(board, (void *)&j->busyflags) != 0) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ if (ixjdebug & 0x0040)
+ printk("phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+ if (minor >= IXJMAX) {
+ clear_bit(board, &j->busyflags);
+ return -ENODEV;
+ }
/*
* Check ioctls only root can use.
*/
switch (cmd) {
case IXJCTL_TESTRAM:
case IXJCTL_HZ:
- return -EPERM;
+ retval = -EPERM;
}
}
switch (cmd) {
retval = j->serial;
break;
case IXJCTL_VERSION:
- if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
- return -EFAULT;
+ if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
+ retval = -EFAULT;
break;
case PHONE_RING_CADENCE:
- if(get_user(j->ring_cadence, (int *)arg))
- return -EFAULT;
+ j->ring_cadence = arg;
break;
case IXJCTL_CIDCW:
if(arg) {
}
ixj_write_cidcw(j);
break;
- /* Binary compatbility */
- case OLD_PHONE_RING_START:
- arg = 0;
- /* Fall through */
- case PHONE_RING_START:
+ /* Binary compatbility */
+ case OLD_PHONE_RING_START:
+ arg = 0;
+ /* Fall through */
+ case PHONE_RING_START:
if(arg) {
- copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+ if(copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID)))
+ {
+ retval = -EFAULT;
+ break;
+ }
+ ixj_write_cid(j);
}
else {
memset(&j->cid_send, 0, sizeof(PHONE_CID));
break;
case PHONE_RING_STOP:
j->flags.cringing = 0;
+ if(j->cadence_f[5].enable) {
+ j->cadence_f[5].state = 0;
+ }
ixj_ring_off(j);
break;
case PHONE_RING:
break;
case PHONE_EXCEPTION:
retval = j->ex.bytes;
- j->ex.bits.flash = 0;
+ if(j->ex.bits.flash) {
+ j->flash_end = 0;
+ j->ex.bits.flash = 0;
+ }
j->ex.bits.pstn_ring = 0;
j->ex.bits.caller_id = 0;
j->ex.bits.pstn_wink = 0;
break;
case PHONE_HOOKSTATE:
j->ex.bits.hookstate = 0;
- retval = j->r_hook;
+ retval = j->hookstate; //j->r_hook;
break;
case IXJCTL_SET_LED:
LED_SetState(arg, j);
retval = arg;
}
break;
+ case PHONE_REC_VOLUME_LINEAR:
+ if(arg == -1) {
+ retval = get_rec_volume_linear(j);
+ }
+ else {
+ set_rec_volume_linear(j, arg);
+ retval = arg;
+ }
+ break;
+ case IXJCTL_DTMF_PRESCALE:
+ if(arg == -1) {
+ retval = get_dtmf_prescale(j);
+ }
+ else {
+ set_dtmf_prescale(j, arg);
+ retval = arg;
+ }
+ break;
case PHONE_REC_LEVEL:
retval = get_rec_level(j);
break;
+ case IXJCTL_SC_RXG:
+ retval = ixj_siadc(j, arg);
+ break;
+ case IXJCTL_SC_TXG:
+ retval = ixj_sidac(j, arg);
+ break;
case IXJCTL_AEC_START:
ixj_aec_start(j, arg);
break;
retval = arg;
}
break;
+ case PHONE_PLAY_VOLUME_LINEAR:
+ if(arg == -1) {
+ retval = get_play_volume_linear(j);
+ }
+ else {
+ set_play_volume_linear(j, arg);
+ retval = arg;
+ }
+ break;
case PHONE_PLAY_LEVEL:
retval = get_play_level(j);
break;
if (j->dtmf_rp != j->dtmf_wp) {
switch (j->dtmfbuffer[j->dtmf_rp]) {
case 10:
- retval = 42; //'*';
+ retval = 42; /* '*'; */
break;
case 11:
- retval = 48; //'0';
+ retval = 48; /*'0'; */
break;
case 12:
- retval = 35; //'#';
+ retval = 35; /*'#'; */
break;
case 28:
- retval = 65; //'A';
+ retval = 65; /*'A'; */
break;
case 29:
- retval = 66; //'B';
+ retval = 66; /*'B'; */
break;
case 30:
- retval = 67; //'C';
+ retval = 67; /*'C'; */
break;
case 31:
- retval = 68; //'D';
+ retval = 68; /*'D'; */
break;
default:
j->dtmf_rp++;
if (j->dtmf_rp == 79)
j->dtmf_rp = 0;
-// if(j->dtmf_rp == j->dtmf_wp)
+ if(j->dtmf_rp == j->dtmf_wp)
{
j->ex.bits.dtmf_ready = j->dtmf_rp = j->dtmf_wp = 0;
}
case PHONE_RINGBACK:
ixj_ringback(j);
break;
+ case PHONE_WINK:
+ if(j->cardtype == QTI_PHONEJACK)
+ retval = -1;
+ else
+ retval = ixj_wink(j);
+ break;
case PHONE_CPT_STOP:
ixj_cpt_stop(j);
break;
- case PHONE_QUERY_CODEC:
- {
- struct phone_codec_data pd;
- int val;
- int proto_size[] = {
- -1,
- 12, 10, 16, 9, 8, 48, 5,
- 40, 40, 80, 40, 40
- };
- if(copy_from_user(&pd, (void *)arg, sizeof(pd)))
- return -EFAULT;
- if(pd.type<1 || pd.type>12)
- return -EPROTONOSUPPORT;
- if(pd.type<G729)
- val=proto_size[pd.type];
- else switch(j->baseframe.low)
- {
- case 0xA0:val=2*proto_size[pd.type];break;
- case 0x50:val=proto_size[pd.type];break;
- default:val=proto_size[pd.type]*3;break;
+ case PHONE_QUERY_CODEC:
+ {
+ struct phone_codec_data pd;
+ int val;
+ int proto_size[] = {
+ -1,
+ 12, 10, 16, 9, 8, 48, 5,
+ 40, 40, 80, 40, 40, 6
+ };
+ if(copy_from_user(&pd, (void *)arg, sizeof(pd))) {
+ retval = -EFAULT;
+ break;
}
- pd.buf_min=pd.buf_max=pd.buf_opt=val;
- if(copy_to_user((void *)arg, &pd, sizeof(pd)))
- return -EFAULT;
- return 0;
- }
+ if(pd.type<1 || pd.type>13) {
+ retval = -EPROTONOSUPPORT;
+ break;
+ }
+ if(pd.type<G729)
+ val=proto_size[pd.type];
+ else switch(j->baseframe.low)
+ {
+ case 0xA0:val=2*proto_size[pd.type];break;
+ case 0x50:val=proto_size[pd.type];break;
+ default:val=proto_size[pd.type]*3;break;
+ }
+ pd.buf_min=pd.buf_max=pd.buf_opt=val;
+ if(copy_to_user((void *)arg, &pd, sizeof(pd)))
+ retval = -EFAULT;
+ break;
+ }
case IXJCTL_DSP_IDLE:
idle(j);
break;
case IXJCTL_MIXER:
- ixj_mixer(arg, j);
+ if ((arg & 0xff) == 0xff)
+ retval = ixj_get_mixer(arg, j);
+ else
+ ixj_mixer(arg, j);
break;
case IXJCTL_DAA_COEFF_SET:
switch (arg) {
retval = 1;
break;
}
- j->country = arg;
break;
case IXJCTL_DAA_AGAIN:
ixj_daa_cr4(j, arg | 0x02);
ixj_write_vmwi(j, arg);
break;
case IXJCTL_CID:
- if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
- return -EFAULT;
+ if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
+ retval = -EFAULT;
j->ex.bits.caller_id = 0;
break;
case IXJCTL_WINK_DURATION:
retval = ixj_set_pots(j, arg);
break;
case PHONE_CAPABILITIES:
+ add_caps(j);
retval = j->caps;
break;
case PHONE_CAPABILITIES_LIST:
- if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
- return -EFAULT;
+ add_caps(j);
+ if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
+ retval = -EFAULT;
break;
case PHONE_CAPABILITIES_CHECK:
- retval = capabilities_check(j, (struct phone_capability *) arg);
+ {
+ struct phone_capability cap;
+ if (copy_from_user(&cap, (char *) arg, sizeof(cap)))
+ retval = -EFAULT;
+ else {
+ add_caps(j);
+ retval = capabilities_check(j, &cap);
+ }
+ }
break;
case PHONE_PSTN_SET_STATE:
daa_set_mode(j, arg);
j->ex.bits.pstn_ring = 0;
break;
case IXJCTL_SET_FILTER:
- if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
- return -EFAULT;
+ if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
+ retval = -EFAULT;
retval = ixj_init_filter(j, &jf);
break;
+ case IXJCTL_SET_FILTER_RAW:
+ if (copy_from_user(&jfr, (char *) arg, sizeof(jfr)))
+ retval = -EFAULT;
+ retval = ixj_init_filter_raw(j, &jfr);
+ break;
case IXJCTL_GET_FILTER_HIST:
retval = j->filter_hist[arg];
break;
case IXJCTL_FILTER_CADENCE:
retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
break;
+ case IXJCTL_SIGCTL:
+ if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF)))
+ retval = -EFAULT;
+ j->ixj_signals[j->sigdef.event] = j->sigdef.signal;
+ if(j->sigdef.event < 33) {
+ raise = 1;
+ for(mant = 0; mant < j->sigdef.event; mant++){
+ raise *= 2;
+ }
+ if(j->sigdef.signal)
+ j->ex_sig.bytes |= raise;
+ else
+ j->ex_sig.bytes &= (raise^0xffff);
+ }
+ break;
case IXJCTL_INTERCOM_STOP:
- if (arg != j->intercom
- || ixj[arg]->intercom != board)
+ if(arg < 0 || arg >= IXJMAX)
return -EINVAL;
-
j->intercom = -1;
- ixj[arg]->intercom = -1;
ixj_record_stop(j);
- ixj_record_stop(ixj[arg]);
ixj_play_stop(j);
- ixj_play_stop(ixj[arg]);
idle(j);
- idle(ixj[arg]);
+ get_ixj(arg)->intercom = -1;
+ ixj_record_stop(get_ixj(arg));
+ ixj_play_stop(get_ixj(arg));
+ idle(get_ixj(arg));
break;
case IXJCTL_INTERCOM_START:
- if (ixj[arg] == NULL)
- return -ENODEV;
-
+ if(arg < 0 || arg >= IXJMAX)
+ return -EINVAL;
j->intercom = arg;
- ixj[arg]->intercom = board;
- ixj_play_start(ixj[arg]);
ixj_record_start(j);
ixj_play_start(j);
- ixj_record_start(ixj[arg]);
- idle(j);
- idle(ixj[arg]);
+ get_ixj(arg)->intercom = board;
+ ixj_play_start(get_ixj(arg));
+ ixj_record_start(get_ixj(arg));
break;
}
+ if (ixjdebug & 0x0040)
+ printk("phone%d ioctl end, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
+ clear_bit(board, &j->busyflags);
return retval;
}
static int ixj_fasync(int fd, struct file *file_p, int mode)
{
- IXJ *j = ixj[NUM(file_p->f_dentry->d_inode->i_rdev)];
-
- if (j == NULL) /* shouldn't happen! */
- return -ENODEV;
+ IXJ *j = get_ixj(NUM(file_p->f_dentry->d_inode->i_rdev));
return fasync_helper(fd, file_p, mode, &j->async_queue);
}
struct file_operations ixj_fops =
{
- owner: THIS_MODULE,
- read: ixj_enhanced_read,
- write: ixj_enhanced_write,
- poll: ixj_poll,
- ioctl: ixj_ioctl,
- release: ixj_release,
- fasync: ixj_fasync
+ owner: THIS_MODULE,
+ read: ixj_enhanced_read,
+ write: ixj_enhanced_write,
+ poll: ixj_poll,
+ ioctl: ixj_ioctl,
+ release: ixj_release,
+ fasync: ixj_fasync
};
static int ixj_linetest(IXJ *j)
{
unsigned long jifwait;
- j->flags.incheck = 1; // Testing
- if (!j->flags.pots_correct) {
- j->flags.pots_correct = 1;
+ j->flags.pstncheck = 1; /* Testing */
+ j->flags.pstn_present = 0; /* Assume the line is not there */
- daa_int_read(j); //Clear DAA Interrupt flags
- //
- // Hold all relays in the normally de-energized position.
- //
+ daa_int_read(j); /*Clear DAA Interrupt flags */
+ /* */
+ /* Hold all relays in the normally de-energized position. */
+ /* */
+
+ j->pld_slicw.bits.rly1 = 0;
+ j->pld_slicw.bits.rly2 = 0;
+ j->pld_slicw.bits.rly3 = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+ j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
+ if (j->pld_slicr.bits.potspstn) {
+ j->flags.pots_pstn = 1;
+ j->flags.pots_correct = 0;
+ LED_SetState(0x4, j);
+ } else {
+ j->flags.pots_pstn = 0;
j->pld_slicw.bits.rly1 = 0;
j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 0;
+ j->pld_slicw.bits.rly3 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
- if (j->pld_slicr.bits.potspstn) {
- j->flags.pots_pstn = 1;
- j->flags.pots_correct = 0;
+ daa_set_mode(j, SOP_PU_CONVERSATION);
+ jifwait = jiffies + hertz;
+ while (time_before(jiffies, jifwait)) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(1);
+ }
+ daa_int_read(j);
+ daa_set_mode(j, SOP_PU_RESET);
+ if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+ j->flags.pots_correct = 0; /* Should not be line voltage on POTS port. */
LED_SetState(0x4, j);
+ j->pld_slicw.bits.rly3 = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
} else {
- j->flags.pots_pstn = 0;
- j->pld_slicw.bits.rly1 = 0;
+ j->flags.pots_correct = 1;
+ LED_SetState(0x8, j);
+ j->pld_slicw.bits.rly1 = 1;
j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 1;
+ j->pld_slicw.bits.rly3 = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
-
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- daa_set_mode(j, SOP_PU_CONVERSATION);
- jifwait = jiffies + hertz;
- while (time_before(jiffies, jifwait)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
- daa_int_read(j);
- daa_set_mode(j, SOP_PU_SLEEP);
- if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
- j->flags.pots_correct = 0; // Should not be line voltage on POTS port.
-
- LED_SetState(0x4, j);
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- } else {
- j->flags.pots_correct = 1;
- LED_SetState(0x8, j);
- j->pld_slicw.bits.rly1 = 1;
- j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- }
}
}
-// if (!j->flags.pstn_present) {
j->pld_slicw.bits.rly3 = 0;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
daa_set_mode(j, SOP_PU_CONVERSATION);
schedule_timeout(1);
}
daa_int_read(j);
- daa_set_mode(j, SOP_PU_SLEEP);
+ daa_set_mode(j, SOP_PU_RESET);
if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+ j->pstn_sleeptil = jiffies + (hertz / 4);
j->flags.pstn_present = 1;
} else {
j->flags.pstn_present = 0;
}
-// }
if (j->flags.pstn_present) {
if (j->flags.pots_correct) {
LED_SetState(0xA, j);
LED_SetState(0x5, j);
}
}
- j->flags.incheck = 0; // Testing
+ j->flags.pstncheck = 0; /* Testing */
return j->flags.pstn_present;
}
-static int ixj_selfprobe(IXJ *j, int cnt)
+static int ixj_selfprobe(IXJ *j)
{
unsigned short cmd;
unsigned long jif;
- int i;
+ int cnt;
BYTES bytes;
-
- init_waitqueue_head(&j->poll_q);
- init_waitqueue_head(&j->read_q);
- init_waitqueue_head(&j->write_q);
- if (ixjdebug > 0)
+
+ init_waitqueue_head(&j->poll_q);
+ init_waitqueue_head(&j->read_q);
+ init_waitqueue_head(&j->write_q);
+
+ while(atomic_read(&j->DSPWrite) > 0)
+ atomic_dec(&j->DSPWrite);
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Write IDLE to Software Control Register\n");
- ixj_WriteDSPCommand(0x0FE0, j); // Put the DSP in full power mode.
+ ixj_WriteDSPCommand(0x0FE0, j); /* Put the DSP in full power mode. */
if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */
return -1;
-// The read values of the SSR should be 0x00 for the IDLE command
+/* The read values of the SSR should be 0x00 for the IDLE command */
if (j->ssr.low || j->ssr.high)
return -1;
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Get Device ID Code\n");
if (ixj_WriteDSPCommand(0x3400, j)) /* Get Device ID Code */
return -1;
j->dsp.low = j->ssr.low;
j->dsp.high = j->ssr.high;
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Get Device Version Code\n");
if (ixj_WriteDSPCommand(0x3800, j)) /* Get Device Version Code */
return -1;
j->ver.high = j->ssr.high;
if (!j->cardtype) {
if (j->dsp.low == 0x21) {
-// j->XILINXbase = j->DSPbase + 0x10;
bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
-// Test for Internet LineJACK or Internet PhoneJACK Lite
+/* Test for Internet LineJACK or Internet PhoneJACK Lite */
bytes.low = inb_p(j->XILINXbase + 0x02);
- if (bytes.low == bytes.high) // Register is read only on
- // Internet PhoneJack Lite
+ if (bytes.low == bytes.high) /* Register is read only on */
+ /* Internet PhoneJack Lite */
{
j->cardtype = QTI_PHONEJACK_LITE;
if (check_region(j->XILINXbase, 4)) {
break;
}
}
- if (j->dsp.low == 0x20
- || j->cardtype == QTI_PHONEJACK_LITE
- || j->cardtype == QTI_PHONEJACK_PCI) {
- if (ixjdebug > 0)
+ if (j->dsp.low == 0x20 || j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Write CODEC config to Software Control Register\n");
if (ixj_WriteDSPCommand(0xC462, j)) /* Write CODEC config to Software Control Register */
return -1;
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
if (j->cardtype == QTI_PHONEJACK) {
cmd = 0x9FF2;
} else {
if (set_base_frame(j, 30) != 30)
return -1;
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Write CODEC config to Software Control Register\n");
if (j->cardtype == QTI_PHONECARD) {
if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */
if (j->cardtype == QTI_LINEJACK) {
if (ixj_WriteDSPCommand(0xC528, j)) /* Write CODEC config to Software Control Register */
return -1;
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
j->pld_clock.byte = 0;
outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
}
if (j->dsp.low == 0x20) {
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Configure GPIO pins\n");
j->gpio.bytes.high = 0x09;
/* bytes.low = 0xEF; 0xF7 */
j->gpio.bits.gpio6 = 1;
j->gpio.bits.gpio7 = 1;
ixj_WriteDSPCommand(j->gpio.word, j); /* Set GPIO pin directions */
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Enable SLIC\n");
j->gpio.bytes.high = 0x0B;
j->gpio.bytes.low = 0x00;
}
LED_SetState(0x0, j);
daa_get_version(j);
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk("Loading DAA Coefficients\n");
DAA_Coeff_US(j);
- if (!ixj_daa_write(j))
- printk("DAA write failed on board %d\n",
- j->p.board);
- ixj_daa_cid_reset(j);
+ if (!ixj_daa_write(j)) {
+ printk("DAA write failed on board %d\n", j->board);
+ return -1;
+ }
+ if(!ixj_daa_cid_reset(j)) {
+ printk("DAA CID reset failed on board %d\n", j->board);
+ return -1;
+ }
j->flags.pots_correct = 0;
j->flags.pstn_present = 0;
ixj_linetest(j);
if (j->flags.pots_correct) {
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
outb_p(j->pld_scrw.byte, j->XILINXbase);
j->pld_slicw.bits.rly1 = 1;
j->pld_slicw.bits.spken = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
j->port = PORT_POTS;
}
ixj_set_port(j, PORT_PSTN);
ixj_set_pots(j, 1);
- if (ixjdebug > 0)
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Enable Mixer\n");
- ixj_mixer(0x0000, j); //Master Volume Left unmute 0db
+ ixj_mixer(0x0000, j); /*Master Volume Left unmute 0db */
+ ixj_mixer(0x0100, j); /*Master Volume Right unmute 0db */
+
+ ixj_mixer(0x0203, j); /*Voice Left Volume unmute 6db */
+ ixj_mixer(0x0303, j); /*Voice Right Volume unmute 6db */
+
+ ixj_mixer(0x0480, j); /*FM Left mute */
+ ixj_mixer(0x0580, j); /*FM Right mute */
- ixj_mixer(0x0100, j); //Master Volume Right unmute 0db
+ ixj_mixer(0x0680, j); /*CD Left mute */
+ ixj_mixer(0x0780, j); /*CD Right mute */
- ixj_mixer(0x0F00, j); //Mono Out Volume unmute 0db
+ ixj_mixer(0x0880, j); /*Line Left mute */
+ ixj_mixer(0x0980, j); /*Line Right mute */
- ixj_mixer(0x0C00, j); //Mono1 Volume unmute 0db
+ ixj_mixer(0x0A80, j); /*Aux left mute */
+ ixj_mixer(0x0B80, j); /*Aux right mute */
- ixj_mixer(0x0200, j); //Voice Left Volume unmute 0db
+ ixj_mixer(0x0C00, j); /*Mono1 unmute 12db */
+ ixj_mixer(0x0D80, j); /*Mono2 mute */
- ixj_mixer(0x0300, j); //Voice Right Volume unmute 0db
+ ixj_mixer(0x0E80, j); /*Mic mute */
- ixj_mixer(0x110C, j); //Voice Left and Right out
+ ixj_mixer(0x0F00, j); /*Mono Out Volume unmute 0db */
- ixj_mixer(0x1401, j); //Mono1 switch on mixer left
+ ixj_mixer(0x1000, j); /*Voice Left and Right out only */
+ ixj_mixer(0x110C, j);
- ixj_mixer(0x1501, j); //Mono1 switch on mixer right
- ixj_mixer(0x1700, j); //Clock select
+ ixj_mixer(0x1200, j); /*Mono1 switch on mixer left */
+ ixj_mixer(0x1401, j);
- ixj_mixer(0x1800, j); //ADC Source select
+ ixj_mixer(0x1300, j); /*Mono1 switch on mixer right */
+ ixj_mixer(0x1501, j);
+
+ ixj_mixer(0x1700, j); /*Clock select */
+
+ ixj_mixer(0x1800, j); /*ADC input from mixer */
+
+ ixj_mixer(0x1901, j); /*Mic gain 30db */
+
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "Setting Default US Ring Cadence Detection\n");
+ j->cadence_f[4].state = 0;
+ j->cadence_f[4].on1 = 0; /*Cadence Filter 4 is used for PSTN ring cadence */
+ j->cadence_f[4].off1 = 0;
+ j->cadence_f[4].on2 = 0;
+ j->cadence_f[4].off2 = 0;
+ j->cadence_f[4].on3 = 0;
+ j->cadence_f[4].off3 = 0; /* These should represent standard US ring pulse. */
+ j->pstn_last_rmr = jiffies;
} else {
if (j->cardtype == QTI_PHONECARD) {
} else {
ixj_set_port(j, PORT_POTS);
SLIC_SetState(PLD_SLIC_STATE_STANDBY, j);
+/* SLIC_SetState(PLD_SLIC_STATE_ACTIVE, j); */
}
}
}
j->framesread = j->frameswritten = 0;
j->read_wait = j->write_wait = 0;
j->rxreadycheck = j->txreadycheck = 0;
+
+ /* initialise the DTMF prescale to a sensible value */
+ if (j->cardtype == QTI_LINEJACK) {
+ set_dtmf_prescale(j, 0x10);
+ } else {
+ set_dtmf_prescale(j, 0x40);
+ }
set_play_volume(j, 0x100);
set_rec_volume(j, 0x100);
+
if (ixj_WriteDSPCommand(0x0000, j)) /* Write IDLE to Software Control Register */
return -1;
-// The read values of the SSR should be 0x00 for the IDLE command
+/* The read values of the SSR should be 0x00 for the IDLE command */
if (j->ssr.low || j->ssr.high)
return -1;
- if (ixjdebug > 0)
+
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Enable Line Monitor\n");
- if (ixjdebug > 0)
+
+ if (ixjdebug & 0x0002)
printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
- if (ixj_WriteDSPCommand(0x7E01, j)) // Asynchronous Line Monitor
+ if (ixj_WriteDSPCommand(0x7E01, j)) /* Asynchronous Line Monitor */
return -1;
- if (ixjdebug > 0)
+
+ if (ixjdebug & 0x002)
printk(KERN_INFO "Enable DTMF Detectors\n");
- if (ixj_WriteDSPCommand(0x5151, j)) // Enable DTMF detection
+ if (ixj_WriteDSPCommand(0x5151, j)) /* Enable DTMF detection */
return -1;
- if (ixj_WriteDSPCommand(0x6E01, j)) // Set Asyncronous Tone Generation
+ if (ixj_WriteDSPCommand(0x6E01, j)) /* Set Asyncronous Tone Generation */
return -1;
- set_rec_depth(j, 2); // Set Record Channel Limit to 2 frames
- set_play_depth(j, 2); // Set Playback Channel Limit to 2 frames
+ set_rec_depth(j, 2); /* Set Record Channel Limit to 2 frames */
+
+ set_play_depth(j, 2); /* Set Playback Channel Limit to 2 frames */
j->ex.bits.dtmf_ready = 0;
j->dtmf_state = 0;
j->drybuffer = 0;
j->winktime = 320;
j->flags.dtmf_oob = 0;
- for (i = 0; i < 4; i++)
- j->cadence_f[i].enable = 0;
+ for (cnt = 0; cnt < 4; cnt++)
+ j->cadence_f[cnt].enable = 0;
/* must be a device on the specified address */
- ixj_WriteDSPCommand(0x0FE3, j); // Put the DSP in 1/5 power mode.
+ ixj_WriteDSPCommand(0x0FE3, j); /* Put the DSP in 1/5 power mode. */
+
+ /* Set up the default signals for events */
+ for (cnt = 0; cnt < 35; cnt++)
+ j->ixj_signals[cnt] = SIGIO;
+
+ /* Set the excetion signal enable flags */
+ j->ex_sig.bits.dtmf_ready = j->ex_sig.bits.hookstate = j->ex_sig.bits.flash = j->ex_sig.bits.pstn_ring =
+ j->ex_sig.bits.caller_id = j->ex_sig.bits.pstn_wink = j->ex_sig.bits.f0 = j->ex_sig.bits.f1 = j->ex_sig.bits.f2 =
+ j->ex_sig.bits.f3 = j->ex_sig.bits.fc0 = j->ex_sig.bits.fc1 = j->ex_sig.bits.fc2 = j->ex_sig.bits.fc3 = 1;
+#ifdef IXJ_DYN_ALLOC
+ j->fskdata = NULL;
+#endif
+ j->fskdcnt = 0;
+ j->cidcw_wait = 0;
+
/* Register with the Telephony for Linux subsystem */
j->p.f_op = &ixj_fops;
j->p.open = ixj_open;
- j->p.board = cnt;
+ j->p.board = j->board;
phone_register_device(&j->p, PHONE_UNIT_ANY);
- add_caps(j);
+
+ ixj_init_timer(j);
+ ixj_add_timer(j);
return 0;
}
-int ixj_get_status_proc(char *buf)
+/*
+ * Exported service for pcmcia card handling
+ */
+
+IXJ *ixj_pcmcia_probe(unsigned long dsp, unsigned long xilinx)
+{
+ IXJ *j = ixj_alloc();
+
+ j->board = 0;
+
+ j->DSPbase = dsp;
+ j->XILINXbase = xilinx;
+ j->cardtype = QTI_PHONECARD;
+ ixj_selfprobe(j);
+ return j;
+}
+
+EXPORT_SYMBOL(ixj_pcmcia_probe); /* Fpr PCMCIA */
+
+static int ixj_get_status_proc(char *buf)
{
int len;
int cnt;
IXJ *j;
len = 0;
- len += sprintf(buf + len, "\n%s", ixj_c_rcsid);
+ len += sprintf(buf + len, "%s", ixj_c_rcsid);
len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- j = ixj[cnt];
+ len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER);
+ len += sprintf(buf + len, "\nsizeof IXJ struct %d bytes", sizeof(IXJ));
+ len += sprintf(buf + len, "\nsizeof DAA struct %d bytes", sizeof(DAA_REGS));
+ len += sprintf(buf + len, "\nUsing old telephony API");
+ len += sprintf(buf + len, "\nDebug Level %d\n", ixjdebug);
- if (j == NULL)
+ for (cnt = 0; cnt < IXJMAX; cnt++) {
+ j = get_ixj(cnt);
+ if(j==NULL)
continue;
-
if (j->DSPbase) {
len += sprintf(buf + len, "\nCard Num %d", cnt);
len += sprintf(buf + len, "\nDSP Base Address 0x%4.4x", j->DSPbase);
len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
if (j->flags.g729_loaded)
len += sprintf(buf + len, " w/G.729 A/B");
- len += sprintf(buf + len, " Country = %d", j->country);
+ len += sprintf(buf + len, " Country = %d", j->daa_country);
break;
case (QTI_PHONEJACK_LITE):
len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
}
len += sprintf(buf + len, "\nReaders %d", j->readers);
len += sprintf(buf + len, "\nWriters %d", j->writers);
- /* FIXME: This makes no sense! */
- len += sprintf(buf + len, "\nFSK words %d", ixj[2] ? ixj[2]->fskdcnt : 0);
+ add_caps(j);
len += sprintf(buf + len, "\nCapabilities %d", j->caps);
if (j->dsp.low != 0x20)
len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
else
len += sprintf(buf + len, "\nCaller ID data not sent");
- len += sprintf(buf + len, "\nCaller ID Date %s%s", j->cid_send.month, j->cid_send.day);
- len += sprintf(buf + len, "\nCaller ID Time %s%s", j->cid_send.hour, j->cid_send.min);
- len += sprintf(buf + len, "\nCaller ID Name %s", j->cid_send.name);
- len += sprintf(buf + len, "\nCaller ID Number %s", j->cid_send.number);
-
len += sprintf(buf + len, "\nPlay CODEC ");
switch (j->play_codec) {
case G723_63:
case G729:
len += sprintf(buf + len, "G.729");
break;
+ case G729B:
+ len += sprintf(buf + len, "G.729B");
+ break;
case ULAW:
len += sprintf(buf + len, "uLaw");
break;
case G729:
len += sprintf(buf + len, "G.729");
break;
+ case G729B:
+ len += sprintf(buf + len, "G.729B");
+ break;
case ULAW:
len += sprintf(buf + len, "uLaw");
break;
len += sprintf(buf + len, "NO CODEC CHOSEN");
break;
}
+ len += sprintf(buf + len, "\nAEC ");
switch (j->aec_level) {
case AEC_OFF:
- len += sprintf(buf + len, "\n AEC OFF");
+ len += sprintf(buf + len, "Off");
break;
case AEC_LOW:
- len += sprintf(buf + len, "\n AEC LOW");
+ len += sprintf(buf + len, "Low");
break;
case AEC_MED:
- len += sprintf(buf + len, "\n AEC MED");
+ len += sprintf(buf + len, "Med");
break;
case AEC_HIGH:
- len += sprintf(buf + len, "\n AEC HIGH");
+ len += sprintf(buf + len, "High");
+ break;
+ case AEC_AUTO:
+ len += sprintf(buf + len, "Auto");
+ break;
+ case AEC_AGC:
+ len += sprintf(buf + len, "AEC/AGC");
+ break;
+ default:
+ len += sprintf(buf + len, "unknown(%i)", j->aec_level);
break;
}
- len += sprintf(buf + len, "\nHook state %d", j->r_hook); // ixj_hookstate(cnt));
+
+ len += sprintf(buf + len, "\nRec volume 0x%x", get_rec_volume(j));
+ len += sprintf(buf + len, "\nPlay volume 0x%x", get_play_volume(j));
+ len += sprintf(buf + len, "\nDTMF prescale 0x%x", get_dtmf_prescale(j));
+
+ len += sprintf(buf + len, "\nHook state %d", j->hookstate); /* j->r_hook); */
if (j->cardtype == QTI_LINEJACK) {
len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
+ len += sprintf(buf + len, "\nPSTN Check %d", j->flags.pstncheck);
len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
- len += sprintf(buf + len, "\nPSTN sleeptil %ld - jiffies %ld", j->pstn_sleeptil, jiffies);
switch (j->daa_mode) {
case SOP_PU_SLEEP:
len += sprintf(buf + len, "\nDAA PSTN On Hook");
break;
case SOP_PU_RINGING:
len += sprintf(buf + len, "\nDAA PSTN Ringing");
+ len += sprintf(buf + len, "\nRinging state = %d", j->cadence_f[4].state);
break;
case SOP_PU_CONVERSATION:
len += sprintf(buf + len, "\nDAA PSTN Off Hook");
len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
break;
}
+ len += sprintf(buf + len, "\nDAA RMR = %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.bitreg.RMR);
+ len += sprintf(buf + len, "\nDAA VDD OK = %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK);
+ len += sprintf(buf + len, "\nDAA CR0 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg);
+ len += sprintf(buf + len, "\nDAA CR1 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg);
+ len += sprintf(buf + len, "\nDAA CR2 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg);
+ len += sprintf(buf + len, "\nDAA CR3 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg);
+ len += sprintf(buf + len, "\nDAA CR4 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg);
+ len += sprintf(buf + len, "\nDAA CR5 = 0x%02x", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg);
+ len += sprintf(buf + len, "\nDAA XR0 = 0x%02x", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg);
+ len += sprintf(buf + len, "\nDAA ringstop %ld - jiffies %ld", j->pstn_ring_stop, jiffies);
}
switch (j->port) {
case PORT_POTS:
case PLD_SLIC_STATE_ACTIVE:
len += sprintf(buf + len, "ACTIVE");
break;
- case PLD_SLIC_STATE_OHT: // On-hook transmit
-
+ case PLD_SLIC_STATE_OHT: /* On-hook transmit */
len += sprintf(buf + len, "OHT");
break;
case PLD_SLIC_STATE_TIPOPEN:
case PLD_SLIC_STATE_STANDBY:
len += sprintf(buf + len, "STANDBY");
break;
- case PLD_SLIC_STATE_APR: // Active polarity reversal
-
+ case PLD_SLIC_STATE_APR: /* Active polarity reversal */
len += sprintf(buf + len, "APR");
break;
- case PLD_SLIC_STATE_OHTPR: // OHT polarity reversal
-
+ case PLD_SLIC_STATE_OHTPR: /* OHT polarity reversal */
len += sprintf(buf + len, "OHTPR");
break;
default:
break;
}
}
+ len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
+ len += sprintf(buf + len, "\nCID Base Frame %2d", j->cid_base_frame_size);
#ifdef PERFMON_STATS
len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
- len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
len += sprintf(buf + len, "\nFrames Read %ld", j->framesread);
len += sprintf(buf + len, "\nFrames Written %ld", j->frameswritten);
len += sprintf(buf + len, "\nDry Buffer %ld", j->drybuffer);
len += sprintf(buf + len, "\nRead Waits %ld", j->read_wait);
len += sprintf(buf + len, "\nWrite Waits %ld", j->write_wait);
+ len += sprintf(buf + len, "\nStatus Waits %ld", j->statuswait);
+ len += sprintf(buf + len, "\nStatus Wait Fails %ld", j->statuswaitfail);
+ len += sprintf(buf + len, "\nPControl Waits %ld", j->pcontrolwait);
+ len += sprintf(buf + len, "\nPControl Wait Fails %ld", j->pcontrolwaitfail);
+ len += sprintf(buf + len, "\nIs Control Ready Checks %ld", j->iscontrolready);
+ len += sprintf(buf + len, "\nIs Control Ready Check failures %ld", j->iscontrolreadyfail);
+
#endif
len += sprintf(buf + len, "\n");
- }
- }
- return len;
-}
-
-int ixj_get_status_proc_fsk(char *buf)
-{
- int len;
- len = 0;
-
- /* This makes no sense - why is ixj[2] special? */
- if (ixj[2] != NULL && ixj[2]->fskdcnt) {
- memcpy(buf, &ixj[2]->fskdata, (ixj[2]->fskdcnt) * 2);
- len += ixj[2]->fskdcnt * 2;
- }
- return len;
-}
-
-static int ixj_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- int len = ixj_get_status_proc(page);
- if (len <= off+count) *eof = 1;
- *start = page + off;
- len -= off;
- if (len>count) len = count;
- if (len<0) len = 0;
- return len;
+ }
+ }
+ return len;
}
-static int ixj_read_proc_fsk(char *page, char **start, off_t off,
+static int ixj_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
- int len = ixj_get_status_proc_fsk(page);
+ int len = ixj_get_status_proc(page);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
return len;
}
-MODULE_DESCRIPTION("Internet Phone/Internet LineJack module - www.quicknet.net");
-MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
-
-#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
-
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...)
-#endif /* PCMCIA_DEBUG */
-
-typedef struct ixj_info_t {
- int ndev;
- dev_node_t node;
- struct ixj *port;
-} ixj_info_t;
-static dev_link_t *ixj_attach(void);
-static void ixj_detach(dev_link_t *);
-static void ixj_config(dev_link_t * link);
-static void ixj_cs_release(u_long arg);
-static int ixj_event(event_t event, int priority, event_callback_args_t * args);
-static dev_info_t dev_info = "ixj_cs";
-static dev_link_t *dev_list = NULL;
-static void cs_error(client_handle_t handle, int func, int ret)
-{
- error_info_t err =
- {
- func, ret
- };
- CardServices(ReportError, handle, &err);
-}
-
-static dev_link_t *ixj_attach(void)
-{
- client_reg_t client_reg;
- dev_link_t *link;
- int ret;
- DEBUG(0, "ixj_attach()\n");
- /* Create new ixj device */
- link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
- if (!link)
- return NULL;
- memset(link, 0, sizeof(struct dev_link_t));
- link->release.function = &ixj_cs_release;
- link->release.data = (u_long) link;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = 3;
- link->conf.Vcc = 50;
- link->conf.IntType = INT_MEMORY_AND_IO;
- link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
- if (!link->priv)
- return NULL;
- memset(link->priv, 0, sizeof(struct ixj_info_t));
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
- client_reg.dev_info = &dev_info;
- client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
- client_reg.EventMask =
- CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
- CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
- CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
- client_reg.event_handler = &ixj_event;
- client_reg.Version = 0x0210;
- client_reg.event_callback_args.client_data = link;
- ret = CardServices(RegisterClient, &link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
- cs_error(link->handle, RegisterClient, ret);
- ixj_detach(link);
- return NULL;
- }
- return link;
-}
-
-static void ixj_detach(dev_link_t * link)
-{
- dev_link_t **linkp;
- long flags;
- int ret;
- DEBUG(0, "ixj_detach(0x%p)\n", link);
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link)
- break;
- if (*linkp == NULL)
- return;
- save_flags(flags);
- cli();
- if (link->state & DEV_RELEASE_PENDING) {
- del_timer(&link->release);
- link->state &= ~DEV_RELEASE_PENDING;
- }
- restore_flags(flags);
- if (link->state & DEV_CONFIG)
- ixj_cs_release((u_long) link);
- if (link->handle) {
- ret = CardServices(DeregisterClient, link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
- /* Unlink device structure, free bits */
- *linkp = link->next;
- kfree(link->priv);
- kfree(link);
-}
-
-#define CS_CHECK(fn, args...) \
-while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
-
-#define CFG_CHECK(fn, args...) \
-if (CardServices(fn, args) != 0) goto next_entry
-
-void ixj_get_serial(dev_link_t * link, IXJ * j)
-{
- client_handle_t handle;
- tuple_t tuple;
- u_short buf[128];
- char *str;
- int last_ret, last_fn, i, place;
- handle = link->handle;
- DEBUG(0, "ixj_get_serial(0x%p)\n", link);
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 80;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_VERS_1;
- CS_CHECK(GetFirstTuple, handle, &tuple);
- CS_CHECK(GetTupleData, handle, &tuple);
- str = (char *) buf;
- printk("PCMCIA Version %d.%d\n", str[0], str[1]);
- str += 2;
- printk("%s", str);
- str = str + strlen(str) + 1;
- printk(" %s", str);
- str = str + strlen(str) + 1;
- place = 1;
- for (i = strlen(str) - 1; i >= 0; i--) {
- switch (str[i]) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- j->serial += (str[i] - 48) * place;
- break;
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- j->serial += (str[i] - 55) * place;
- break;
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- j->serial += (str[i] - 87) * place;
- break;
- }
- place = place * 0x10;
- }
- str = str + strlen(str) + 1;
- printk(" version %s\n", str);
- cs_failed:
- return;
-}
-
-void ixj_config(dev_link_t * link)
-{
- IXJ *j;
- client_handle_t handle;
- ixj_info_t *info;
- tuple_t tuple;
- u_short buf[128];
- cisparse_t parse;
- config_info_t conf;
- cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
- cistpl_cftable_entry_t dflt =
- {
- 0
- };
- int last_ret, last_fn;
- handle = link->handle;
- info = link->priv;
- DEBUG(0, "ixj_config(0x%p)\n", link);
- tuple.TupleData = (cisdata_t *) buf;
- tuple.TupleOffset = 0;
- tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
- tuple.DesiredTuple = CISTPL_CONFIG;
- CS_CHECK(GetFirstTuple, handle, &tuple);
- CS_CHECK(GetTupleData, handle, &tuple);
- CS_CHECK(ParseTuple, handle, &tuple, &parse);
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
- link->state |= DEV_CONFIG;
- CS_CHECK(GetConfigurationInfo, handle, &conf);
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- tuple.Attributes = 0;
- CS_CHECK(GetFirstTuple, handle, &tuple);
- while (1) {
- CFG_CHECK(GetTupleData, handle, &tuple);
- CFG_CHECK(ParseTuple, handle, &tuple, &parse);
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
- link->conf.ConfigIndex = cfg->index;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
- if (io->nwin == 2) {
- link->io.BasePort2 = io->win[1].base;
- link->io.NumPorts2 = io->win[1].len;
- }
- CFG_CHECK(RequestIO, link->handle, &link->io);
- /* If we've got this far, we're done */
- break;
- }
- next_entry:
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
- dflt = *cfg;
- CS_CHECK(GetNextTuple, handle, &tuple);
- }
-
- CS_CHECK(RequestConfiguration, handle, &link->conf);
-
-
- if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL)
- goto cs_failed;
-
- ixj[0] = j;
-
- j->DSPbase = link->io.BasePort1;
- j->XILINXbase = link->io.BasePort1 + 0x10;
- j->cardtype = QTI_PHONECARD;
- ixj_selfprobe(j, 0);
-
- info->ndev = 1;
- info->node.major = PHONE_MAJOR;
- link->dev = &info->node;
- ixj_get_serial(link, j);
- link->state &= ~DEV_CONFIG_PENDING;
- return;
-
- cs_failed:
- cs_error(link->handle, last_fn, last_ret);
- ixj_cs_release((u_long) link);
-}
-
-void ixj_cs_release(u_long arg)
-{
- dev_link_t *link = (dev_link_t *) arg;
- ixj_info_t *info = link->priv;
- DEBUG(0, "ixj_cs_release(0x%p)\n", link);
- info->ndev = 0;
- link->dev = NULL;
- CardServices(ReleaseConfiguration, link->handle);
- CardServices(ReleaseIO, link->handle, &link->io);
- link->state &= ~DEV_CONFIG;
-
- kfree(ixj[0]);
- ixj[0] = NULL;
-}
-
-int ixj_event(event_t event, int priority, event_callback_args_t * args)
-{
- dev_link_t *link = args->client_data;
- DEBUG(1, "ixj_event(0x%06x)\n", event);
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
- if (link->state & DEV_CONFIG) {
- link->release.expires = jiffies + (HZ / 20);
- link->state |= DEV_RELEASE_PENDING;
- add_timer(&link->release);
- }
- break;
- case CS_EVENT_CARD_INSERTION:
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- ixj_config(link);
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_RESET_PHYSICAL:
- if (link->state & DEV_CONFIG)
- CardServices(ReleaseConfiguration, link->handle);
- break;
- case CS_EVENT_PM_RESUME:
- link->state &= ~DEV_SUSPEND;
- /* Fall through... */
- case CS_EVENT_CARD_RESET:
- if (DEV_OK(link))
- CardServices(RequestConfiguration, link->handle, &link->conf);
- break;
- }
- return 0;
-}
-
-#endif /* CONFIG_PCMCIA */
static void cleanup(void)
{
int cnt;
- del_timer(&ixj_timer);
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- IXJ *j = ixj[cnt];
-
- if (j == NULL)
- continue;
+ IXJ *j;
- if (j->cardtype == QTI_LINEJACK) {
- j->pld_scrw.bits.daafsyncen = 0; // Turn off DAA Frame Sync
+ for (cnt = 0; cnt < IXJMAX; cnt++) {
+ j = get_ixj(cnt);
+ if(j != NULL && j->DSPbase) {
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Deleting timer for /dev/phone%d\n", cnt);
+ del_timer(&j->timer);
+ if (j->cardtype == QTI_LINEJACK) {
+ j->pld_scrw.bits.daafsyncen = 0; /* Turn off DAA Frame Sync */
- outb_p(j->pld_scrw.byte, j->XILINXbase);
- j->pld_slicw.bits.rly1 = 0;
- j->pld_slicw.bits.rly2 = 0;
- j->pld_slicw.bits.rly3 = 0;
- outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
- LED_SetState(0x0, j);
- release_region(j->XILINXbase, 8);
- }
- if (j->cardtype == QTI_PHONEJACK_LITE
- || j->cardtype == QTI_PHONEJACK_PCI) {
- release_region(j->XILINXbase, 4);
- }
- if (j->DSPbase) {
- release_region(j->DSPbase, 16);
+ outb_p(j->pld_scrw.byte, j->XILINXbase);
+ j->pld_slicw.bits.rly1 = 0;
+ j->pld_slicw.bits.rly2 = 0;
+ j->pld_slicw.bits.rly3 = 0;
+ outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+ LED_SetState(0x0, j);
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
+ release_region(j->XILINXbase, 8);
+ } else if (j->cardtype == QTI_PHONEJACK_LITE || j->cardtype == QTI_PHONEJACK_PCI) {
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Releasing XILINX address for /dev/phone%d\n", cnt);
+ release_region(j->XILINXbase, 4);
+ }
+ if (j->read_buffer)
+ kfree(j->read_buffer);
+ if (j->write_buffer)
+ kfree(j->write_buffer);
+ if (j->dev && j->dev->deactivate)
+ j->dev->deactivate(j->dev);
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Unregistering /dev/phone%d from LTAPI\n", cnt);
phone_unregister_device(&j->p);
- }
- if (j->read_buffer)
- kfree(j->read_buffer);
- if (j->write_buffer)
- kfree(j->write_buffer);
-#ifdef CONFIG_ISAPNP
- if (j->dev)
- j->dev->deactivate(j->dev);
-#endif
-#ifdef CONFIG_PCMCIA
- DEBUG(0, "ixj_cs: unloading\n");
- unregister_pcmcia_driver(&dev_info);
- while (dev_list != NULL)
- ixj_detach(dev_list);
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Releasing DSP address for /dev/phone%d\n", cnt);
+ release_region(j->DSPbase, 16);
+#ifdef IXJ_DYN_ALLOC
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Freeing memory for /dev/phone%d\n", cnt);
+ kfree(j);
+ ixj[cnt] = NULL;
#endif
-
- kfree(j);
- ixj[cnt] = NULL;
+ }
}
+ if (ixjdebug & 0x0002)
+ printk(KERN_INFO "IXJ: Removing /proc/ixj\n");
remove_proc_entry ("ixj", NULL);
- remove_proc_entry ("ixjfsk", NULL);
}
-// Typedefs
+/* Typedefs */
typedef struct {
BYTE length;
DWORD bits;
} DATABLOCK;
+
static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
{
lastLCC = lastLCC & 0xfb;
lastLCC = lastLCC | (byData ? 4 : 0);
- outb(lastLCC, wEEPROMAddress); //set data out bit as appropriate
+ outb(lastLCC, wEEPROMAddress); /*set data out bit as appropriate */
- udelay(1000);
+ mdelay(1);
lastLCC = lastLCC | 0x01;
- outb(lastLCC, wEEPROMAddress); //SK rising edge
+ outb(lastLCC, wEEPROMAddress); /*SK rising edge */
byData = byData << 1;
lastLCC = lastLCC & 0xfe;
- udelay(1000);
- outb(lastLCC, wEEPROMAddress); //after delay, SK falling edge
+ mdelay(1);
+ outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */
}
static BYTE PCIEE_ReadBit(WORD wEEPROMAddress, BYTE lastLCC)
{
- udelay(1000);
+ mdelay(1);
lastLCC = lastLCC | 0x01;
- outb(lastLCC, wEEPROMAddress); //SK rising edge
+ outb(lastLCC, wEEPROMAddress); /*SK rising edge */
lastLCC = lastLCC & 0xfe;
- udelay(1000);
- outb(lastLCC, wEEPROMAddress); //after delay, SK falling edge
+ mdelay(1);
+ outb(lastLCC, wEEPROMAddress); /*after delay, SK falling edge */
return ((inb(wEEPROMAddress) >> 3) & 1);
}
lastLCC = inb(wEEPROMAddress);
lastLCC = lastLCC | 0x02;
lastLCC = lastLCC & 0xfe;
- outb(lastLCC, wEEPROMAddress); // CS hi, SK lo
+ outb(lastLCC, wEEPROMAddress); /* CS hi, SK lo */
- udelay(1000); // delay
+ mdelay(1); /* delay */
PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
*pwResult = (*pwResult << 1) | byResult;
}
- udelay(1000); // another delay
+ mdelay(1); /* another delay */
lastLCC = lastLCC & 0xfd;
- outb(lastLCC, wEEPROMAddress); // negate CS
+ outb(lastLCC, wEEPROMAddress); /* negate CS */
return 0;
}
return (((DWORD) wHi << 16) | wLo);
}
-#ifndef CONFIG_ISAPNP
-static int dspio[IXJMAX + 1];
-static int xio[IXJMAX + 1];
+static int dspio[IXJMAX + 1] =
+{
+ 0,
+};
+static int xio[IXJMAX + 1] =
+{
+ 0,
+};
MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
-#endif
+MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
+MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
+MODULE_LICENSE("GPL");
void ixj_exit(void)
{
- cleanup();
-}
-
-#if defined(CONFIG_PCMCIA)
-int __init ixj_register_pcmcia(void)
-{
- servinfo_t serv;
-
- DEBUG(0, "%s\n", version);
- CardServices(GetCardServicesInfo, &serv);
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
- return -EINVAL;
- }
- register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
- return 0;
-}
-#else
-extern __inline__ int ixj_register_pcmcia(void)
-{
- return 0;
-}
-#endif /* CONFIG_PCMCIA */
-
-#if defined(CONFIG_ISAPNP)
-extern __inline__ int ixj_probe_isa(int *cnt)
-{
- return 0;
+ cleanup();
}
int __init ixj_probe_isapnp(int *cnt)
-{
+{
int probe = 0;
int func = 0x110;
- struct pci_dev *dev = NULL, *old_dev = NULL;
+ struct pci_dev *dev = NULL, *old_dev = NULL;
while (1) {
do {
old_dev = dev;
dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
- ISAPNP_FUNCTION(func), old_dev);
+ ISAPNP_FUNCTION(func), old_dev);
if (!dev)
break;
result = dev->prepare(dev);
return -ENOMEM;
}
- /* DSP base */
- if ((result = check_region(dev->resource[0].start, 16)) < 0) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n",
- dev->resource[0].start);
- cleanup();
- return result;
- }
-
- if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
- cleanup();
- return -ENOMEM;
+ result = check_region(dev->resource[0].start, 16);
+ if (result) {
+ printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", dev->resource[0].start);
+ break;
}
- ixj[*cnt] = j;
-
- j->DSPbase = dev->resource[0].start;
-
- /* XXX is this racy? */
+ j = ixj_alloc();
request_region(j->DSPbase, 16, "ixj DSP");
if (func != 0x110)
- j->XILINXbase = dev->resource[1].start;
+ j->XILINXbase = dev->resource[1].start; /* get real port */
switch (func) {
case (0x110):
j->cardtype = QTI_PHONEJACK_LITE;
break;
}
- probe = ixj_selfprobe(j, *cnt);
-
- j->serial = dev->bus->serial;
- j->dev = dev;
- switch (func) {
- case 0x110:
- printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n",
- j->DSPbase);
- break;
- case 0x310:
- printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n",
- j->DSPbase);
- break;
- case 0x410:
- printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n",
- j->DSPbase);
- break;
+ j->board = *cnt;
+ probe = ixj_selfprobe(j);
+ if(!probe) {
+ j->serial = dev->bus->serial;
+ j->dev = dev;
+ switch (func) {
+ case 0x110:
+ printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", j->DSPbase);
+ break;
+ case 0x310:
+ printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", j->DSPbase);
+ break;
+ case 0x410:
+ printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", j->DSPbase);
+ break;
+ }
}
++*cnt;
} while (dev);
func = 0x310;
dev = NULL;
}
-
return probe;
}
-#else
-extern __inline__ int ixj_probe_isapnp(int *cnt)
-{
- return 0;
-}
-
+
int __init ixj_probe_isa(int *cnt)
{
int i, result, probe;
if (dspio[i]) {
IXJ *j;
- if ((result = check_region(dspio[i], 16)) < 0) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", dspio[i]);
- cleanup();
- return result;
+ if ((result = check_region(ixj[*cnt].DSPbase, 16)) < 0) {
+ printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[*cnt].DSPbase);
+ break;
}
- if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
- cleanup();
- return -ENOMEM;
- }
- ixj[*cnt] = j;
+ j = ixj_alloc();
j->DSPbase = dspio[i];
request_region(j->DSPbase, 16, "ixj DSP");
j->XILINXbase = xio[i];
j->cardtype = 0;
- probe = ixj_selfprobe(j, *cnt);
+ j->board = *cnt;
+ probe = ixj_selfprobe(j);
j->dev = NULL;
-
++*cnt;
}
}
-
return 0;
}
-#endif /* CONFIG_ISAPNP */
-#if defined(CONFIG_PCI)
int __init ixj_probe_pci(int *cnt)
{
- struct pci_dev *pci = NULL;
+ struct pci_dev *pci = NULL;
int i, probe = 0;
+ IXJ *j = NULL;
+ int result;
+
+ if(!pci_present())
+ return 0;
for (i = 0; i < IXJMAX - *cnt; i++) {
pci = pci_find_device(0x15E2, 0x0500, pci);
if (!pci)
break;
+
if (pci_enable_device(pci))
break;
- {
- IXJ *j;
- int result;
-
- if ((result = check_region(pci_resource_start(pci, 0), 16)) < 0) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n",
- pci_resource_start(pci, 0));
- cleanup();
- return result;
- }
-
- if ((j = kmalloc(sizeof(*j), GFP_KERNEL)) == NULL) {
- cleanup();
- return -ENOMEM;
- }
- ixj[*cnt] = j;
-
- j->DSPbase = pci_resource_start(pci, 0);
- request_region(j->DSPbase, 16, "ixj DSP");
-
- j->XILINXbase = j->DSPbase + 0x10;
- j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
- j->cardtype = QTI_PHONEJACK_PCI;
-
- probe = ixj_selfprobe(j, *cnt);
- if (probe)
- printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
- ++*cnt;
+ if ((result = check_region(pci_resource_start(pci, 0), 16)) < 0) {
+ printk(KERN_INFO "ixj: can't get I/O address\n");
+ break;
}
- }
+ /* Grab a device slot */
+ j = ixj_alloc();
+ if(j == NULL)
+ break;
+
+ j->DSPbase = pci_resource_start(pci, 0);
+ j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
+ j->XILINXbase = j->DSPbase + 0x10;
+ request_region(j->DSPbase, 16, "ixj DSP");
+ j->cardtype = QTI_PHONEJACK_PCI;
+ j->board = *cnt;
+ probe = ixj_selfprobe(j);
+ if (!probe)
+ printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", j->DSPbase);
+ ++*cnt;
+ }
return probe;
}
-#else
-extern __inline__ int ixj_probe_pci(int *cnt)
-{
- return 0;
-}
-#endif /* CONFIG_PCI */
int __init ixj_init(void)
{
int cnt = 0;
- int probe = 0;
+ int probe = 0;
+
+ cnt = 0;
/* These might be no-ops, see above. */
- if ((probe = ixj_register_pcmcia()) < 0) {
- return probe;
- }
if ((probe = ixj_probe_isapnp(&cnt)) < 0) {
return probe;
}
if ((probe = ixj_probe_pci(&cnt)) < 0) {
return probe;
}
- }
-
+ }
printk("%s\n", ixj_c_rcsid);
-
create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL);
- create_proc_read_entry ("ixjfsk", 0, NULL, ixj_read_proc_fsk, NULL);
-
- ixj_init_timer();
- ixj_add_timer();
-
return probe;
}
int i;
j->daa_country = DAA_US;
- //-----------------------------------------------
- // CAO
+ /*----------------------------------------------- */
+ /* CAO */
for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
}
-// Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x32;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2F;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0xC2;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x5A;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xC0;
+/* Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00 */
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x03;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x4B;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x5D;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xCD;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[3] = 0x24;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xC5;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x72;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x85;
+/* Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08 */
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x71;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x1A;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0E;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0x2B;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
- j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[4] = 0x0A;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[3] = 0xB5;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
+ j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x03;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0xF2;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x48;
- j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x70;
+/* Bytes for FRX-filter (08): 03,8F,48,F2,8F,48,70,08 */
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x05;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xA3;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x72;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[4] = 0x34;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[3] = 0x3F;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x3B;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x04;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x7F;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x9B;
- j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
+/* Bytes for FRR-filter (07): 04,8F,38,7F,9B,EA,B0,08 */
+ j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x05;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[4] = 0x3E;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[3] = 0x32;
+ j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xDA;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter (0A): 16,55,DD,CA
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
- j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x55;
+/* Bytes for AX-filter (0A): 16,55,DD,CA */
+ j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x41;
+ j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter (09): 52,D3,11,42
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x52;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xD3;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x11;
- j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x42;
-// Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98
+/* Bytes for AR-filter (09): 52,D3,11,42 */
+ j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
+ j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
+ j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
+ j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[4] = 0x81;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xB3;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[3] = 0xA5;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD
+/* Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xF2;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x33;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xA0;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0x68;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xA2;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2B;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[4] = 0xB0;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[3] = 0xE8;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAD;
-// Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xCC;
+/* Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x54;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xA4;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2D;
- j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBB;
-// ; (10K, 0.68uF)
- //
- // Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xD2;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[4] = 0x24;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[3] = 0xBA;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xA9;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x3B;
+ j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xA6;
+/* ; (10K, 0.68uF) */
+ /* */
+ /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0xD4;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0x3A;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x22;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
+ /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBA;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0xD4;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
- j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x22;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
+ j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-//
- // Levelmetering Ringing (0D):B2,45,0F,8E
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
- j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
+
+ /* Levelmetering Ringing (0D):B2,45,0F,8E */
+ j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
+ j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
+
+ /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1C; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0xB3; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0xAB; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[4] = 0xAB; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[3] = 0x54; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x2D; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0x62; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x2D; */
+ /* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x2D; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x62; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[4] = 0xBB; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[3] = 0x2A; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7D; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD4; */
+/* */
+ /* Levelmetering Ringing (0D):B2,45,0F,8E */
+/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x05; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F; */
+/* j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E; */
+
+ /* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-//
- // ;CR Registers
- // Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal
+/* */
+ /* ;CR Registers */
+ /* Config. Reg. 0 (filters) (cr0):FE ; CLK gen. by crystal */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-// Config. Reg. 1 (dialing) (cr1):05
+/* Config. Reg. 1 (dialing) (cr1):05 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID) (cr2):04
+/* Config. Reg. 2 (caller ID) (cr2):04 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x03;
-// Config. Reg. 4 (analog gain) (cr4):01
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
- // Config. Reg. 5 (Version) (cr5):02
- // Config. Reg. 6 (Reserved) (cr6):00
- // Config. Reg. 7 (Reserved) (cr7):00
- //
- // ;xr Registers
- // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
-
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
- // Ext. Reg. 1 (Interrupt enable) (xr1):1C // Cadence, RING, Caller ID, VDD_OK
+/* Config. Reg. 3 (testloops) (cr3):03 ; SEL Bit==0, HP-disabled */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
+/* Config. Reg. 4 (analog gain) (cr4):02 */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+ /* Config. Reg. 5 (Version) (cr5):02 */
+ /* Config. Reg. 6 (Reserved) (cr6):00 */
+ /* Config. Reg. 7 (Reserved) (cr7):00 */
+ /* */
+ /* ;xr Registers */
+ /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
+
+ j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
+ /* Ext. Reg. 1 (Interrupt enable) (xr1):3C Cadence, RING, Caller ID, VDD_OK */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
-// Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+/* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x12; //0x32;
- // Ext. Reg. 4 (Cadence) (xr4):00
+/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off == 1 */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x3B; /*0x32; */
+ /* Ext. Reg. 4 (Cadence) (xr4):00 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer) (xr5):22
+/* Ext. Reg. 5 (Ring timer) (xr5):22 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State) (xr6):00
+/* Ext. Reg. 6 (Power State) (xr6):00 */
j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd) (xr7):40
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
- //
- // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
- // 12,33,5A,C3 ; 770 Hz
- // 13,3C,5B,32 ; 852 Hz
- // 1D,1B,5C,CC ; 941 Hz
+/* Ext. Reg. 7 (Vdd) (xr7):40 */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
+ /* */
+ /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
+ /* 12,33,5A,C3 ; 770 Hz */
+ /* 13,3C,5B,32 ; 852 Hz */
+ /* 1D,1B,5C,CC ; 941 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
- // EC,1D,52,22 ; 1336 Hz
- // AA,AC,51,D2 ; 1477 Hz
- // 9B,3B,51,25 ; 1633 Hz
+/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
+ /* EC,1D,52,22 ; 1336 Hz */
+ /* AA,AC,51,D2 ; 1477 Hz */
+ /* 9B,3B,51,25 ; 1633 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
int i;
j->daa_country = DAA_UK;
- //-----------------------------------------------
- // CAO
+ /*----------------------------------------------- */
+ /* CAO */
for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
}
-// Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00
+/* Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08
+/* Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08
+/* Bytes for FRX-filter (08): 07,9B,ED,24,B2,A2,A0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xED;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08
+/* Bytes for FRR-filter (07): 0F,92,F2,B2,87,D2,30,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF2;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter (0A): 1B,A5,DD,CA
+/* Bytes for AX-filter (0A): 1B,A5,DD,CA */
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter (09): E2,27,10,D6
+/* Bytes for AR-filter (09): E2,27,10,D6 */
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98
+/* Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x38;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4
+/* Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x53;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
-// Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32
+/* Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x6A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
-// ; idle
- // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ; idle */
+ /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible?
+/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V less possible? */
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
- // Config. Reg. 0 (filters) (cr0):FF
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing) (cr1):05
+/* ;CR Registers */
+ /* Config. Reg. 0 (filters) (cr0):FF */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing) (cr1):05 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID) (cr2):04
+/* Config. Reg. 2 (caller ID) (cr2):04 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops) (cr3):00 ;
+/* Config. Reg. 3 (testloops) (cr3):00 ; */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain) (cr4):01
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
- // Config. Reg. 5 (Version) (cr5):02
- // Config. Reg. 6 (Reserved) (cr6):00
- // Config. Reg. 7 (Reserved) (cr7):00
- // ;xr Registers
- // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+/* Config. Reg. 4 (analog gain) (cr4):02 */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+ /* Config. Reg. 5 (Version) (cr5):02 */
+ /* Config. Reg. 6 (Reserved) (cr6):00 */
+ /* Config. Reg. 7 (Reserved) (cr7):00 */
+ /* ;xr Registers */
+ /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
- // Ext. Reg. 1 (Interrupt enable) (xr1):1C
+ j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
+ /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
- // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
+ /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char) (xr3):36 ;
+/* Ext. Reg. 3 (DC Char) (xr3):36 ; */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-// Ext. Reg. 4 (Cadence) (xr4):00
+/* Ext. Reg. 4 (Cadence) (xr4):00 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer) (xr5):22
+/* Ext. Reg. 5 (Ring timer) (xr5):22 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State) (xr6):00
+/* Ext. Reg. 6 (Power State) (xr6):00 */
j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd) (xr7):46
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; // 0x46 ??? Should it be 0x00?
- // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
- // 12,33,5A,C3 ; 770 Hz
- // 13,3C,5B,32 ; 852 Hz
- // 1D,1B,5C,CC ; 941 Hz
+/* Ext. Reg. 7 (Vdd) (xr7):46 */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */
+ /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
+ /* 12,33,5A,C3 ; 770 Hz */
+ /* 13,3C,5B,32 ; 852 Hz */
+ /* 1D,1B,5C,CC ; 941 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
- // EC,1D,52,22 ; 1336 Hz
- // AA,AC,51,D2 ; 1477 Hz
- // 9B,3B,51,25 ; 1633 Hz
+/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
+ /* EC,1D,52,22 ; 1336 Hz */
+ /* AA,AC,51,D2 ; 1477 Hz */
+ /* 9B,3B,51,25 ; 1633 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
int i;
j->daa_country = DAA_FRANCE;
- //-----------------------------------------------
- // CAO
+ /*----------------------------------------------- */
+ /* CAO */
for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
}
-// Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00
+/* Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08
+/* Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08
+/* Bytes for FRX-filter (08): 07,9A,28,F6,23,4A,B0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x28;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08
+/* Bytes for FRR-filter (07): 03,8F,F9,2F,9E,FA,20,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xF9;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter (0A): 16,B5,DD,CA
+/* Bytes for AX-filter (0A): 16,B5,DD,CA */
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter (09): 52,C7,10,D6
+/* Bytes for AR-filter (09): 52,C7,10,D6 */
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C
+/* Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
-// Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45
+/* Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
-// ; idle
- // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ; idle */
+ /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V
+/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-// Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
- // Config. Reg. 0 (filters) (cr0):FF
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing) (cr1):05
+/* ;CR Registers */
+ /* Config. Reg. 0 (filters) (cr0):FF */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing) (cr1):05 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID) (cr2):04
+/* Config. Reg. 2 (caller ID) (cr2):04 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops) (cr3):00 ;
+/* Config. Reg. 3 (testloops) (cr3):00 ; */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain) (cr4):01
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
- // Config. Reg. 5 (Version) (cr5):02
- // Config. Reg. 6 (Reserved) (cr6):00
- // Config. Reg. 7 (Reserved) (cr7):00
- // ;xr Registers
- // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+/* Config. Reg. 4 (analog gain) (cr4):02 */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+ /* Config. Reg. 5 (Version) (cr5):02 */
+ /* Config. Reg. 6 (Reserved) (cr6):00 */
+ /* Config. Reg. 7 (Reserved) (cr7):00 */
+ /* ;xr Registers */
+ /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
- // Ext. Reg. 1 (Interrupt enable) (xr1):1C
+ j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
+ /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
- // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
+ /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char) (xr3):36 ;
+/* Ext. Reg. 3 (DC Char) (xr3):36 ; */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-// Ext. Reg. 4 (Cadence) (xr4):00
+/* Ext. Reg. 4 (Cadence) (xr4):00 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer) (xr5):22
+/* Ext. Reg. 5 (Ring timer) (xr5):22 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State) (xr6):00
+/* Ext. Reg. 6 (Power State) (xr6):00 */
j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd) (xr7):46
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; // 0x46 ??? Should it be 0x00?
- // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
- // 12,33,5A,C3 ; 770 Hz
- // 13,3C,5B,32 ; 852 Hz
- // 1D,1B,5C,CC ; 941 Hz
+/* Ext. Reg. 7 (Vdd) (xr7):46 */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46; /* 0x46 ??? Should it be 0x00? */
+ /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
+ /* 12,33,5A,C3 ; 770 Hz */
+ /* 13,3C,5B,32 ; 852 Hz */
+ /* 1D,1B,5C,CC ; 941 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
- // EC,1D,52,22 ; 1336 Hz
- // AA,AC,51,D2 ; 1477 Hz
- // 9B,3B,51,25 ; 1633 Hz
+/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
+ /* EC,1D,52,22 ; 1336 Hz */
+ /* AA,AC,51,D2 ; 1477 Hz */
+ /* 9B,3B,51,25 ; 1633 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
int i;
j->daa_country = DAA_GERMANY;
- //-----------------------------------------------
- // CAO
+ /*----------------------------------------------- */
+ /* CAO */
for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
}
-// Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00
+/* Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08
+/* Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08
+/* Bytes for FRX-filter (08): 07,AA,E2,34,24,89,20,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08
+/* Bytes for FRR-filter (07): 02,87,FA,37,9A,CA,B0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xFA;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter (0A): 72,D5,DD,CA
+/* Bytes for AX-filter (0A): 72,D5,DD,CA */
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter (09): 72,42,13,4B
+/* Bytes for AR-filter (09): 72,42,13,4B */
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
-// Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98
+/* Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27
+/* Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
-// Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2
+/* Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x63;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
-// ; (10K, 0.68uF)
- // Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
+/* ; (10K, 0.68uF) */
+ /* Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
+/* Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing (0D):B2,45,0F,8E
+/* Levelmetering Ringing (0D):B2,45,0F,8E */
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
- // Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled
+/* ;CR Registers */
+ /* Config. Reg. 0 (filters) (cr0):FF ; all Filters enabled, CLK from ext. source */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing) (cr1):05 ; Manual Ring, Ring metering enabled */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal
+/* Config. Reg. 2 (caller ID) (cr2):04 ; Analog Gain 0dB, FSC internal */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled
+/* Config. Reg. 3 (testloops) (cr3):00 ; SEL Bit==0, HP-enabled */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain) (cr4):01
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
- // Config. Reg. 5 (Version) (cr5):02
- // Config. Reg. 6 (Reserved) (cr6):00
- // Config. Reg. 7 (Reserved) (cr7):00
- // ;xr Registers
- // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+/* Config. Reg. 4 (analog gain) (cr4):02 */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+ /* Config. Reg. 5 (Version) (cr5):02 */
+ /* Config. Reg. 6 (Reserved) (cr6):00 */
+ /* Config. Reg. 7 (Reserved) (cr7):00 */
+ /* ;xr Registers */
+ /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
- // Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled
+ j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
+ /* Ext. Reg. 1 (Interrupt enable) (xr1):1C ; Ring, CID, VDDOK Interrupts enabled */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
- // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
+ /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm
+/* Ext. Reg. 3 (DC Char) (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
-// Ext. Reg. 4 (Cadence) (xr4):00
+/* Ext. Reg. 4 (Cadence) (xr4):00 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer) (xr5):22
+/* Ext. Reg. 5 (Ring timer) (xr5):22 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State) (xr6):00
+/* Ext. Reg. 6 (Power State) (xr6):00 */
j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
- // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
- // 12,33,5A,C3 ; 770 Hz
- // 13,3C,5B,32 ; 852 Hz
- // 1D,1B,5C,CC ; 941 Hz
+/* Ext. Reg. 7 (Vdd) (xr7):40 ; VDD=4.25 V */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
+ /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
+ /* 12,33,5A,C3 ; 770 Hz */
+ /* 13,3C,5B,32 ; 852 Hz */
+ /* 1D,1B,5C,CC ; 941 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
- // EC,1D,52,22 ; 1336 Hz
- // AA,AC,51,D2 ; 1477 Hz
- // 9B,3B,51,25 ; 1633 Hz
+/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
+ /* EC,1D,52,22 ; 1336 Hz */
+ /* AA,AC,51,D2 ; 1477 Hz */
+ /* 9B,3B,51,25 ; 1633 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
int i;
j->daa_country = DAA_AUSTRALIA;
- //-----------------------------------------------
- // CAO
+ /*----------------------------------------------- */
+ /* CAO */
for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
}
-// Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00
+/* Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08
+/* Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08
+/* Bytes for FRX-filter (08): 07,96,E2,34,32,9B,30,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0xE2;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08
+/* Bytes for FRR-filter (07): 0F,9A,E9,2F,22,CC,A0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0xE9;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter (0A): CB,45,DD,CA
+/* Bytes for AX-filter (0A): CB,45,DD,CA */
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter (09): 1B,67,10,D6
+/* Bytes for AR-filter (09): 1B,67,10,D6 */
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98
+/* Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC
+/* Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x52;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
-// Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46
+/* Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0x4A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;
-// ; idle
- // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ; idle */
+ /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V
+/* Levelmetering Ringing (0D):32,45,B5,84 ; 50Hz 20V */
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-// Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
- // Config. Reg. 0 (filters) (cr0):FF
+/* ;CR Registers */
+ /* Config. Reg. 0 (filters) (cr0):FF */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-// Config. Reg. 1 (dialing) (cr1):05
+/* Config. Reg. 1 (dialing) (cr1):05 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID) (cr2):04
+/* Config. Reg. 2 (caller ID) (cr2):04 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops) (cr3):00 ;
+/* Config. Reg. 3 (testloops) (cr3):00 ; */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain) (cr4):01
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
- // Config. Reg. 5 (Version) (cr5):02
- // Config. Reg. 6 (Reserved) (cr6):00
- // Config. Reg. 7 (Reserved) (cr7):00
- // ;xr Registers
- // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+/* Config. Reg. 4 (analog gain) (cr4):02 */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+ /* Config. Reg. 5 (Version) (cr5):02 */
+ /* Config. Reg. 6 (Reserved) (cr6):00 */
+ /* Config. Reg. 7 (Reserved) (cr7):00 */
+ /* ;xr Registers */
+ /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
- // Ext. Reg. 1 (Interrupt enable) (xr1):1C
+ j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
+ /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
- // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
+ /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char) (xr3):2B ;
+/* Ext. Reg. 3 (DC Char) (xr3):2B ; */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;
-// Ext. Reg. 4 (Cadence) (xr4):00
+/* Ext. Reg. 4 (Cadence) (xr4):00 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer) (xr5):22
+/* Ext. Reg. 5 (Ring timer) (xr5):22 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State) (xr6):00
+/* Ext. Reg. 6 (Power State) (xr6):00 */
j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd) (xr7):40
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
- // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
- // 12,33,5A,C3 ; 770 Hz
- // 13,3C,5B,32 ; 852 Hz
- // 1D,1B,5C,CC ; 941 Hz
+/* Ext. Reg. 7 (Vdd) (xr7):40 */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
+ /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
+ /* 12,33,5A,C3 ; 770 Hz */
+ /* 13,3C,5B,32 ; 852 Hz */
+ /* 1D,1B,5C,CC ; 941 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
- // EC,1D,52,22 ; 1336 Hz
- // AA,AC,51,D2 ; 1477 Hz
- // 9B,3B,51,25 ; 1633 Hz
+
+ /* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
+ /* EC,1D,52,22 ; 1336 Hz */
+ /* AA,AC,51,D2 ; 1477 Hz */
+ /* 9B,3B,51,25 ; 1633 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
int i;
j->daa_country = DAA_JAPAN;
- //-----------------------------------------------
- // CAO
+ /*----------------------------------------------- */
+ /* CAO */
for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
}
-// Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00
+/* Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-// Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08
+/* Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-// Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08
+/* Bytes for FRX-filter (08): 02,8F,68,77,9C,58,F0,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[5] = 0x68;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;
j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-// Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08
+/* Bytes for FRR-filter (07): 03,8F,38,73,87,EA,20,08 */
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[5] = 0x38;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-// Bytes for AX-filter (0A): 51,C5,DD,CA
+/* Bytes for AX-filter (0A): 51,C5,DD,CA */
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-// Bytes for AR-filter (09): 25,A7,10,D6
+/* Bytes for AR-filter (09): 25,A7,10,D6 */
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-// Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98
+/* Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[5] = 0x48;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-// Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28
+/* Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28 */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[5] = 0x2A;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
-// Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA
+/* Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA */
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[5] = 0xDA;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;
-// ; idle
- // Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+/* ; idle */
+ /* Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-// Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
+/* Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5 */
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[5] = 0xA6;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-// Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ?????????
+/* Levelmetering Ringing (0D):AA,35,0F,8E ; 25Hz 30V ????????? */
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-// Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99
+/* Caller ID 1st Tone (0E):CA,0E,CA,09,99,99,99,99 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[5] = 0xCA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-// Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00
+/* Caller ID 2nd Tone (0F):FD,B5,BA,07,DA,00,00,00 */
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[5] = 0xBA;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-// ;CR Registers
- // Config. Reg. 0 (filters) (cr0):FF
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-// Config. Reg. 1 (dialing) (cr1):05
+/* ;CR Registers */
+ /* Config. Reg. 0 (filters) (cr0):FF */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
+/* Config. Reg. 1 (dialing) (cr1):05 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-// Config. Reg. 2 (caller ID) (cr2):04
+/* Config. Reg. 2 (caller ID) (cr2):04 */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-// Config. Reg. 3 (testloops) (cr3):00 ;
+/* Config. Reg. 3 (testloops) (cr3):00 ; */
j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-// Config. Reg. 4 (analog gain) (cr4):01
- j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02; //0x01;
- // Config. Reg. 5 (Version) (cr5):02
- // Config. Reg. 6 (Reserved) (cr6):00
- // Config. Reg. 7 (Reserved) (cr7):00
- // ;xr Registers
- // Ext. Reg. 0 (Interrupt Reg.) (xr0):02
+/* Config. Reg. 4 (analog gain) (cr4):02 */
+ j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;
+ /* Config. Reg. 5 (Version) (cr5):02 */
+ /* Config. Reg. 6 (Reserved) (cr6):00 */
+ /* Config. Reg. 7 (Reserved) (cr7):00 */
+ /* ;xr Registers */
+ /* Ext. Reg. 0 (Interrupt Reg.) (xr0):02 */
- j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; // SO_1 set to '1' because it is inverted.
- // Ext. Reg. 1 (Interrupt enable) (xr1):1C
+ j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02; /* SO_1 set to '1' because it is inverted. */
+ /* Ext. Reg. 1 (Interrupt enable) (xr1):1C */
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; // RING, Caller ID, VDD_OK
- // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C; /* RING, Caller ID, VDD_OK */
+ /* Ext. Reg. 2 (Cadence Time Out) (xr2):7D */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-// Ext. Reg. 3 (DC Char) (xr3):22 ;
+/* Ext. Reg. 3 (DC Char) (xr3):22 ; */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
-// Ext. Reg. 4 (Cadence) (xr4):00
+/* Ext. Reg. 4 (Cadence) (xr4):00 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-// Ext. Reg. 5 (Ring timer) (xr5):22
+/* Ext. Reg. 5 (Ring timer) (xr5):22 */
j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-// Ext. Reg. 6 (Power State) (xr6):00
+/* Ext. Reg. 6 (Power State) (xr6):00 */
j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-// Ext. Reg. 7 (Vdd) (xr7):40
- j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; // 0x40 ??? Should it be 0x00?
- // DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz
- // 12,33,5A,C3 ; 770 Hz
- // 13,3C,5B,32 ; 852 Hz
- // 1D,1B,5C,CC ; 941 Hz
+/* Ext. Reg. 7 (Vdd) (xr7):40 */
+ j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40; /* 0x40 ??? Should it be 0x00? */
+ /* DTMF Tone 1 (0B): 11,B3,5A,2C ; 697 Hz */
+ /* 12,33,5A,C3 ; 770 Hz */
+ /* 13,3C,5B,32 ; 852 Hz */
+ /* 1D,1B,5C,CC ; 941 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-// DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz
- // EC,1D,52,22 ; 1336 Hz
- // AA,AC,51,D2 ; 1477 Hz
- // 9B,3B,51,25 ; 1633 Hz
+/* DTMF Tone 2 (0C): 32,32,52,B3 ; 1209 Hz */
+ /* EC,1D,52,22 ; 1336 Hz */
+ /* AA,AC,51,D2 ; 1477 Hz */
+ /* 9B,3B,51,25 ; 1633 Hz */
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
static s16 tone_table[][19] =
{
- { // f20_50[] 11
- 32538, // A1 = 1.985962
- -32325, // A2 = -0.986511
- -343, // B2 = -0.010493
- 0, // B1 = 0
- 343, // B0 = 0.010493
- 32619, // A1 = 1.990906
- -32520, // A2 = -0.992462
- 19179, // B2 = 0.585327
- -19178, // B1 = -1.170593
- 19179, // B0 = 0.585327
- 32723, // A1 = 1.997314
- -32686, // A2 = -0.997528
- 9973, // B2 = 0.304352
- -9955, // B1 = -0.607605
- 9973, // B0 = 0.304352
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f20_50[] 11 */
+ 32538, /* A1 = 1.985962 */
+ -32325, /* A2 = -0.986511 */
+ -343, /* B2 = -0.010493 */
+ 0, /* B1 = 0 */
+ 343, /* B0 = 0.010493 */
+ 32619, /* A1 = 1.990906 */
+ -32520, /* A2 = -0.992462 */
+ 19179, /* B2 = 0.585327 */
+ -19178, /* B1 = -1.170593 */
+ 19179, /* B0 = 0.585327 */
+ 32723, /* A1 = 1.997314 */
+ -32686, /* A2 = -0.997528 */
+ 9973, /* B2 = 0.304352 */
+ -9955, /* B1 = -0.607605 */
+ 9973, /* B0 = 0.304352 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
+ },
+ { /* f133_200[] 12 */
+ 32072, /* A1 = 1.95752 */
+ -31896, /* A2 = -0.973419 */
+ -435, /* B2 = -0.013294 */
+ 0, /* B1 = 0 */
+ 435, /* B0 = 0.013294 */
+ 32188, /* A1 = 1.9646 */
+ -32400, /* A2 = -0.98877 */
+ 15139, /* B2 = 0.462036 */
+ -14882, /* B1 = -0.908356 */
+ 15139, /* B0 = 0.462036 */
+ 32473, /* A1 = 1.981995 */
+ -32524, /* A2 = -0.992584 */
+ 23200, /* B2 = 0.708008 */
+ -23113, /* B1 = -1.410706 */
+ 23200, /* B0 = 0.708008 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f133_200[] 12
- 32072, // A1 = 1.95752
- -31896, // A2 = -0.973419
- -435, // B2 = -0.013294
- 0, // B1 = 0
- 435, // B0 = 0.013294
- 32188, // A1 = 1.9646
- -32400, // A2 = -0.98877
- 15139, // B2 = 0.462036
- -14882, // B1 = -0.908356
- 15139, // B0 = 0.462036
- 32473, // A1 = 1.981995
- -32524, // A2 = -0.992584
- 23200, // B2 = 0.708008
- -23113, // B1 = -1.410706
- 23200, // B0 = 0.708008
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f300 13 */
+ 31769, /* A1 = -1.939026 */
+ -32584, /* A2 = 0.994385 */
+ -475, /* B2 = -0.014522 */
+ 0, /* B1 = 0.000000 */
+ 475, /* B0 = 0.014522 */
+ 31789, /* A1 = -1.940247 */
+ -32679, /* A2 = 0.997284 */
+ 17280, /* B2 = 0.527344 */
+ -16865, /* B1 = -1.029358 */
+ 17280, /* B0 = 0.527344 */
+ 31841, /* A1 = -1.943481 */
+ -32681, /* A2 = 0.997345 */
+ 543, /* B2 = 0.016579 */
+ -525, /* B1 = -0.032097 */
+ 543, /* B0 = 0.016579 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 300.txt 13
- 31769, // A1 = -1.939026
- -32584, // A2 = 0.994385
- -475, // B2 = -0.014522
- 0, // B1 = 0.000000
- 475, // B0 = 0.014522
- 31789, // A1 = -1.940247
- -32679, // A2 = 0.997284
- 17280, // B2 = 0.527344
- -16865, // B1 = -1.029358
- 17280, // B0 = 0.527344
- 31841, // A1 = -1.943481
- -32681, // A2 = 0.997345
- 543, // B2 = 0.016579
- -525, // B1 = -0.032097
- 543, // B0 = 0.016579
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f300_420[] 14 */
+ 30750, /* A1 = 1.876892 */
+ -31212, /* A2 = -0.952515 */
+ -804, /* B2 = -0.024541 */
+ 0, /* B1 = 0 */
+ 804, /* B0 = 0.024541 */
+ 30686, /* A1 = 1.872925 */
+ -32145, /* A2 = -0.980988 */
+ 14747, /* B2 = 0.450043 */
+ -13703, /* B1 = -0.836395 */
+ 14747, /* B0 = 0.450043 */
+ 31651, /* A1 = 1.931824 */
+ -32321, /* A2 = -0.986389 */
+ 24425, /* B2 = 0.745422 */
+ -23914, /* B1 = -1.459595 */
+ 24427, /* B0 = 0.745483 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f300_420[] 14
- 30750, // A1 = 1.876892
- -31212, // A2 = -0.952515
- -804, // B2 = -0.024541
- 0, // B1 = 0
- 804, // B0 = 0.024541
- 30686, // A1 = 1.872925
- -32145, // A2 = -0.980988
- 14747, // B2 = 0.450043
- -13703, // B1 = -0.836395
- 14747, // B0 = 0.450043
- 31651, // A1 = 1.931824
- -32321, // A2 = -0.986389
- 24425, // B2 = 0.745422
- -23914, // B1 = -1.459595
- 24427, // B0 = 0.745483
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f330 15 */
+ 31613, /* A1 = -1.929565 */
+ -32646, /* A2 = 0.996277 */
+ -185, /* B2 = -0.005657 */
+ 0, /* B1 = 0.000000 */
+ 185, /* B0 = 0.005657 */
+ 31620, /* A1 = -1.929932 */
+ -32713, /* A2 = 0.998352 */
+ 19253, /* B2 = 0.587585 */
+ -18566, /* B1 = -1.133179 */
+ 19253, /* B0 = 0.587585 */
+ 31674, /* A1 = -1.933228 */
+ -32715, /* A2 = 0.998413 */
+ 2575, /* B2 = 0.078590 */
+ -2495, /* B1 = -0.152283 */
+ 2575, /* B0 = 0.078590 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 330.txt 15
- 31613, // A1 = -1.929565
- -32646, // A2 = 0.996277
- -185, // B2 = -0.005657
- 0, // B1 = 0.000000
- 185, // B0 = 0.005657
- 31620, // A1 = -1.929932
- -32713, // A2 = 0.998352
- 19253, // B2 = 0.587585
- -18566, // B1 = -1.133179
- 19253, // B0 = 0.587585
- 31674, // A1 = -1.933228
- -32715, // A2 = 0.998413
- 2575, // B2 = 0.078590
- -2495, // B1 = -0.152283
- 2575, // B0 = 0.078590
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f300_425[] 16 */
+ 30741, /* A1 = 1.876282 */
+ -31475, /* A2 = -0.960541 */
+ -703, /* B2 = -0.021484 */
+ 0, /* B1 = 0 */
+ 703, /* B0 = 0.021484 */
+ 30688, /* A1 = 1.873047 */
+ -32248, /* A2 = -0.984161 */
+ 14542, /* B2 = 0.443787 */
+ -13523, /* B1 = -0.825439 */
+ 14542, /* B0 = 0.443817 */
+ 31494, /* A1 = 1.922302 */
+ -32366, /* A2 = -0.987762 */
+ 21577, /* B2 = 0.658508 */
+ -21013, /* B1 = -1.282532 */
+ 21577, /* B0 = 0.658508 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f300_425[] 16
- 30741, // A1 = 1.876282
- -31475, // A2 = -0.960541
- -703, // B2 = -0.021484
- 0, // B1 = 0
- 703, // B0 = 0.021484
- 30688, // A1 = 1.873047
- -32248, // A2 = -0.984161
- 14542, // B2 = 0.443787
- -13523, // B1 = -0.825439
- 14542, // B0 = 0.443817
- 31494, // A1 = 1.922302
- -32366, // A2 = -0.987762
- 21577, // B2 = 0.658508
- -21013, // B1 = -1.282532
- 21577, // B0 = 0.658508
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f330_440[] 17 */
+ 30627, /* A1 = 1.869324 */
+ -31338, /* A2 = -0.95636 */
+ -843, /* B2 = -0.025749 */
+ 0, /* B1 = 0 */
+ 843, /* B0 = 0.025749 */
+ 30550, /* A1 = 1.864685 */
+ -32221, /* A2 = -0.983337 */
+ 13594, /* B2 = 0.414886 */
+ -12589, /* B1 = -0.768402 */
+ 13594, /* B0 = 0.414886 */
+ 31488, /* A1 = 1.921936 */
+ -32358, /* A2 = -0.987518 */
+ 24684, /* B2 = 0.753296 */
+ -24029, /* B1 = -1.466614 */
+ 24684, /* B0 = 0.753296 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f330_440[] 17
- 30627, // A1 = 1.869324
- -31338, // A2 = -0.95636
- -843, // B2 = -0.025749
- 0, // B1 = 0
- 843, // B0 = 0.025749
- 30550, // A1 = 1.864685
- -32221, // A2 = -0.983337
- 13594, // B2 = 0.414886
- -12589, // B1 = -0.768402
- 13594, // B0 = 0.414886
- 31488, // A1 = 1.921936
- -32358, // A2 = -0.987518
- 24684, // B2 = 0.753296
- -24029, // B1 = -1.466614
- 24684, // B0 = 0.753296
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f340 18 */
+ 31546, /* A1 = -1.925476 */
+ -32646, /* A2 = 0.996277 */
+ -445, /* B2 = -0.013588 */
+ 0, /* B1 = 0.000000 */
+ 445, /* B0 = 0.013588 */
+ 31551, /* A1 = -1.925781 */
+ -32713, /* A2 = 0.998352 */
+ 23884, /* B2 = 0.728882 */
+ -22979, /* B1 = -1.402527 */
+ 23884, /* B0 = 0.728882 */
+ 31606, /* A1 = -1.929138 */
+ -32715, /* A2 = 0.998413 */
+ 863, /* B2 = 0.026367 */
+ -835, /* B1 = -0.050985 */
+ 863, /* B0 = 0.026367 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 340.txt 18
- 31546, // A1 = -1.925476
- -32646, // A2 = 0.996277
- -445, // B2 = -0.013588
- 0, // B1 = 0.000000
- 445, // B0 = 0.013588
- 31551, // A1 = -1.925781
- -32713, // A2 = 0.998352
- 23884, // B2 = 0.728882
- -22979, // B1 = -1.402527
- 23884, // B0 = 0.728882
- 31606, // A1 = -1.929138
- -32715, // A2 = 0.998413
- 863, // B2 = 0.026367
- -835, // B1 = -0.050985
- 863, // B0 = 0.026367
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f350_400[] 19 */
+ 31006, /* A1 = 1.892517 */
+ -32029, /* A2 = -0.977448 */
+ -461, /* B2 = -0.014096 */
+ 0, /* B1 = 0 */
+ 461, /* B0 = 0.014096 */
+ 30999, /* A1 = 1.892029 */
+ -32487, /* A2 = -0.991455 */
+ 11325, /* B2 = 0.345612 */
+ -10682, /* B1 = -0.651978 */
+ 11325, /* B0 = 0.345612 */
+ 31441, /* A1 = 1.919067 */
+ -32526, /* A2 = -0.992615 */
+ 24324, /* B2 = 0.74231 */
+ -23535, /* B1 = -1.436523 */
+ 24324, /* B0 = 0.74231 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f350_400[] 19
- 31006, // A1 = 1.892517
- -32029, // A2 = -0.977448
- -461, // B2 = -0.014096
- 0, // B1 = 0
- 461, // B0 = 0.014096
- 30999, // A1 = 1.892029
- -32487, // A2 = -0.991455
- 11325, // B2 = 0.345612
- -10682, // B1 = -0.651978
- 11325, // B0 = 0.345612
- 31441, // A1 = 1.919067
- -32526, // A2 = -0.992615
- 24324, // B2 = 0.74231
- -23535, // B1 = -1.436523
- 24324, // B0 = 0.74231
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f350_440[] */
+ 30634, /* A1 = 1.869751 */
+ -31533, /* A2 = -0.962341 */
+ -680, /* B2 = -0.020782 */
+ 0, /* B1 = 0 */
+ 680, /* B0 = 0.020782 */
+ 30571, /* A1 = 1.865906 */
+ -32277, /* A2 = -0.985016 */
+ 12894, /* B2 = 0.393524 */
+ -11945, /* B1 = -0.729065 */
+ 12894, /* B0 = 0.393524 */
+ 31367, /* A1 = 1.91449 */
+ -32379, /* A2 = -0.988129 */
+ 23820, /* B2 = 0.726929 */
+ -23104, /* B1 = -1.410217 */
+ 23820, /* B0 = 0.726929 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f350_440[]
- 30634, // A1 = 1.869751
- -31533, // A2 = -0.962341
- -680, // B2 = -0.020782
- 0, // B1 = 0
- 680, // B0 = 0.020782
- 30571, // A1 = 1.865906
- -32277, // A2 = -0.985016
- 12894, // B2 = 0.393524
- -11945, // B1 = -0.729065
- 12894, // B0 = 0.393524
- 31367, // A1 = 1.91449
- -32379, // A2 = -0.988129
- 23820, // B2 = 0.726929
- -23104, // B1 = -1.410217
- 23820, // B0 = 0.726929
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f350_450[] */
+ 30552, /* A1 = 1.864807 */
+ -31434, /* A2 = -0.95929 */
+ -690, /* B2 = -0.021066 */
+ 0, /* B1 = 0 */
+ 690, /* B0 = 0.021066 */
+ 30472, /* A1 = 1.859924 */
+ -32248, /* A2 = -0.984161 */
+ 13385, /* B2 = 0.408478 */
+ -12357, /* B1 = -0.754242 */
+ 13385, /* B0 = 0.408478 */
+ 31358, /* A1 = 1.914001 */
+ -32366, /* A2 = -0.987732 */
+ 26488, /* B2 = 0.80835 */
+ -25692, /* B1 = -1.568176 */
+ 26490, /* B0 = 0.808411 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f350_450[]
- 30552, // A1 = 1.864807
- -31434, // A2 = -0.95929
- -690, // B2 = -0.021066
- 0, // B1 = 0
- 690, // B0 = 0.021066
- 30472, // A1 = 1.859924
- -32248, // A2 = -0.984161
- 13385, // B2 = 0.408478
- -12357, // B1 = -0.754242
- 13385, // B0 = 0.408478
- 31358, // A1 = 1.914001
- -32366, // A2 = -0.987732
- 26488, // B2 = 0.80835
- -25692, // B1 = -1.568176
- 26490, // B0 = 0.808411
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f360 */
+ 31397, /* A1 = -1.916321 */
+ -32623, /* A2 = 0.995605 */
+ -117, /* B2 = -0.003598 */
+ 0, /* B1 = 0.000000 */
+ 117, /* B0 = 0.003598 */
+ 31403, /* A1 = -1.916687 */
+ -32700, /* A2 = 0.997925 */
+ 3388, /* B2 = 0.103401 */
+ -3240, /* B1 = -0.197784 */
+ 3388, /* B0 = 0.103401 */
+ 31463, /* A1 = -1.920410 */
+ -32702, /* A2 = 0.997986 */
+ 13346, /* B2 = 0.407288 */
+ -12863, /* B1 = -0.785126 */
+ 13346, /* B0 = 0.407288 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 360.txt
- 31397, // A1 = -1.916321
- -32623, // A2 = 0.995605
- -117, // B2 = -0.003598
- 0, // B1 = 0.000000
- 117, // B0 = 0.003598
- 31403, // A1 = -1.916687
- -32700, // A2 = 0.997925
- 3388, // B2 = 0.103401
- -3240, // B1 = -0.197784
- 3388, // B0 = 0.103401
- 31463, // A1 = -1.920410
- -32702, // A2 = 0.997986
- 13346, // B2 = 0.407288
- -12863, // B1 = -0.785126
- 13346, // B0 = 0.407288
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f380_420[] */
+ 30831, /* A1 = 1.881775 */
+ -32064, /* A2 = -0.978546 */
+ -367, /* B2 = -0.01122 */
+ 0, /* B1 = 0 */
+ 367, /* B0 = 0.01122 */
+ 30813, /* A1 = 1.880737 */
+ -32456, /* A2 = -0.990509 */
+ 11068, /* B2 = 0.337769 */
+ -10338, /* B1 = -0.631042 */
+ 11068, /* B0 = 0.337769 */
+ 31214, /* A1 = 1.905212 */
+ -32491, /* A2 = -0.991577 */
+ 16374, /* B2 = 0.499695 */
+ -15781, /* B1 = -0.963196 */
+ 16374, /* B0 = 0.499695 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f380_420[]
- 30831, // A1 = 1.881775
- -32064, // A2 = -0.978546
- -367, // B2 = -0.01122
- 0, // B1 = 0
- 367, // B0 = 0.01122
- 30813, // A1 = 1.880737
- -32456, // A2 = -0.990509
- 11068, // B2 = 0.337769
- -10338, // B1 = -0.631042
- 11068, // B0 = 0.337769
- 31214, // A1 = 1.905212
- -32491, // A2 = -0.991577
- 16374, // B2 = 0.499695
- -15781, // B1 = -0.963196
- 16374, // B0 = 0.499695
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f392 */
+ 31152, /* A1 = -1.901428 */
+ -32613, /* A2 = 0.995300 */
+ -314, /* B2 = -0.009605 */
+ 0, /* B1 = 0.000000 */
+ 314, /* B0 = 0.009605 */
+ 31156, /* A1 = -1.901672 */
+ -32694, /* A2 = 0.997742 */
+ 28847, /* B2 = 0.880371 */
+ -2734, /* B1 = -0.166901 */
+ 28847, /* B0 = 0.880371 */
+ 31225, /* A1 = -1.905823 */
+ -32696, /* A2 = 0.997803 */
+ 462, /* B2 = 0.014108 */
+ -442, /* B1 = -0.027019 */
+ 462, /* B0 = 0.014108 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 392.txt
- 31152, // A1 = -1.901428
- -32613, // A2 = 0.995300
- -314, // B2 = -0.009605
- 0, // B1 = 0.000000
- 314, // B0 = 0.009605
- 31156, // A1 = -1.901672
- -32694, // A2 = 0.997742
- 28847, // B2 = 0.880371
- -2734, // B1 = -0.166901
- 28847, // B0 = 0.880371
- 31225, // A1 = -1.905823
- -32696, // A2 = 0.997803
- 462, // B2 = 0.014108
- -442, // B1 = -0.027019
- 462, // B0 = 0.014108
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f400_425[] */
+ 30836, /* A1 = 1.882141 */
+ -32296, /* A2 = -0.985596 */
+ -324, /* B2 = -0.009903 */
+ 0, /* B1 = 0 */
+ 324, /* B0 = 0.009903 */
+ 30825, /* A1 = 1.881409 */
+ -32570, /* A2 = -0.993958 */
+ 16847, /* B2 = 0.51416 */
+ -15792, /* B1 = -0.963898 */
+ 16847, /* B0 = 0.51416 */
+ 31106, /* A1 = 1.89856 */
+ -32584, /* A2 = -0.994415 */
+ 9579, /* B2 = 0.292328 */
+ -9164, /* B1 = -0.559357 */
+ 9579, /* B0 = 0.292328 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f400_425[]
- 30836, // A1 = 1.882141
- -32296, // A2 = -0.985596
- -324, // B2 = -0.009903
- 0, // B1 = 0
- 324, // B0 = 0.009903
- 30825, // A1 = 1.881409
- -32570, // A2 = -0.993958
- 16847, // B2 = 0.51416
- -15792, // B1 = -0.963898
- 16847, // B0 = 0.51416
- 31106, // A1 = 1.89856
- -32584, // A2 = -0.994415
- 9579, // B2 = 0.292328
- -9164, // B1 = -0.559357
- 9579, // B0 = 0.292328
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f400_440[] */
+ 30702, /* A1 = 1.873962 */
+ -32134, /* A2 = -0.980682 */
+ -517, /* B2 = -0.015793 */
+ 0, /* B1 = 0 */
+ 517, /* B0 = 0.015793 */
+ 30676, /* A1 = 1.872375 */
+ -32520, /* A2 = -0.992462 */
+ 8144, /* B2 = 0.24855 */
+ -7596, /* B1 = -0.463684 */
+ 8144, /* B0 = 0.24855 */
+ 31084, /* A1 = 1.897217 */
+ -32547, /* A2 = -0.993256 */
+ 22713, /* B2 = 0.693176 */
+ -21734, /* B1 = -1.326599 */
+ 22713, /* B0 = 0.693176 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f400_440[]
- 30702, // A1 = 1.873962
- -32134, // A2 = -0.980682
- -517, // B2 = -0.015793
- 0, // B1 = 0
- 517, // B0 = 0.015793
- 30676, // A1 = 1.872375
- -32520, // A2 = -0.992462
- 8144, // B2 = 0.24855
- -7596, // B1 = -0.463684
- 8144, // B0 = 0.24855
- 31084, // A1 = 1.897217
- -32547, // A2 = -0.993256
- 22713, // B2 = 0.693176
- -21734, // B1 = -1.326599
- 22713, // B0 = 0.693176
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f400_450[] */
+ 30613, /* A1 = 1.86853 */
+ -32031, /* A2 = -0.977509 */
+ -618, /* B2 = -0.018866 */
+ 0, /* B1 = 0 */
+ 618, /* B0 = 0.018866 */
+ 30577, /* A1 = 1.866272 */
+ -32491, /* A2 = -0.991577 */
+ 9612, /* B2 = 0.293335 */
+ -8935, /* B1 = -0.54541 */
+ 9612, /* B0 = 0.293335 */
+ 31071, /* A1 = 1.896484 */
+ -32524, /* A2 = -0.992584 */
+ 21596, /* B2 = 0.659058 */
+ -20667, /* B1 = -1.261414 */
+ 21596, /* B0 = 0.659058 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f400_450[]
- 30613, // A1 = 1.86853
- -32031, // A2 = -0.977509
- -618, // B2 = -0.018866
- 0, // B1 = 0
- 618, // B0 = 0.018866
- 30577, // A1 = 1.866272
- -32491, // A2 = -0.991577
- 9612, // B2 = 0.293335
- -8935, // B1 = -0.54541
- 9612, // B0 = 0.293335
- 31071, // A1 = 1.896484
- -32524, // A2 = -0.992584
- 21596, // B2 = 0.659058
- -20667, // B1 = -1.261414
- 21596, // B0 = 0.659058
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f420 */
+ 30914, /* A1 = -1.886841 */
+ -32584, /* A2 = 0.994385 */
+ -426, /* B2 = -0.013020 */
+ 0, /* B1 = 0.000000 */
+ 426, /* B0 = 0.013020 */
+ 30914, /* A1 = -1.886841 */
+ -32679, /* A2 = 0.997314 */
+ 17520, /* B2 = 0.534668 */
+ -16471, /* B1 = -1.005310 */
+ 17520, /* B0 = 0.534668 */
+ 31004, /* A1 = -1.892334 */
+ -32683, /* A2 = 0.997406 */
+ 819, /* B2 = 0.025023 */
+ -780, /* B1 = -0.047619 */
+ 819, /* B0 = 0.025023 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 420.txt
- 30914, // A1 = -1.886841
- -32584, // A2 = 0.994385
- -426, // B2 = -0.013020
- 0, // B1 = 0.000000
- 426, // B0 = 0.013020
- 30914, // A1 = -1.886841
- -32679, // A2 = 0.997314
- 17520, // B2 = 0.534668
- -16471, // B1 = -1.005310
- 17520, // B0 = 0.534668
- 31004, // A1 = -1.892334
- -32683, // A2 = 0.997406
- 819, // B2 = 0.025023
- -780, // B1 = -0.047619
- 819, // B0 = 0.025023
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+#if 0
+ { /* f425 */
+ 30881, /* A1 = -1.884827 */
+ -32603, /* A2 = 0.994965 */
+ -496, /* B2 = -0.015144 */
+ 0, /* B1 = 0.000000 */
+ 496, /* B0 = 0.015144 */
+ 30880, /* A1 = -1.884766 */
+ -32692, /* A2 = 0.997711 */
+ 24767, /* B2 = 0.755859 */
+ -23290, /* B1 = -1.421509 */
+ 24767, /* B0 = 0.755859 */
+ 30967, /* A1 = -1.890076 */
+ -32694, /* A2 = 0.997772 */
+ 728, /* B2 = 0.022232 */
+ -691, /* B1 = -0.042194 */
+ 728, /* B0 = 0.022232 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 425.txt
- 30881, // A1 = -1.884827
- -32603, // A2 = 0.994965
- -496, // B2 = -0.015144
- 0, // B1 = 0.000000
- 496, // B0 = 0.015144
- 30880, // A1 = -1.884766
- -32692, // A2 = 0.997711
- 24767, // B2 = 0.755859
- -23290, // B1 = -1.421509
- 24767, // B0 = 0.755859
- 30967, // A1 = -1.890076
- -32694, // A2 = 0.997772
- 728, // B2 = 0.022232
- -691, // B1 = -0.042194
- 728, // B0 = 0.022232
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+#else
+ {
+ 30850,
+ -32534,
+ -504,
+ 0,
+ 504,
+ 30831,
+ -32669,
+ 24303,
+ -22080,
+ 24303,
+ 30994,
+ -32673,
+ 1905,
+ -1811,
+ 1905,
+ 5,
+ 129,
+ 17,
+ 0xff5
},
- { // f425_450[]
- 30646, // A1 = 1.870544
- -32327, // A2 = -0.986572
- -287, // B2 = -0.008769
- 0, // B1 = 0
- 287, // B0 = 0.008769
- 30627, // A1 = 1.869324
- -32607, // A2 = -0.995087
- 13269, // B2 = 0.404968
- -12376, // B1 = -0.755432
- 13269, // B0 = 0.404968
- 30924, // A1 = 1.887512
- -32619, // A2 = -0.995453
- 19950, // B2 = 0.608826
- -18940, // B1 = -1.156006
- 19950, // B0 = 0.608826
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+#endif
+ { /* f425_450[] */
+ 30646, /* A1 = 1.870544 */
+ -32327, /* A2 = -0.986572 */
+ -287, /* B2 = -0.008769 */
+ 0, /* B1 = 0 */
+ 287, /* B0 = 0.008769 */
+ 30627, /* A1 = 1.869324 */
+ -32607, /* A2 = -0.995087 */
+ 13269, /* B2 = 0.404968 */
+ -12376, /* B1 = -0.755432 */
+ 13269, /* B0 = 0.404968 */
+ 30924, /* A1 = 1.887512 */
+ -32619, /* A2 = -0.995453 */
+ 19950, /* B2 = 0.608826 */
+ -18940, /* B1 = -1.156006 */
+ 19950, /* B0 = 0.608826 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f425_475[]
- 30396, // A1 = 1.855225
- -32014, // A2 = -0.97699
- -395, // B2 = -0.012055
- 0, // B1 = 0
- 395, // B0 = 0.012055
- 30343, // A1 = 1.85199
- -32482, // A2 = -0.991302
- 17823, // B2 = 0.543945
- -16431, // B1 = -1.002869
- 17823, // B0 = 0.543945
- 30872, // A1 = 1.884338
- -32516, // A2 = -0.99231
- 18124, // B2 = 0.553101
- -17246, // B1 = -1.052673
- 18124, // B0 = 0.553101
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f425_475[] */
+ 30396, /* A1 = 1.855225 */
+ -32014, /* A2 = -0.97699 */
+ -395, /* B2 = -0.012055 */
+ 0, /* B1 = 0 */
+ 395, /* B0 = 0.012055 */
+ 30343, /* A1 = 1.85199 */
+ -32482, /* A2 = -0.991302 */
+ 17823, /* B2 = 0.543945 */
+ -16431, /* B1 = -1.002869 */
+ 17823, /* B0 = 0.543945 */
+ 30872, /* A1 = 1.884338 */
+ -32516, /* A2 = -0.99231 */
+ 18124, /* B2 = 0.553101 */
+ -17246, /* B1 = -1.052673 */
+ 18124, /* B0 = 0.553101 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 435.txt
- 30796, // A1 = -1.879639
- -32603, // A2 = 0.994965
- -254, // B2 = -0.007762
- 0, // B1 = 0.000000
- 254, // B0 = 0.007762
- 30793, // A1 = -1.879456
- -32692, // A2 = 0.997711
- 18934, // B2 = 0.577820
- -17751, // B1 = -1.083496
- 18934, // B0 = 0.577820
- 30882, // A1 = -1.884888
- -32694, // A2 = 0.997772
- 1858, // B2 = 0.056713
- -1758, // B1 = -0.107357
- 1858, // B0 = 0.056713
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f435 */
+ 30796, /* A1 = -1.879639 */
+ -32603, /* A2 = 0.994965 */
+ -254, /* B2 = -0.007762 */
+ 0, /* B1 = 0.000000 */
+ 254, /* B0 = 0.007762 */
+ 30793, /* A1 = -1.879456 */
+ -32692, /* A2 = 0.997711 */
+ 18934, /* B2 = 0.577820 */
+ -17751, /* B1 = -1.083496 */
+ 18934, /* B0 = 0.577820 */
+ 30882, /* A1 = -1.884888 */
+ -32694, /* A2 = 0.997772 */
+ 1858, /* B2 = 0.056713 */
+ -1758, /* B1 = -0.107357 */
+ 1858, /* B0 = 0.056713 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f440_450[]
- 30641, // A1 = 1.870239
- -32458, // A2 = -0.99057
- -155, // B2 = -0.004735
- 0, // B1 = 0
- 155, // B0 = 0.004735
- 30631, // A1 = 1.869568
- -32630, // A2 = -0.995789
- 11453, // B2 = 0.349548
- -10666, // B1 = -0.651001
- 11453, // B0 = 0.349548
- 30810, // A1 = 1.880554
- -32634, // A2 = -0.995941
- 12237, // B2 = 0.373474
- -11588, // B1 = -0.707336
- 12237, // B0 = 0.373474
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f440_450[] */
+ 30641, /* A1 = 1.870239 */
+ -32458, /* A2 = -0.99057 */
+ -155, /* B2 = -0.004735 */
+ 0, /* B1 = 0 */
+ 155, /* B0 = 0.004735 */
+ 30631, /* A1 = 1.869568 */
+ -32630, /* A2 = -0.995789 */
+ 11453, /* B2 = 0.349548 */
+ -10666, /* B1 = -0.651001 */
+ 11453, /* B0 = 0.349548 */
+ 30810, /* A1 = 1.880554 */
+ -32634, /* A2 = -0.995941 */
+ 12237, /* B2 = 0.373474 */
+ -11588, /* B1 = -0.707336 */
+ 12237, /* B0 = 0.373474 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f440_480[]
- 30367, // A1 = 1.853455
- -32147, // A2 = -0.981079
- -495, // B2 = -0.015113
- 0, // B1 = 0
- 495, // B0 = 0.015113
- 30322, // A1 = 1.850769
- -32543, // A2 = -0.993134
- 10031, // B2 = 0.306152
- -9252, // B1 = -0.564728
- 10031, // B0 = 0.306152
- 30770, // A1 = 1.878052
- -32563, // A2 = -0.993774
- 22674, // B2 = 0.691956
- -21465, // B1 = -1.31012
- 22674, // B0 = 0.691956
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f440_480[] */
+ 30367, /* A1 = 1.853455 */
+ -32147, /* A2 = -0.981079 */
+ -495, /* B2 = -0.015113 */
+ 0, /* B1 = 0 */
+ 495, /* B0 = 0.015113 */
+ 30322, /* A1 = 1.850769 */
+ -32543, /* A2 = -0.993134 */
+ 10031, /* B2 = 0.306152 */
+ -9252, /* B1 = -0.564728 */
+ 10031, /* B0 = 0.306152 */
+ 30770, /* A1 = 1.878052 */
+ -32563, /* A2 = -0.993774 */
+ 22674, /* B2 = 0.691956 */
+ -21465, /* B1 = -1.31012 */
+ 22674, /* B0 = 0.691956 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 445.txt
- 30709, // A1 = -1.874329
- -32603, // A2 = 0.994965
- -83, // B2 = -0.002545
- 0, // B1 = 0.000000
- 83, // B0 = 0.002545
- 30704, // A1 = -1.874084
- -32692, // A2 = 0.997711
- 10641, // B2 = 0.324738
- -9947, // B1 = -0.607147
- 10641, // B0 = 0.324738
- 30796, // A1 = -1.879639
- -32694, // A2 = 0.997772
- 10079, // B2 = 0.307587
- 9513, // B1 = 0.580688
- 10079, // B0 = 0.307587
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f445 */
+ 30709, /* A1 = -1.874329 */
+ -32603, /* A2 = 0.994965 */
+ -83, /* B2 = -0.002545 */
+ 0, /* B1 = 0.000000 */
+ 83, /* B0 = 0.002545 */
+ 30704, /* A1 = -1.874084 */
+ -32692, /* A2 = 0.997711 */
+ 10641, /* B2 = 0.324738 */
+ -9947, /* B1 = -0.607147 */
+ 10641, /* B0 = 0.324738 */
+ 30796, /* A1 = -1.879639 */
+ -32694, /* A2 = 0.997772 */
+ 10079, /* B2 = 0.307587 */
+ 9513, /* B1 = 0.580688 */
+ 10079, /* B0 = 0.307587 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 450.txt
- 30664, // A1 = -1.871643
- -32603, // A2 = 0.994965
- -164, // B2 = -0.005029
- 0, // B1 = 0.000000
- 164, // B0 = 0.005029
- 30661, // A1 = -1.871399
- -32692, // A2 = 0.997711
- 15294, // B2 = 0.466736
- -14275, // B1 = -0.871307
- 15294, // B0 = 0.466736
- 30751, // A1 = -1.876953
- -32694, // A2 = 0.997772
- 3548, // B2 = 0.108284
- -3344, // B1 = -0.204155
- 3548, // B0 = 0.108284
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f450 */
+ 30664, /* A1 = -1.871643 */
+ -32603, /* A2 = 0.994965 */
+ -164, /* B2 = -0.005029 */
+ 0, /* B1 = 0.000000 */
+ 164, /* B0 = 0.005029 */
+ 30661, /* A1 = -1.871399 */
+ -32692, /* A2 = 0.997711 */
+ 15294, /* B2 = 0.466736 */
+ -14275, /* B1 = -0.871307 */
+ 15294, /* B0 = 0.466736 */
+ 30751, /* A1 = -1.876953 */
+ -32694, /* A2 = 0.997772 */
+ 3548, /* B2 = 0.108284 */
+ -3344, /* B1 = -0.204155 */
+ 3548, /* B0 = 0.108284 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 452.txt
- 30653, // A1 = -1.870911
- -32615, // A2 = 0.995361
- -209, // B2 = -0.006382
- 0, // B1 = 0.000000
- 209, // B0 = 0.006382
- 30647, // A1 = -1.870605
- -32702, // A2 = 0.997986
- 18971, // B2 = 0.578979
- -17716, // B1 = -1.081299
- 18971, // B0 = 0.578979
- 30738, // A1 = -1.876099
- -32702, // A2 = 0.998016
- 2967, // B2 = 0.090561
- -2793, // B1 = -0.170502
- 2967, // B0 = 0.090561
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f452 */
+ 30653, /* A1 = -1.870911 */
+ -32615, /* A2 = 0.995361 */
+ -209, /* B2 = -0.006382 */
+ 0, /* B1 = 0.000000 */
+ 209, /* B0 = 0.006382 */
+ 30647, /* A1 = -1.870605 */
+ -32702, /* A2 = 0.997986 */
+ 18971, /* B2 = 0.578979 */
+ -17716, /* B1 = -1.081299 */
+ 18971, /* B0 = 0.578979 */
+ 30738, /* A1 = -1.876099 */
+ -32702, /* A2 = 0.998016 */
+ 2967, /* B2 = 0.090561 */
+ -2793, /* B1 = -0.170502 */
+ 2967, /* B0 = 0.090561 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 475.txt
- 30437, // A1 = -1.857727
- -32603, // A2 = 0.994965
- -264, // B2 = -0.008062
- 0, // B1 = 0.000000
- 264, // B0 = 0.008062
- 30430, // A1 = -1.857300
- -32692, // A2 = 0.997711
- 21681, // B2 = 0.661682
- -20082, // B1 = -1.225708
- 21681, // B0 = 0.661682
- 30526, // A1 = -1.863220
- -32694, // A2 = 0.997742
- 1559, // B2 = 0.047600
- -1459, // B1 = -0.089096
- 1559, // B0 = 0.047600
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f475 */
+ 30437, /* A1 = -1.857727 */
+ -32603, /* A2 = 0.994965 */
+ -264, /* B2 = -0.008062 */
+ 0, /* B1 = 0.000000 */
+ 264, /* B0 = 0.008062 */
+ 30430, /* A1 = -1.857300 */
+ -32692, /* A2 = 0.997711 */
+ 21681, /* B2 = 0.661682 */
+ -20082, /* B1 = -1.225708 */
+ 21681, /* B0 = 0.661682 */
+ 30526, /* A1 = -1.863220 */
+ -32694, /* A2 = 0.997742 */
+ 1559, /* B2 = 0.047600 */
+ -1459, /* B1 = -0.089096 */
+ 1559, /* B0 = 0.047600 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f480_620[]
- 28975, // A1 = 1.768494
- -30955, // A2 = -0.944672
- -1026, // B2 = -0.03133
- 0, // B1 = 0
- 1026, // B0 = 0.03133
- 28613, // A1 = 1.746399
- -32089, // A2 = -0.979309
- 14214, // B2 = 0.433807
- -12202, // B1 = -0.744812
- 14214, // B0 = 0.433807
- 30243, // A1 = 1.845947
- -32238, // A2 = -0.983856
- 24825, // B2 = 0.757629
- -23402, // B1 = -1.428345
- 24825, // B0 = 0.757629
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f480_620[] */
+ 28975, /* A1 = 1.768494 */
+ -30955, /* A2 = -0.944672 */
+ -1026, /* B2 = -0.03133 */
+ 0, /* B1 = 0 */
+ 1026, /* B0 = 0.03133 */
+ 28613, /* A1 = 1.746399 */
+ -32089, /* A2 = -0.979309 */
+ 14214, /* B2 = 0.433807 */
+ -12202, /* B1 = -0.744812 */
+ 14214, /* B0 = 0.433807 */
+ 30243, /* A1 = 1.845947 */
+ -32238, /* A2 = -0.983856 */
+ 24825, /* B2 = 0.757629 */
+ -23402, /* B1 = -1.428345 */
+ 24825, /* B0 = 0.757629 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 494.txt
- 30257, // A1 = -1.846741
- -32605, // A2 = 0.995056
- -249, // B2 = -0.007625
- 0, // B1 = 0.000000
- 249, // B0 = 0.007625
- 30247, // A1 = -1.846191
- -32694, // A2 = 0.997772
- 18088, // B2 = 0.552002
- -16652, // B1 = -1.016418
- 18088, // B0 = 0.552002
- 30348, // A1 = -1.852295
- -32696, // A2 = 0.997803
- 2099, // B2 = 0.064064
- -1953, // B1 = -0.119202
- 2099, // B0 = 0.064064
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f494 */
+ 30257, /* A1 = -1.846741 */
+ -32605, /* A2 = 0.995056 */
+ -249, /* B2 = -0.007625 */
+ 0, /* B1 = 0.000000 */
+ 249, /* B0 = 0.007625 */
+ 30247, /* A1 = -1.846191 */
+ -32694, /* A2 = 0.997772 */
+ 18088, /* B2 = 0.552002 */
+ -16652, /* B1 = -1.016418 */
+ 18088, /* B0 = 0.552002 */
+ 30348, /* A1 = -1.852295 */
+ -32696, /* A2 = 0.997803 */
+ 2099, /* B2 = 0.064064 */
+ -1953, /* B1 = -0.119202 */
+ 2099, /* B0 = 0.064064 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 500.txt
- 30202, // A1 = -1.843431
- -32624, // A2 = 0.995622
- -413, // B2 = -0.012622
- 0, // B1 = 0.000000
- 413, // B0 = 0.012622
- 30191, // A1 = -1.842721
- -32714, // A2 = 0.998364
- 25954, // B2 = 0.792057
- -23890, // B1 = -1.458131
- 25954, // B0 = 0.792057
- 30296, // A1 = -1.849172
- -32715, // A2 = 0.998397
- 2007, // B2 = 0.061264
- -1860, // B1 = -0.113568
- 2007, // B0 = 0.061264
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f500 */
+ 30202, /* A1 = -1.843431 */
+ -32624, /* A2 = 0.995622 */
+ -413, /* B2 = -0.012622 */
+ 0, /* B1 = 0.000000 */
+ 413, /* B0 = 0.012622 */
+ 30191, /* A1 = -1.842721 */
+ -32714, /* A2 = 0.998364 */
+ 25954, /* B2 = 0.792057 */
+ -23890, /* B1 = -1.458131 */
+ 25954, /* B0 = 0.792057 */
+ 30296, /* A1 = -1.849172 */
+ -32715, /* A2 = 0.998397 */
+ 2007, /* B2 = 0.061264 */
+ -1860, /* B1 = -0.113568 */
+ 2007, /* B0 = 0.061264 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 520.txt
- 30001, // A1 = -1.831116
- -32613, // A2 = 0.995270
- -155, // B2 = -0.004750
- 0, // B1 = 0.000000
- 155, // B0 = 0.004750
- 29985, // A1 = -1.830200
- -32710, // A2 = 0.998260
- 6584, // B2 = 0.200928
- -6018, // B1 = -0.367355
- 6584, // B0 = 0.200928
- 30105, // A1 = -1.837524
- -32712, // A2 = 0.998291
- 23812, // B2 = 0.726685
- -21936, // B1 = -1.338928
- 23812, // B0 = 0.726685
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f520 */
+ 30001, /* A1 = -1.831116 */
+ -32613, /* A2 = 0.995270 */
+ -155, /* B2 = -0.004750 */
+ 0, /* B1 = 0.000000 */
+ 155, /* B0 = 0.004750 */
+ 29985, /* A1 = -1.830200 */
+ -32710, /* A2 = 0.998260 */
+ 6584, /* B2 = 0.200928 */
+ -6018, /* B1 = -0.367355 */
+ 6584, /* B0 = 0.200928 */
+ 30105, /* A1 = -1.837524 */
+ -32712, /* A2 = 0.998291 */
+ 23812, /* B2 = 0.726685 */
+ -21936, /* B1 = -1.338928 */
+ 23812, /* B0 = 0.726685 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 523.txt
- 29964, // A1 = -1.828918
- -32601, // A2 = 0.994904
- -101, // B2 = -0.003110
- 0, // B1 = 0.000000
- 101, // B0 = 0.003110
- 29949, // A1 = -1.827942
- -32700, // A2 = 0.997925
- 11041, // B2 = 0.336975
- -10075, // B1 = -0.614960
- 11041, // B0 = 0.336975
- 30070, // A1 = -1.835388
- -32702, // A2 = 0.997986
- 16762, // B2 = 0.511536
- -15437, // B1 = -0.942230
- 16762, // B0 = 0.511536
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f523 */
+ 29964, /* A1 = -1.828918 */
+ -32601, /* A2 = 0.994904 */
+ -101, /* B2 = -0.003110 */
+ 0, /* B1 = 0.000000 */
+ 101, /* B0 = 0.003110 */
+ 29949, /* A1 = -1.827942 */
+ -32700, /* A2 = 0.997925 */
+ 11041, /* B2 = 0.336975 */
+ -10075, /* B1 = -0.614960 */
+ 11041, /* B0 = 0.336975 */
+ 30070, /* A1 = -1.835388 */
+ -32702, /* A2 = 0.997986 */
+ 16762, /* B2 = 0.511536 */
+ -15437, /* B1 = -0.942230 */
+ 16762, /* B0 = 0.511536 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 525.txt
- 29936, // A1 = -1.827209
- -32584, // A2 = 0.994415
- -91, // B2 = -0.002806
- 0, // B1 = 0.000000
- 91, // B0 = 0.002806
- 29921, // A1 = -1.826233
- -32688, // A2 = 0.997559
- 11449, // B2 = 0.349396
- -10426, // B1 = -0.636383
- 11449, // B0 = 0.349396
- 30045, // A1 = -1.833862
- -32688, // A2 = 0.997589
- 13055, // B2 = 0.398407
- -12028, // B1 = -0.734161
- 13055, // B0 = 0.398407
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f525 */
+ 29936, /* A1 = -1.827209 */
+ -32584, /* A2 = 0.994415 */
+ -91, /* B2 = -0.002806 */
+ 0, /* B1 = 0.000000 */
+ 91, /* B0 = 0.002806 */
+ 29921, /* A1 = -1.826233 */
+ -32688, /* A2 = 0.997559 */
+ 11449, /* B2 = 0.349396 */
+ -10426, /* B1 = -0.636383 */
+ 11449, /* B0 = 0.349396 */
+ 30045, /* A1 = -1.833862 */
+ -32688, /* A2 = 0.997589 */
+ 13055, /* B2 = 0.398407 */
+ -12028, /* B1 = -0.734161 */
+ 13055, /* B0 = 0.398407 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f540_660[]
- 28499, // A1 = 1.739441
- -31129, // A2 = -0.949982
- -849, // B2 = -0.025922
- 0, // B1 = 0
- 849, // B0 = 0.025922
- 28128, // A1 = 1.716797
- -32130, // A2 = -0.98056
- 14556, // B2 = 0.444214
- -12251, // B1 = -0.747772
- 14556, // B0 = 0.444244
- 29667, // A1 = 1.81073
- -32244, // A2 = -0.984039
- 23038, // B2 = 0.703064
- -21358, // B1 = -1.303589
- 23040, // B0 = 0.703125
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f540_660[] */
+ 28499, /* A1 = 1.739441 */
+ -31129, /* A2 = -0.949982 */
+ -849, /* B2 = -0.025922 */
+ 0, /* B1 = 0 */
+ 849, /* B0 = 0.025922 */
+ 28128, /* A1 = 1.716797 */
+ -32130, /* A2 = -0.98056 */
+ 14556, /* B2 = 0.444214 */
+ -12251, /* B1 = -0.747772 */
+ 14556, /* B0 = 0.444244 */
+ 29667, /* A1 = 1.81073 */
+ -32244, /* A2 = -0.984039 */
+ 23038, /* B2 = 0.703064 */
+ -21358, /* B1 = -1.303589 */
+ 23040, /* B0 = 0.703125 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 587.txt
- 29271, // A1 = -1.786560
- -32599, // A2 = 0.994873
- -490, // B2 = -0.014957
- 0, // B1 = 0.000000
- 490, // B0 = 0.014957
- 29246, // A1 = -1.785095
- -32700, // A2 = 0.997925
- 28961, // B2 = 0.883850
- -25796, // B1 = -1.574463
- 28961, // B0 = 0.883850
- 29383, // A1 = -1.793396
- -32700, // A2 = 0.997955
- 1299, // B2 = 0.039650
- -1169, // B1 = -0.071396
- 1299, // B0 = 0.039650
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f587 */
+ 29271, /* A1 = -1.786560 */
+ -32599, /* A2 = 0.994873 */
+ -490, /* B2 = -0.014957 */
+ 0, /* B1 = 0.000000 */
+ 490, /* B0 = 0.014957 */
+ 29246, /* A1 = -1.785095 */
+ -32700, /* A2 = 0.997925 */
+ 28961, /* B2 = 0.883850 */
+ -25796, /* B1 = -1.574463 */
+ 28961, /* B0 = 0.883850 */
+ 29383, /* A1 = -1.793396 */
+ -32700, /* A2 = 0.997955 */
+ 1299, /* B2 = 0.039650 */
+ -1169, /* B1 = -0.071396 */
+ 1299, /* B0 = 0.039650 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 590.txt
- 29230, // A1 = -1.784058
- -32584, // A2 = 0.994415
- -418, // B2 = -0.012757
- 0, // B1 = 0.000000
- 418, // B0 = 0.012757
- 29206, // A1 = -1.782593
- -32688, // A2 = 0.997559
- 36556, // B2 = 1.115601
- -32478, // B1 = -1.982300
- 36556, // B0 = 1.115601
- 29345, // A1 = -1.791077
- -32688, // A2 = 0.997589
- 897, // B2 = 0.027397
- -808, // B1 = -0.049334
- 897, // B0 = 0.027397
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f590 */
+ 29230, /* A1 = -1.784058 */
+ -32584, /* A2 = 0.994415 */
+ -418, /* B2 = -0.012757 */
+ 0, /* B1 = 0.000000 */
+ 418, /* B0 = 0.012757 */
+ 29206, /* A1 = -1.782593 */
+ -32688, /* A2 = 0.997559 */
+ 36556, /* B2 = 1.115601 */
+ -32478, /* B1 = -1.982300 */
+ 36556, /* B0 = 1.115601 */
+ 29345, /* A1 = -1.791077 */
+ -32688, /* A2 = 0.997589 */
+ 897, /* B2 = 0.027397 */
+ -808, /* B1 = -0.049334 */
+ 897, /* B0 = 0.027397 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 600.txt
- 29116, // A1 = -1.777100
- -32603, // A2 = 0.994965
- -165, // B2 = -0.005039
- 0, // B1 = 0.000000
- 165, // B0 = 0.005039
- 29089, // A1 = -1.775452
- -32708, // A2 = 0.998199
- 6963, // B2 = 0.212494
- -6172, // B1 = -0.376770
- 6963, // B0 = 0.212494
- 29237, // A1 = -1.784485
- -32710, // A2 = 0.998230
- 24197, // B2 = 0.738464
- -21657, // B1 = -1.321899
- 24197, // B0 = 0.738464
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f600 */
+ 29116, /* A1 = -1.777100 */
+ -32603, /* A2 = 0.994965 */
+ -165, /* B2 = -0.005039 */
+ 0, /* B1 = 0.000000 */
+ 165, /* B0 = 0.005039 */
+ 29089, /* A1 = -1.775452 */
+ -32708, /* A2 = 0.998199 */
+ 6963, /* B2 = 0.212494 */
+ -6172, /* B1 = -0.376770 */
+ 6963, /* B0 = 0.212494 */
+ 29237, /* A1 = -1.784485 */
+ -32710, /* A2 = 0.998230 */
+ 24197, /* B2 = 0.738464 */
+ -21657, /* B1 = -1.321899 */
+ 24197, /* B0 = 0.738464 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 660.txt
- 28376, // A1 = -1.731934
- -32567, // A2 = 0.993896
- -363, // B2 = -0.011102
- 0, // B1 = 0.000000
- 363, // B0 = 0.011102
- 28337, // A1 = -1.729614
- -32683, // A2 = 0.997434
- 21766, // B2 = 0.664246
- -18761, // B1 = -1.145081
- 21766, // B0 = 0.664246
- 28513, // A1 = -1.740356
- -32686, // A2 = 0.997498
- 2509, // B2 = 0.076584
- -2196, // B1 = -0.134041
- 2509, // B0 = 0.076584
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f660 */
+ 28376, /* A1 = -1.731934 */
+ -32567, /* A2 = 0.993896 */
+ -363, /* B2 = -0.011102 */
+ 0, /* B1 = 0.000000 */
+ 363, /* B0 = 0.011102 */
+ 28337, /* A1 = -1.729614 */
+ -32683, /* A2 = 0.997434 */
+ 21766, /* B2 = 0.664246 */
+ -18761, /* B1 = -1.145081 */
+ 21766, /* B0 = 0.664246 */
+ 28513, /* A1 = -1.740356 */
+ -32686, /* A2 = 0.997498 */
+ 2509, /* B2 = 0.076584 */
+ -2196, /* B1 = -0.134041 */
+ 2509, /* B0 = 0.076584 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 700.txt
- 27844, // A1 = -1.699463
- -32563, // A2 = 0.993744
- -366, // B2 = -0.011187
- 0, // B1 = 0.000000
- 366, // B0 = 0.011187
- 27797, // A1 = -1.696655
- -32686, // A2 = 0.997498
- 22748, // B2 = 0.694214
- -19235, // B1 = -1.174072
- 22748, // B0 = 0.694214
- 27995, // A1 = -1.708740
- -32688, // A2 = 0.997559
- 2964, // B2 = 0.090477
- -2546, // B1 = -0.155449
- 2964, // B0 = 0.090477
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f700 */
+ 27844, /* A1 = -1.699463 */
+ -32563, /* A2 = 0.993744 */
+ -366, /* B2 = -0.011187 */
+ 0, /* B1 = 0.000000 */
+ 366, /* B0 = 0.011187 */
+ 27797, /* A1 = -1.696655 */
+ -32686, /* A2 = 0.997498 */
+ 22748, /* B2 = 0.694214 */
+ -19235, /* B1 = -1.174072 */
+ 22748, /* B0 = 0.694214 */
+ 27995, /* A1 = -1.708740 */
+ -32688, /* A2 = 0.997559 */
+ 2964, /* B2 = 0.090477 */
+ -2546, /* B1 = -0.155449 */
+ 2964, /* B0 = 0.090477 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 740.txt
- 27297, // A1 = -1.666077
- -32551, // A2 = 0.993408
- -345, // B2 = -0.010540
- 0, // B1 = 0.000000
- 345, // B0 = 0.010540
- 27240, // A1 = -1.662598
- -32683, // A2 = 0.997406
- 22560, // B2 = 0.688477
- -18688, // B1 = -1.140625
- 22560, // B0 = 0.688477
- 27461, // A1 = -1.676147
- -32684, // A2 = 0.997467
- 3541, // B2 = 0.108086
- -2985, // B1 = -0.182220
- 3541, // B0 = 0.108086
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f740 */
+ 27297, /* A1 = -1.666077 */
+ -32551, /* A2 = 0.993408 */
+ -345, /* B2 = -0.010540 */
+ 0, /* B1 = 0.000000 */
+ 345, /* B0 = 0.010540 */
+ 27240, /* A1 = -1.662598 */
+ -32683, /* A2 = 0.997406 */
+ 22560, /* B2 = 0.688477 */
+ -18688, /* B1 = -1.140625 */
+ 22560, /* B0 = 0.688477 */
+ 27461, /* A1 = -1.676147 */
+ -32684, /* A2 = 0.997467 */
+ 3541, /* B2 = 0.108086 */
+ -2985, /* B1 = -0.182220 */
+ 3541, /* B0 = 0.108086 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 750.txt
- 27155, // A1 = -1.657410
- -32551, // A2 = 0.993408
- -462, // B2 = -0.014117
- 0, // B1 = 0.000000
- 462, // B0 = 0.014117
- 27097, // A1 = -1.653870
- -32683, // A2 = 0.997406
- 32495, // B2 = 0.991699
- -26776, // B1 = -1.634338
- 32495, // B0 = 0.991699
- 27321, // A1 = -1.667542
- -32684, // A2 = 0.997467
- 1835, // B2 = 0.056007
- -1539, // B1 = -0.093948
- 1835, // B0 = 0.056007
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f750 */
+ 27155, /* A1 = -1.657410 */
+ -32551, /* A2 = 0.993408 */
+ -462, /* B2 = -0.014117 */
+ 0, /* B1 = 0.000000 */
+ 462, /* B0 = 0.014117 */
+ 27097, /* A1 = -1.653870 */
+ -32683, /* A2 = 0.997406 */
+ 32495, /* B2 = 0.991699 */
+ -26776, /* B1 = -1.634338 */
+ 32495, /* B0 = 0.991699 */
+ 27321, /* A1 = -1.667542 */
+ -32684, /* A2 = 0.997467 */
+ 1835, /* B2 = 0.056007 */
+ -1539, /* B1 = -0.093948 */
+ 1835, /* B0 = 0.056007 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f750_1450[]
- 19298, // A1 = 1.177917
- -24471, // A2 = -0.746796
- -4152, // B2 = -0.126709
- 0, // B1 = 0
- 4152, // B0 = 0.126709
- 12902, // A1 = 0.787476
- -29091, // A2 = -0.887817
- 12491, // B2 = 0.38121
- -1794, // B1 = -0.109528
- 12494, // B0 = 0.381317
- 26291, // A1 = 1.604736
- -30470, // A2 = -0.929901
- 28859, // B2 = 0.880737
- -26084, // B1 = -1.592102
- 28861, // B0 = 0.880798
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f750_1450[] */
+ 19298, /* A1 = 1.177917 */
+ -24471, /* A2 = -0.746796 */
+ -4152, /* B2 = -0.126709 */
+ 0, /* B1 = 0 */
+ 4152, /* B0 = 0.126709 */
+ 12902, /* A1 = 0.787476 */
+ -29091, /* A2 = -0.887817 */
+ 12491, /* B2 = 0.38121 */
+ -1794, /* B1 = -0.109528 */
+ 12494, /* B0 = 0.381317 */
+ 26291, /* A1 = 1.604736 */
+ -30470, /* A2 = -0.929901 */
+ 28859, /* B2 = 0.880737 */
+ -26084, /* B1 = -1.592102 */
+ 28861, /* B0 = 0.880798 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 770.txt
- 26867, // A1 = -1.639832
- -32551, // A2 = 0.993408
- -123, // B2 = -0.003755
- 0, // B1 = 0.000000
- 123, // B0 = 0.003755
- 26805, // A1 = -1.636108
- -32683, // A2 = 0.997406
- 17297, // B2 = 0.527863
- -14096, // B1 = -0.860382
- 17297, // B0 = 0.527863
- 27034, // A1 = -1.650085
- -32684, // A2 = 0.997467
- 12958, // B2 = 0.395477
- -10756, // B1 = -0.656525
- 12958, // B0 = 0.395477
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f770 */
+ 26867, /* A1 = -1.639832 */
+ -32551, /* A2 = 0.993408 */
+ -123, /* B2 = -0.003755 */
+ 0, /* B1 = 0.000000 */
+ 123, /* B0 = 0.003755 */
+ 26805, /* A1 = -1.636108 */
+ -32683, /* A2 = 0.997406 */
+ 17297, /* B2 = 0.527863 */
+ -14096, /* B1 = -0.860382 */
+ 17297, /* B0 = 0.527863 */
+ 27034, /* A1 = -1.650085 */
+ -32684, /* A2 = 0.997467 */
+ 12958, /* B2 = 0.395477 */
+ -10756, /* B1 = -0.656525 */
+ 12958, /* B0 = 0.395477 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 800.txt
- 26413, // A1 = -1.612122
- -32547, // A2 = 0.993286
- -223, // B2 = -0.006825
- 0, // B1 = 0.000000
- 223, // B0 = 0.006825
- 26342, // A1 = -1.607849
- -32686, // A2 = 0.997498
- 6391, // B2 = 0.195053
- -5120, // B1 = -0.312531
- 6391, // B0 = 0.195053
- 26593, // A1 = -1.623108
- -32688, // A2 = 0.997559
- 23681, // B2 = 0.722717
- -19328, // B1 = -1.179688
- 23681, // B0 = 0.722717
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f800 */
+ 26413, /* A1 = -1.612122 */
+ -32547, /* A2 = 0.993286 */
+ -223, /* B2 = -0.006825 */
+ 0, /* B1 = 0.000000 */
+ 223, /* B0 = 0.006825 */
+ 26342, /* A1 = -1.607849 */
+ -32686, /* A2 = 0.997498 */
+ 6391, /* B2 = 0.195053 */
+ -5120, /* B1 = -0.312531 */
+ 6391, /* B0 = 0.195053 */
+ 26593, /* A1 = -1.623108 */
+ -32688, /* A2 = 0.997559 */
+ 23681, /* B2 = 0.722717 */
+ -19328, /* B1 = -1.179688 */
+ 23681, /* B0 = 0.722717 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 816.txt
- 26168, // A1 = -1.597209
- -32528, // A2 = 0.992706
- -235, // B2 = -0.007182
- 0, // B1 = 0.000000
- 235, // B0 = 0.007182
- 26092, // A1 = -1.592590
- -32675, // A2 = 0.997192
- 20823, // B2 = 0.635498
- -16510, // B1 = -1.007751
- 20823, // B0 = 0.635498
- 26363, // A1 = -1.609070
- -32677, // A2 = 0.997253
- 6739, // B2 = 0.205688
- -5459, // B1 = -0.333206
- 6739, // B0 = 0.205688
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f816 */
+ 26168, /* A1 = -1.597209 */
+ -32528, /* A2 = 0.992706 */
+ -235, /* B2 = -0.007182 */
+ 0, /* B1 = 0.000000 */
+ 235, /* B0 = 0.007182 */
+ 26092, /* A1 = -1.592590 */
+ -32675, /* A2 = 0.997192 */
+ 20823, /* B2 = 0.635498 */
+ -16510, /* B1 = -1.007751 */
+ 20823, /* B0 = 0.635498 */
+ 26363, /* A1 = -1.609070 */
+ -32677, /* A2 = 0.997253 */
+ 6739, /* B2 = 0.205688 */
+ -5459, /* B1 = -0.333206 */
+ 6739, /* B0 = 0.205688 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 850.txt
- 25641, // A1 = -1.565063
- -32536, // A2 = 0.992950
- -121, // B2 = -0.003707
- 0, // B1 = 0.000000
- 121, // B0 = 0.003707
- 25560, // A1 = -1.560059
- -32684, // A2 = 0.997437
- 18341, // B2 = 0.559753
- -14252, // B1 = -0.869904
- 18341, // B0 = 0.559753
- 25837, // A1 = -1.577026
- -32684, // A2 = 0.997467
- 16679, // B2 = 0.509003
- -13232, // B1 = -0.807648
- 16679, // B0 = 0.509003
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f850 */
+ 25641, /* A1 = -1.565063 */
+ -32536, /* A2 = 0.992950 */
+ -121, /* B2 = -0.003707 */
+ 0, /* B1 = 0.000000 */
+ 121, /* B0 = 0.003707 */
+ 25560, /* A1 = -1.560059 */
+ -32684, /* A2 = 0.997437 */
+ 18341, /* B2 = 0.559753 */
+ -14252, /* B1 = -0.869904 */
+ 18341, /* B0 = 0.559753 */
+ 25837, /* A1 = -1.577026 */
+ -32684, /* A2 = 0.997467 */
+ 16679, /* B2 = 0.509003 */
+ -13232, /* B1 = -0.807648 */
+ 16679, /* B0 = 0.509003 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f857_1645[]
- 16415, // A1 = 1.001953
- -23669, // A2 = -0.722321
- -4549, // B2 = -0.138847
- 0, // B1 = 0
- 4549, // B0 = 0.138847
- 8456, // A1 = 0.516174
- -28996, // A2 = -0.884918
- 13753, // B2 = 0.419724
- -12, // B1 = -0.000763
- 13757, // B0 = 0.419846
- 24632, // A1 = 1.503418
- -30271, // A2 = -0.923828
- 29070, // B2 = 0.887146
- -25265, // B1 = -1.542114
- 29073, // B0 = 0.887268
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f857_1645[] */
+ 16415, /* A1 = 1.001953 */
+ -23669, /* A2 = -0.722321 */
+ -4549, /* B2 = -0.138847 */
+ 0, /* B1 = 0 */
+ 4549, /* B0 = 0.138847 */
+ 8456, /* A1 = 0.516174 */
+ -28996, /* A2 = -0.884918 */
+ 13753, /* B2 = 0.419724 */
+ -12, /* B1 = -0.000763 */
+ 13757, /* B0 = 0.419846 */
+ 24632, /* A1 = 1.503418 */
+ -30271, /* A2 = -0.923828 */
+ 29070, /* B2 = 0.887146 */
+ -25265, /* B1 = -1.542114 */
+ 29073, /* B0 = 0.887268 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 900.txt
- 24806, // A1 = -1.514099
- -32501, // A2 = 0.991852
- -326, // B2 = -0.009969
- 0, // B1 = 0.000000
- 326, // B0 = 0.009969
- 24709, // A1 = -1.508118
- -32659, // A2 = 0.996674
- 20277, // B2 = 0.618835
- -15182, // B1 = -0.926636
- 20277, // B0 = 0.618835
- 25022, // A1 = -1.527222
- -32661, // A2 = 0.996735
- 4320, // B2 = 0.131836
- -3331, // B1 = -0.203339
- 4320, // B0 = 0.131836
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f900 */
+ 24806, /* A1 = -1.514099 */
+ -32501, /* A2 = 0.991852 */
+ -326, /* B2 = -0.009969 */
+ 0, /* B1 = 0.000000 */
+ 326, /* B0 = 0.009969 */
+ 24709, /* A1 = -1.508118 */
+ -32659, /* A2 = 0.996674 */
+ 20277, /* B2 = 0.618835 */
+ -15182, /* B1 = -0.926636 */
+ 20277, /* B0 = 0.618835 */
+ 25022, /* A1 = -1.527222 */
+ -32661, /* A2 = 0.996735 */
+ 4320, /* B2 = 0.131836 */
+ -3331, /* B1 = -0.203339 */
+ 4320, /* B0 = 0.131836 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f900_1300[]
- 19776, // A1 = 1.207092
- -27437, // A2 = -0.837341
- -2666, // B2 = -0.081371
- 0, // B1 = 0
- 2666, // B0 = 0.081371
- 16302, // A1 = 0.995026
- -30354, // A2 = -0.926361
- 10389, // B2 = 0.317062
- -3327, // B1 = -0.203064
- 10389, // B0 = 0.317062
- 24299, // A1 = 1.483154
- -30930, // A2 = -0.943909
- 25016, // B2 = 0.763428
- -21171, // B1 = -1.292236
- 25016, // B0 = 0.763428
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f900_1300[] */
+ 19776, /* A1 = 1.207092 */
+ -27437, /* A2 = -0.837341 */
+ -2666, /* B2 = -0.081371 */
+ 0, /* B1 = 0 */
+ 2666, /* B0 = 0.081371 */
+ 16302, /* A1 = 0.995026 */
+ -30354, /* A2 = -0.926361 */
+ 10389, /* B2 = 0.317062 */
+ -3327, /* B1 = -0.203064 */
+ 10389, /* B0 = 0.317062 */
+ 24299, /* A1 = 1.483154 */
+ -30930, /* A2 = -0.943909 */
+ 25016, /* B2 = 0.763428 */
+ -21171, /* B1 = -1.292236 */
+ 25016, /* B0 = 0.763428 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f935_1215[]
- 20554, // A1 = 1.254517
- -28764, // A2 = -0.877838
- -2048, // B2 = -0.062515
- 0, // B1 = 0
- 2048, // B0 = 0.062515
- 18209, // A1 = 1.11145
- -30951, // A2 = -0.94458
- 9390, // B2 = 0.286575
- -3955, // B1 = -0.241455
- 9390, // B0 = 0.286575
- 23902, // A1 = 1.458923
- -31286, // A2 = -0.954803
- 23252, // B2 = 0.709595
- -19132, // B1 = -1.167725
- 23252, // B0 = 0.709595
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f935_1215[] */
+ 20554, /* A1 = 1.254517 */
+ -28764, /* A2 = -0.877838 */
+ -2048, /* B2 = -0.062515 */
+ 0, /* B1 = 0 */
+ 2048, /* B0 = 0.062515 */
+ 18209, /* A1 = 1.11145 */
+ -30951, /* A2 = -0.94458 */
+ 9390, /* B2 = 0.286575 */
+ -3955, /* B1 = -0.241455 */
+ 9390, /* B0 = 0.286575 */
+ 23902, /* A1 = 1.458923 */
+ -31286, /* A2 = -0.954803 */
+ 23252, /* B2 = 0.709595 */
+ -19132, /* B1 = -1.167725 */
+ 23252, /* B0 = 0.709595 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f941_1477[]
- 17543, // A1 = 1.07074
- -26220, // A2 = -0.800201
- -3298, // B2 = -0.100647
- 0, // B1 = 0
- 3298, // B0 = 0.100647
- 12423, // A1 = 0.75827
- -30036, // A2 = -0.916626
- 12651, // B2 = 0.386078
- -2444, // B1 = -0.14917
- 12653, // B0 = 0.386154
- 23518, // A1 = 1.435425
- -30745, // A2 = -0.938293
- 27282, // B2 = 0.832581
- -22529, // B1 = -1.375122
- 27286, // B0 = 0.832703
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f941_1477[] */
+ 17543, /* A1 = 1.07074 */
+ -26220, /* A2 = -0.800201 */
+ -3298, /* B2 = -0.100647 */
+ 0, /* B1 = 0 */
+ 3298, /* B0 = 0.100647 */
+ 12423, /* A1 = 0.75827 */
+ -30036, /* A2 = -0.916626 */
+ 12651, /* B2 = 0.386078 */
+ -2444, /* B1 = -0.14917 */
+ 12653, /* B0 = 0.386154 */
+ 23518, /* A1 = 1.435425 */
+ -30745, /* A2 = -0.938293 */
+ 27282, /* B2 = 0.832581 */
+ -22529, /* B1 = -1.375122 */
+ 27286, /* B0 = 0.832703 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 942.txt
- 24104, // A1 = -1.471252
- -32507, // A2 = 0.992065
- -351, // B2 = -0.010722
- 0, // B1 = 0.000000
- 351, // B0 = 0.010722
- 23996, // A1 = -1.464600
- -32671, // A2 = 0.997040
- 22848, // B2 = 0.697266
- -16639, // B1 = -1.015564
- 22848, // B0 = 0.697266
- 24332, // A1 = -1.485168
- -32673, // A2 = 0.997101
- 4906, // B2 = 0.149727
- -3672, // B1 = -0.224174
- 4906, // B0 = 0.149727
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f942 */
+ 24104, /* A1 = -1.471252 */
+ -32507, /* A2 = 0.992065 */
+ -351, /* B2 = -0.010722 */
+ 0, /* B1 = 0.000000 */
+ 351, /* B0 = 0.010722 */
+ 23996, /* A1 = -1.464600 */
+ -32671, /* A2 = 0.997040 */
+ 22848, /* B2 = 0.697266 */
+ -16639, /* B1 = -1.015564 */
+ 22848, /* B0 = 0.697266 */
+ 24332, /* A1 = -1.485168 */
+ -32673, /* A2 = 0.997101 */
+ 4906, /* B2 = 0.149727 */
+ -3672, /* B1 = -0.224174 */
+ 4906, /* B0 = 0.149727 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 950.txt
- 23967, // A1 = -1.462830
- -32507, // A2 = 0.992065
- -518, // B2 = -0.015821
- 0, // B1 = 0.000000
- 518, // B0 = 0.015821
- 23856, // A1 = -1.456055
- -32671, // A2 = 0.997040
- 26287, // B2 = 0.802246
- -19031, // B1 = -1.161560
- 26287, // B0 = 0.802246
- 24195, // A1 = -1.476746
- -32673, // A2 = 0.997101
- 2890, // B2 = 0.088196
- -2151, // B1 = -0.131317
- 2890, // B0 = 0.088196
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f950 */
+ 23967, /* A1 = -1.462830 */
+ -32507, /* A2 = 0.992065 */
+ -518, /* B2 = -0.015821 */
+ 0, /* B1 = 0.000000 */
+ 518, /* B0 = 0.015821 */
+ 23856, /* A1 = -1.456055 */
+ -32671, /* A2 = 0.997040 */
+ 26287, /* B2 = 0.802246 */
+ -19031, /* B1 = -1.161560 */
+ 26287, /* B0 = 0.802246 */
+ 24195, /* A1 = -1.476746 */
+ -32673, /* A2 = 0.997101 */
+ 2890, /* B2 = 0.088196 */
+ -2151, /* B1 = -0.131317 */
+ 2890, /* B0 = 0.088196 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f950_1400[]
- 18294, // A1 = 1.116638
- -26962, // A2 = -0.822845
- -2914, // B2 = -0.088936
- 0, // B1 = 0
- 2914, // B0 = 0.088936
- 14119, // A1 = 0.861786
- -30227, // A2 = -0.922455
- 11466, // B2 = 0.349945
- -2833, // B1 = -0.172943
- 11466, // B0 = 0.349945
- 23431, // A1 = 1.430115
- -30828, // A2 = -0.940796
- 25331, // B2 = 0.773071
- -20911, // B1 = -1.276367
- 25331, // B0 = 0.773071
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f950_1400[] */
+ 18294, /* A1 = 1.116638 */
+ -26962, /* A2 = -0.822845 */
+ -2914, /* B2 = -0.088936 */
+ 0, /* B1 = 0 */
+ 2914, /* B0 = 0.088936 */
+ 14119, /* A1 = 0.861786 */
+ -30227, /* A2 = -0.922455 */
+ 11466, /* B2 = 0.349945 */
+ -2833, /* B1 = -0.172943 */
+ 11466, /* B0 = 0.349945 */
+ 23431, /* A1 = 1.430115 */
+ -30828, /* A2 = -0.940796 */
+ 25331, /* B2 = 0.773071 */
+ -20911, /* B1 = -1.276367 */
+ 25331, /* B0 = 0.773071 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 975.txt
- 23521, // A1 = -1.435608
- -32489, // A2 = 0.991516
- -193, // B2 = -0.005915
- 0, // B1 = 0.000000
- 193, // B0 = 0.005915
- 23404, // A1 = -1.428467
- -32655, // A2 = 0.996582
- 17740, // B2 = 0.541412
- -12567, // B1 = -0.767029
- 17740, // B0 = 0.541412
- 23753, // A1 = -1.449829
- -32657, // A2 = 0.996613
- 9090, // B2 = 0.277405
- -6662, // B1 = -0.406647
- 9090, // B0 = 0.277405
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f975 */
+ 23521, /* A1 = -1.435608 */
+ -32489, /* A2 = 0.991516 */
+ -193, /* B2 = -0.005915 */
+ 0, /* B1 = 0.000000 */
+ 193, /* B0 = 0.005915 */
+ 23404, /* A1 = -1.428467 */
+ -32655, /* A2 = 0.996582 */
+ 17740, /* B2 = 0.541412 */
+ -12567, /* B1 = -0.767029 */
+ 17740, /* B0 = 0.541412 */
+ 23753, /* A1 = -1.449829 */
+ -32657, /* A2 = 0.996613 */
+ 9090, /* B2 = 0.277405 */
+ -6662, /* B1 = -0.406647 */
+ 9090, /* B0 = 0.277405 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1000.txt
- 23071, // A1 = -1.408203
- -32489, // A2 = 0.991516
- -293, // B2 = -0.008965
- 0, // B1 = 0.000000
- 293, // B0 = 0.008965
- 22951, // A1 = -1.400818
- -32655, // A2 = 0.996582
- 5689, // B2 = 0.173645
- -3951, // B1 = -0.241150
- 5689, // B0 = 0.173645
- 23307, // A1 = -1.422607
- -32657, // A2 = 0.996613
- 18692, // B2 = 0.570435
- -13447, // B1 = -0.820770
- 18692, // B0 = 0.570435
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1000 */
+ 23071, /* A1 = -1.408203 */
+ -32489, /* A2 = 0.991516 */
+ -293, /* B2 = -0.008965 */
+ 0, /* B1 = 0.000000 */
+ 293, /* B0 = 0.008965 */
+ 22951, /* A1 = -1.400818 */
+ -32655, /* A2 = 0.996582 */
+ 5689, /* B2 = 0.173645 */
+ -3951, /* B1 = -0.241150 */
+ 5689, /* B0 = 0.173645 */
+ 23307, /* A1 = -1.422607 */
+ -32657, /* A2 = 0.996613 */
+ 18692, /* B2 = 0.570435 */
+ -13447, /* B1 = -0.820770 */
+ 18692, /* B0 = 0.570435 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1020.txt
- 22701, // A1 = -1.385620
- -32474, // A2 = 0.991058
- -292, // B2 = -0.008933
- 0, //163840 , // B1 = 10.000000
- 292, // B0 = 0.008933
- 22564, // A1 = -1.377258
- -32655, // A2 = 0.996552
- 20756, // B2 = 0.633423
- -14176, // B1 = -0.865295
- 20756, // B0 = 0.633423
- 22960, // A1 = -1.401428
- -32657, // A2 = 0.996613
- 6520, // B2 = 0.198990
- -4619, // B1 = -0.281937
- 6520, // B0 = 0.198990
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1020 */
+ 22701, /* A1 = -1.385620 */
+ -32474, /* A2 = 0.991058 */
+ -292, /* B2 = -0.008933 */
+ 0, /*163840 , B1 = 10.000000 */
+ 292, /* B0 = 0.008933 */
+ 22564, /* A1 = -1.377258 */
+ -32655, /* A2 = 0.996552 */
+ 20756, /* B2 = 0.633423 */
+ -14176, /* B1 = -0.865295 */
+ 20756, /* B0 = 0.633423 */
+ 22960, /* A1 = -1.401428 */
+ -32657, /* A2 = 0.996613 */
+ 6520, /* B2 = 0.198990 */
+ -4619, /* B1 = -0.281937 */
+ 6520, /* B0 = 0.198990 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1050.txt
- 22142, // A1 = -1.351501
- -32474, // A2 = 0.991058
- -147, // B2 = -0.004493
- 0, // B1 = 0.000000
- 147, // B0 = 0.004493
- 22000, // A1 = -1.342834
- -32655, // A2 = 0.996552
- 15379, // B2 = 0.469360
- -10237, // B1 = -0.624847
- 15379, // B0 = 0.469360
- 22406, // A1 = -1.367554
- -32657, // A2 = 0.996613
- 17491, // B2 = 0.533783
- -12096, // B1 = -0.738312
- 17491, // B0 = 0.533783
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1050 */
+ 22142, /* A1 = -1.351501 */
+ -32474, /* A2 = 0.991058 */
+ -147, /* B2 = -0.004493 */
+ 0, /* B1 = 0.000000 */
+ 147, /* B0 = 0.004493 */
+ 22000, /* A1 = -1.342834 */
+ -32655, /* A2 = 0.996552 */
+ 15379, /* B2 = 0.469360 */
+ -10237, /* B1 = -0.624847 */
+ 15379, /* B0 = 0.469360 */
+ 22406, /* A1 = -1.367554 */
+ -32657, /* A2 = 0.996613 */
+ 17491, /* B2 = 0.533783 */
+ -12096, /* B1 = -0.738312 */
+ 17491, /* B0 = 0.533783 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f1100_1750[]
- 12973, // A1 = 0.79184
- -24916, // A2 = -0.760376
- 6655, // B2 = 0.203102
- 367, // B1 = 0.0224
- 6657, // B0 = 0.203171
- 5915, // A1 = 0.361053
- -29560, // A2 = -0.90213
- -7777, // B2 = -0.23735
- 0, // B1 = 0
- 7777, // B0 = 0.23735
- 20510, // A1 = 1.251892
- -30260, // A2 = -0.923462
- 26662, // B2 = 0.81366
- -20573, // B1 = -1.255737
- 26668, // B0 = 0.813843
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1100_1750[] */
+ 12973, /* A1 = 0.79184 */
+ -24916, /* A2 = -0.760376 */
+ 6655, /* B2 = 0.203102 */
+ 367, /* B1 = 0.0224 */
+ 6657, /* B0 = 0.203171 */
+ 5915, /* A1 = 0.361053 */
+ -29560, /* A2 = -0.90213 */
+ -7777, /* B2 = -0.23735 */
+ 0, /* B1 = 0 */
+ 7777, /* B0 = 0.23735 */
+ 20510, /* A1 = 1.251892 */
+ -30260, /* A2 = -0.923462 */
+ 26662, /* B2 = 0.81366 */
+ -20573, /* B1 = -1.255737 */
+ 26668, /* B0 = 0.813843 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1140.txt
- 20392, // A1 = -1.244629
- -32460, // A2 = 0.990601
- -270, // B2 = -0.008240
- 0, // B1 = 0.000000
- 270, // B0 = 0.008240
- 20218, // A1 = -1.234009
- -32655, // A2 = 0.996582
- 21337, // B2 = 0.651154
- -13044, // B1 = -0.796143
- 21337, // B0 = 0.651154
- 20684, // A1 = -1.262512
- -32657, // A2 = 0.996643
- 8572, // B2 = 0.261612
- -5476, // B1 = -0.334244
- 8572, // B0 = 0.261612
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1140 */
+ 20392, /* A1 = -1.244629 */
+ -32460, /* A2 = 0.990601 */
+ -270, /* B2 = -0.008240 */
+ 0, /* B1 = 0.000000 */
+ 270, /* B0 = 0.008240 */
+ 20218, /* A1 = -1.234009 */
+ -32655, /* A2 = 0.996582 */
+ 21337, /* B2 = 0.651154 */
+ -13044, /* B1 = -0.796143 */
+ 21337, /* B0 = 0.651154 */
+ 20684, /* A1 = -1.262512 */
+ -32657, /* A2 = 0.996643 */
+ 8572, /* B2 = 0.261612 */
+ -5476, /* B1 = -0.334244 */
+ 8572, /* B0 = 0.261612 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1200.txt
- 19159, // A1 = -1.169373
- -32456, // A2 = 0.990509
- -335, // B2 = -0.010252
- 0, // B1 = 0.000000
- 335, // B0 = 0.010252
- 18966, // A1 = -1.157593
- -32661, // A2 = 0.996735
- 6802, // B2 = 0.207588
- -3900, // B1 = -0.238098
- 6802, // B0 = 0.207588
- 19467, // A1 = -1.188232
- -32661, // A2 = 0.996765
- 25035, // B2 = 0.764008
- -15049, // B1 = -0.918579
- 25035, // B0 = 0.764008
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1200 */
+ 19159, /* A1 = -1.169373 */
+ -32456, /* A2 = 0.990509 */
+ -335, /* B2 = -0.010252 */
+ 0, /* B1 = 0.000000 */
+ 335, /* B0 = 0.010252 */
+ 18966, /* A1 = -1.157593 */
+ -32661, /* A2 = 0.996735 */
+ 6802, /* B2 = 0.207588 */
+ -3900, /* B1 = -0.238098 */
+ 6802, /* B0 = 0.207588 */
+ 19467, /* A1 = -1.188232 */
+ -32661, /* A2 = 0.996765 */
+ 25035, /* B2 = 0.764008 */
+ -15049, /* B1 = -0.918579 */
+ 25035, /* B0 = 0.764008 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1209.txt
- 18976, // A1 = -1.158264
- -32439, // A2 = 0.989990
- -183, // B2 = -0.005588
- 0, // B1 = 0.000000
- 183, // B0 = 0.005588
- 18774, // A1 = -1.145874
- -32650, // A2 = 0.996429
- 15468, // B2 = 0.472076
- -8768, // B1 = -0.535217
- 15468, // B0 = 0.472076
- 19300, // A1 = -1.177979
- -32652, // A2 = 0.996490
- 19840, // B2 = 0.605499
- -11842, // B1 = -0.722809
- 19840, // B0 = 0.605499
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1209 */
+ 18976, /* A1 = -1.158264 */
+ -32439, /* A2 = 0.989990 */
+ -183, /* B2 = -0.005588 */
+ 0, /* B1 = 0.000000 */
+ 183, /* B0 = 0.005588 */
+ 18774, /* A1 = -1.145874 */
+ -32650, /* A2 = 0.996429 */
+ 15468, /* B2 = 0.472076 */
+ -8768, /* B1 = -0.535217 */
+ 15468, /* B0 = 0.472076 */
+ 19300, /* A1 = -1.177979 */
+ -32652, /* A2 = 0.996490 */
+ 19840, /* B2 = 0.605499 */
+ -11842, /* B1 = -0.722809 */
+ 19840, /* B0 = 0.605499 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1330.txt
- 16357, // A1 = -0.998413
- -32368, // A2 = 0.987793
- -217, // B2 = -0.006652
- 0, // B1 = 0.000000
- 217, // B0 = 0.006652
- 16107, // A1 = -0.983126
- -32601, // A2 = 0.994904
- 11602, // B2 = 0.354065
- -5555, // B1 = -0.339111
- 11602, // B0 = 0.354065
- 16722, // A1 = -1.020630
- -32603, // A2 = 0.994965
- 15574, // B2 = 0.475311
- -8176, // B1 = -0.499069
- 15574, // B0 = 0.475311
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1330 */
+ 16357, /* A1 = -0.998413 */
+ -32368, /* A2 = 0.987793 */
+ -217, /* B2 = -0.006652 */
+ 0, /* B1 = 0.000000 */
+ 217, /* B0 = 0.006652 */
+ 16107, /* A1 = -0.983126 */
+ -32601, /* A2 = 0.994904 */
+ 11602, /* B2 = 0.354065 */
+ -5555, /* B1 = -0.339111 */
+ 11602, /* B0 = 0.354065 */
+ 16722, /* A1 = -1.020630 */
+ -32603, /* A2 = 0.994965 */
+ 15574, /* B2 = 0.475311 */
+ -8176, /* B1 = -0.499069 */
+ 15574, /* B0 = 0.475311 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1336.txt
- 16234, // A1 = -0.990875
- 32404, // A2 = -0.988922
- -193, // B2 = -0.005908
- 0, // B1 = 0.000000
- 193, // B0 = 0.005908
- 15986, // A1 = -0.975769
- -32632, // A2 = 0.995880
- 18051, // B2 = 0.550903
- -8658, // B1 = -0.528473
- 18051, // B0 = 0.550903
- 16591, // A1 = -1.012695
- -32634, // A2 = 0.995941
- 15736, // B2 = 0.480240
- -8125, // B1 = -0.495926
- 15736, // B0 = 0.480240
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1336 */
+ 16234, /* A1 = -0.990875 */
+ 32404, /* A2 = -0.988922 */
+ -193, /* B2 = -0.005908 */
+ 0, /* B1 = 0.000000 */
+ 193, /* B0 = 0.005908 */
+ 15986, /* A1 = -0.975769 */
+ -32632, /* A2 = 0.995880 */
+ 18051, /* B2 = 0.550903 */
+ -8658, /* B1 = -0.528473 */
+ 18051, /* B0 = 0.550903 */
+ 16591, /* A1 = -1.012695 */
+ -32634, /* A2 = 0.995941 */
+ 15736, /* B2 = 0.480240 */
+ -8125, /* B1 = -0.495926 */
+ 15736, /* B0 = 0.480240 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1366.txt
- 15564, // A1 = -0.949982
- -32404, // A2 = 0.988922
- -269, // B2 = -0.008216
- 0, // B1 = 0.000000
- 269, // B0 = 0.008216
- 15310, // A1 = -0.934479
- -32632, // A2 = 0.995880
- 10815, // B2 = 0.330063
- -4962, // B1 = -0.302887
- 10815, // B0 = 0.330063
- 15924, // A1 = -0.971924
- -32634, // A2 = 0.995941
- 18880, // B2 = 0.576172
- -9364, // B1 = -0.571594
- 18880, // B0 = 0.576172
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1366 */
+ 15564, /* A1 = -0.949982 */
+ -32404, /* A2 = 0.988922 */
+ -269, /* B2 = -0.008216 */
+ 0, /* B1 = 0.000000 */
+ 269, /* B0 = 0.008216 */
+ 15310, /* A1 = -0.934479 */
+ -32632, /* A2 = 0.995880 */
+ 10815, /* B2 = 0.330063 */
+ -4962, /* B1 = -0.302887 */
+ 10815, /* B0 = 0.330063 */
+ 15924, /* A1 = -0.971924 */
+ -32634, /* A2 = 0.995941 */
+ 18880, /* B2 = 0.576172 */
+ -9364, /* B1 = -0.571594 */
+ 18880, /* B0 = 0.576172 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1380.txt
- 15247, // A1 = -0.930603
- -32397, // A2 = 0.988708
- -244, // B2 = -0.007451
- 0, // B1 = 0.000000
- 244, // B0 = 0.007451
- 14989, // A1 = -0.914886
- -32627, // A2 = 0.995697
- 18961, // B2 = 0.578644
- -8498, // B1 = -0.518707
- 18961, // B0 = 0.578644
- 15608, // A1 = -0.952667
- -32628, // A2 = 0.995758
- 11145, // B2 = 0.340134
- -5430, // B1 = -0.331467
- 11145, // B0 = 0.340134
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1380 */
+ 15247, /* A1 = -0.930603 */
+ -32397, /* A2 = 0.988708 */
+ -244, /* B2 = -0.007451 */
+ 0, /* B1 = 0.000000 */
+ 244, /* B0 = 0.007451 */
+ 14989, /* A1 = -0.914886 */
+ -32627, /* A2 = 0.995697 */
+ 18961, /* B2 = 0.578644 */
+ -8498, /* B1 = -0.518707 */
+ 18961, /* B0 = 0.578644 */
+ 15608, /* A1 = -0.952667 */
+ -32628, /* A2 = 0.995758 */
+ 11145, /* B2 = 0.340134 */
+ -5430, /* B1 = -0.331467 */
+ 11145, /* B0 = 0.340134 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1400.txt
- 14780, // A1 = -0.902130
- -32393, // A2 = 0.988586
- -396, // B2 = -0.012086
- 0, // B1 = 0.000000
- 396, // B0 = 0.012086
- 14510, // A1 = -0.885651
- -32630, // A2 = 0.995819
- 6326, // B2 = 0.193069
- -2747, // B1 = -0.167671
- 6326, // B0 = 0.193069
- 15154, // A1 = -0.924957
- -32632, // A2 = 0.995850
- 23235, // B2 = 0.709076
- -10983, // B1 = -0.670380
- 23235, // B0 = 0.709076
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1400 */
+ 14780, /* A1 = -0.902130 */
+ -32393, /* A2 = 0.988586 */
+ -396, /* B2 = -0.012086 */
+ 0, /* B1 = 0.000000 */
+ 396, /* B0 = 0.012086 */
+ 14510, /* A1 = -0.885651 */
+ -32630, /* A2 = 0.995819 */
+ 6326, /* B2 = 0.193069 */
+ -2747, /* B1 = -0.167671 */
+ 6326, /* B0 = 0.193069 */
+ 15154, /* A1 = -0.924957 */
+ -32632, /* A2 = 0.995850 */
+ 23235, /* B2 = 0.709076 */
+ -10983, /* B1 = -0.670380 */
+ 23235, /* B0 = 0.709076 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1477.txt
- 13005, // A1 = -0.793793
- -32368, // A2 = 0.987823
- -500, // B2 = -0.015265
- 0, // B1 = 0.000000
- 500, // B0 = 0.015265
- 12708, // A1 = -0.775665
- -32615, // A2 = 0.995331
- 11420, // B2 = 0.348526
- -4306, // B1 = -0.262833
- 11420, // B0 = 0.348526
- 13397, // A1 = -0.817688
- -32615, // A2 = 0.995361
- 9454, // B2 = 0.288528
- -3981, // B1 = -0.243027
- 9454, // B0 = 0.288528
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1477 */
+ 13005, /* A1 = -0.793793 */
+ -32368, /* A2 = 0.987823 */
+ -500, /* B2 = -0.015265 */
+ 0, /* B1 = 0.000000 */
+ 500, /* B0 = 0.015265 */
+ 12708, /* A1 = -0.775665 */
+ -32615, /* A2 = 0.995331 */
+ 11420, /* B2 = 0.348526 */
+ -4306, /* B1 = -0.262833 */
+ 11420, /* B0 = 0.348526 */
+ 13397, /* A1 = -0.817688 */
+ -32615, /* A2 = 0.995361 */
+ 9454, /* B2 = 0.288528 */
+ -3981, /* B1 = -0.243027 */
+ 9454, /* B0 = 0.288528 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1600.txt
- 10046, // A1 = -0.613190
- -32331, // A2 = 0.986694
- -455, // B2 = -0.013915
- 0, // B1 = 0.000000
- 455, // B0 = 0.013915
- 9694, // A1 = -0.591705
- -32601, // A2 = 0.994934
- 6023, // B2 = 0.183815
- -1708, // B1 = -0.104279
- 6023, // B0 = 0.183815
- 10478, // A1 = -0.639587
- -32603, // A2 = 0.994965
- 22031, // B2 = 0.672333
- -7342, // B1 = -0.448151
- 22031, // B0 = 0.672333
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1600 */
+ 10046, /* A1 = -0.613190 */
+ -32331, /* A2 = 0.986694 */
+ -455, /* B2 = -0.013915 */
+ 0, /* B1 = 0.000000 */
+ 455, /* B0 = 0.013915 */
+ 9694, /* A1 = -0.591705 */
+ -32601, /* A2 = 0.994934 */
+ 6023, /* B2 = 0.183815 */
+ -1708, /* B1 = -0.104279 */
+ 6023, /* B0 = 0.183815 */
+ 10478, /* A1 = -0.639587 */
+ -32603, /* A2 = 0.994965 */
+ 22031, /* B2 = 0.672333 */
+ -7342, /* B1 = -0.448151 */
+ 22031, /* B0 = 0.672333 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // f1633_1638[]
- 9181, // A1 = 0.560394
- -32256, // A2 = -0.984375
- -556, // B2 = -0.016975
- 0, // B1 = 0
- 556, // B0 = 0.016975
- 8757, // A1 = 0.534515
- -32574, // A2 = -0.99408
- 8443, // B2 = 0.25769
- -2135, // B1 = -0.130341
- 8443, // B0 = 0.25769
- 9691, // A1 = 0.591522
- -32574, // A2 = -0.99411
- 15446, // B2 = 0.471375
- -4809, // B1 = -0.293579
- 15446, // B0 = 0.471375
- 7, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1633_1638[] */
+ 9181, /* A1 = 0.560394 */
+ -32256, /* A2 = -0.984375 */
+ -556, /* B2 = -0.016975 */
+ 0, /* B1 = 0 */
+ 556, /* B0 = 0.016975 */
+ 8757, /* A1 = 0.534515 */
+ -32574, /* A2 = -0.99408 */
+ 8443, /* B2 = 0.25769 */
+ -2135, /* B1 = -0.130341 */
+ 8443, /* B0 = 0.25769 */
+ 9691, /* A1 = 0.591522 */
+ -32574, /* A2 = -0.99411 */
+ 15446, /* B2 = 0.471375 */
+ -4809, /* B1 = -0.293579 */
+ 15446, /* B0 = 0.471375 */
+ 7, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1800.txt
- 5076, // A1 = -0.309875
- -32304, // A2 = 0.985840
- -508, // B2 = -0.015503
- 0, // B1 = 0.000000
- 508, // B0 = 0.015503
- 4646, // A1 = -0.283600
- -32605, // A2 = 0.995026
- 6742, // B2 = 0.205780
- -878, // B1 = -0.053635
- 6742, // B0 = 0.205780
- 5552, // A1 = -0.338928
- -32605, // A2 = 0.995056
- 23667, // B2 = 0.722260
- -4297, // B1 = -0.262329
- 23667, // B0 = 0.722260
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1800 */
+ 5076, /* A1 = -0.309875 */
+ -32304, /* A2 = 0.985840 */
+ -508, /* B2 = -0.015503 */
+ 0, /* B1 = 0.000000 */
+ 508, /* B0 = 0.015503 */
+ 4646, /* A1 = -0.283600 */
+ -32605, /* A2 = 0.995026 */
+ 6742, /* B2 = 0.205780 */
+ -878, /* B1 = -0.053635 */
+ 6742, /* B0 = 0.205780 */
+ 5552, /* A1 = -0.338928 */
+ -32605, /* A2 = 0.995056 */
+ 23667, /* B2 = 0.722260 */
+ -4297, /* B1 = -0.262329 */
+ 23667, /* B0 = 0.722260 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
- { // 1860.txt
- 3569, // A1 = -0.217865
- -32292, // A2 = 0.985504
- -239, // B2 = -0.007322
- 0, // B1 = 0.000000
- 239, // B0 = 0.007322
- 3117, // A1 = -0.190277
- -32603, // A2 = 0.994965
- 18658, // B2 = 0.569427
- -1557, // B1 = -0.095032
- 18658, // B0 = 0.569427
- 4054, // A1 = -0.247437
- -32603, // A2 = 0.994965
- 18886, // B2 = 0.576385
- -2566, // B1 = -0.156647
- 18886, // B0 = 0.576385
- 5, // Internal filter scaling
- 159, // Minimum in-band energy threshold
- 21, // 21/32 in-band to broad-band ratio
- 0x0FF5 // shift-mask 0x0FF (look at 16 half-frames) bit count = 5
+ { /* f1860 */
+ 3569, /* A1 = -0.217865 */
+ -32292, /* A2 = 0.985504 */
+ -239, /* B2 = -0.007322 */
+ 0, /* B1 = 0.000000 */
+ 239, /* B0 = 0.007322 */
+ 3117, /* A1 = -0.190277 */
+ -32603, /* A2 = 0.994965 */
+ 18658, /* B2 = 0.569427 */
+ -1557, /* B1 = -0.095032 */
+ 18658, /* B0 = 0.569427 */
+ 4054, /* A1 = -0.247437 */
+ -32603, /* A2 = 0.994965 */
+ 18886, /* B2 = 0.576385 */
+ -2566, /* B1 = -0.156647 */
+ 18886, /* B0 = 0.576385 */
+ 5, /* Internal filter scaling */
+ 159, /* Minimum in-band energy threshold */
+ 21, /* 21/32 in-band to broad-band ratio */
+ 0x0FF5 /* shift-mask 0x0FF (look at 16 half-frames) bit count = 5 */
},
};
static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf)
if (jf->filter > 3) {
return -1;
}
- if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) // Select Filter
+ if (ixj_WriteDSPCommand(0x5154 + jf->filter, j)) /* Select Filter */
return -1;
if (!jf->enable) {
- if (ixj_WriteDSPCommand(0x5152, j)) // Disable Filter
+ if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */
return -1;
else
return 0;
} else {
- if (ixj_WriteDSPCommand(0x5153, j)) // Enable Filter
+ if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */
return -1;
- // Select the filter (f0 - f3) to use.
+ /* Select the filter (f0 - f3) to use. */
if (ixj_WriteDSPCommand(0x5154 + jf->filter, j))
return -1;
}
if (jf->freq < 12 && jf->freq > 3) {
- // Select the frequency for the selected filter.
+ /* Select the frequency for the selected filter. */
if (ixj_WriteDSPCommand(0x5170 + jf->freq, j))
return -1;
} else if (jf->freq > 11) {
- // We need to load a programmable filter set for undefined
- // frequencies. So we will point the filter to a programmable set.
- // Since there are only 4 filters and 4 programmable sets, we will
- // just point the filter to the same number set and program it for the
- // frequency we want.
+ /* We need to load a programmable filter set for undefined */
+ /* frequencies. So we will point the filter to a programmable set. */
+ /* Since there are only 4 filters and 4 programmable sets, we will */
+ /* just point the filter to the same number set and program it for the */
+ /* frequency we want. */
if (ixj_WriteDSPCommand(0x5170 + jf->filter, j))
return -1;
if (j->ver.low != 0x12) {
return 0;
}
+static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr)
+{
+ unsigned short cmd;
+ int cnt, max;
+ if (jfr->filter > 3) {
+ return -1;
+ }
+ if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j)) /* Select Filter */
+ return -1;
+
+ if (!jfr->enable) {
+ if (ixj_WriteDSPCommand(0x5152, j)) /* Disable Filter */
+ return -1;
+ else
+ return 0;
+ } else {
+ if (ixj_WriteDSPCommand(0x5153, j)) /* Enable Filter */
+ return -1;
+ /* Select the filter (f0 - f3) to use. */
+ if (ixj_WriteDSPCommand(0x5154 + jfr->filter, j))
+ return -1;
+ }
+ /* We need to load a programmable filter set for undefined */
+ /* frequencies. So we will point the filter to a programmable set. */
+ /* Since there are only 4 filters and 4 programmable sets, we will */
+ /* just point the filter to the same number set and program it for the */
+ /* frequency we want. */
+ if (ixj_WriteDSPCommand(0x5170 + jfr->filter, j))
+ return -1;
+ if (j->ver.low != 0x12) {
+ cmd = 0x515B;
+ max = 19;
+ } else {
+ cmd = 0x515E;
+ max = 15;
+ }
+ if (ixj_WriteDSPCommand(cmd, j))
+ return -1;
+ for (cnt = 0; cnt < max; cnt++) {
+ if (ixj_WriteDSPCommand(jfr->coeff[cnt], j))
+ return -1;
+ }
+ j->filter_en[jfr->filter] = jfr->enable;
+ return 0;
+}
+
static int ixj_init_tone(IXJ *j, IXJ_TONE * ti)
{
int freq0, freq1;
{
if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, j))
return -1;
- if (ixj_WriteDSPCommand(0x6000 + (ti->gain0 << 4) + ti->gain1, j))
+ if (ixj_WriteDSPCommand(0x6000 + (ti->gain1 << 4) + ti->gain0, j))
return -1;
data = freq0;
if (ixj_WriteDSPCommand(data, j))
}
return freq0;
}
+
/******************************************************************************
* ixj.h
*
- * Device Driver for the Internet PhoneJACK and
- * Internet LineJACK Telephony Cards.
*
- * (c) Copyright 1999 Quicknet Technologies, Inc.
+ * Device Driver for Quicknet Technologies, Inc.'s Telephony cards
+ * including the Internet PhoneJACK, Internet PhoneJACK Lite,
+ * Internet PhoneJACK PCI, Internet LineJACK, Internet PhoneCARD and
+ * SmartCABLE
+ *
+ * (c) Copyright 1999-2001 Quicknet Technologies, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*****************************************************************************/
-static char ixj_h_rcsid[] = "$Id: ixj.h,v 3.14 2000/03/30 22:06:48 eokerson Exp $";
+static char ixj_h_rcsid[] = "$Id: ixj.h,v 4.1 2001/08/04 14:49:27 craigs Exp $";
-#ifndef _I386_TYPES_H
-#include <asm/types.h>
-#endif
+#define IXJ_VERSION 3031
+
+#include <linux/types.h>
#include <linux/ixjuser.h>
#include <linux/phonedev.h>
typedef __u8 BYTE;
typedef __u8 BOOL;
+#ifndef IXJMAX
#define IXJMAX 16
+#endif
#define TRUE 1
#define FALSE 0
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+
/******************************************************************************
*
* This structure when unioned with the structures below makes simple byte
unsigned int led2:1;
unsigned int led3:1;
unsigned int led4:1;
-} PSCRWI; // Internet LineJACK and Internet PhoneJACK Lite
+} PSCRWI; /* Internet LineJACK and Internet PhoneJACK Lite */
typedef struct {
unsigned int eidp:1;
unsigned int eisd:1;
unsigned int x:6;
-} PSCRWP; // Internet PhoneJACK PCI
+} PSCRWP; /* Internet PhoneJACK PCI */
typedef union {
PSCRWI bits;
*
******************************************************************************/
typedef struct {
- unsigned int x0:4; // unused bits
+ unsigned int x0:4; /* unused bits */
- unsigned int ed:1; // Event Detect
+ unsigned int ed:1; /* Event Detect */
- unsigned int drf:1; // Smart Cable Removal Flag 1=no cable
+ unsigned int drf:1; /* SmartCABLE Removal Flag 1=no cable */
- unsigned int dspf:1; // DSP Flag 1=DSP Ready
+ unsigned int dspf:1; /* DSP Flag 1=DSP Ready */
- unsigned int crr:1; // Control Register Ready
+ unsigned int crr:1; /* Control Register Ready */
} COMMAND_REG1;
} PCMCIA_CR1;
typedef struct {
- unsigned int x0:4; // unused bits
+ unsigned int x0:4; /* unused bits */
- unsigned int rstc:1; // Smart Cable Reset
+ unsigned int rstc:1; /* SmartCABLE Reset */
- unsigned int pwr:1; // Smart Cable Power
+ unsigned int pwr:1; /* SmartCABLE Power */
- unsigned int x1:2; // unused bits
+ unsigned int x1:2; /* unused bits */
} COMMAND_REG2;
} PCMCIA_CR2;
typedef struct {
- unsigned int addr:5; // R/W Smart Cable Register Address
+ unsigned int addr:5; /* R/W SmartCABLE Register Address */
- unsigned int rw:1; // Read / Write flag
+ unsigned int rw:1; /* Read / Write flag */
- unsigned int dev:2; // 2 bit Smart Cable Device Address
+ unsigned int dev:2; /* 2 bit SmartCABLE Device Address */
} CONTROL_REG;
} PCMCIA_SLIC;
typedef struct {
- unsigned int cpd:1; // Chip Power Down
+ unsigned int cpd:1; /* Chip Power Down */
- unsigned int mpd:1; // MIC Bias Power Down
+ unsigned int mpd:1; /* MIC Bias Power Down */
- unsigned int hpd:1; // Handset Drive Power Down
+ unsigned int hpd:1; /* Handset Drive Power Down */
- unsigned int lpd:1; // Line Drive Power Down
+ unsigned int lpd:1; /* Line Drive Power Down */
- unsigned int spd:1; // Speaker Drive Power Down
+ unsigned int spd:1; /* Speaker Drive Power Down */
- unsigned int x:2; // unused bits
+ unsigned int x:2; /* unused bits */
- unsigned int sr:1; // Software Reset
+ unsigned int sr:1; /* Software Reset */
} Si3CONTROL1;
} Si3C1;
typedef struct {
- unsigned int al:1; // Analog Loopback DAC analog -> ADC analog
+ unsigned int al:1; /* Analog Loopback DAC analog -> ADC analog */
- unsigned int dl2:1; // Digital Loopback DAC -> ADC one bit
+ unsigned int dl2:1; /* Digital Loopback DAC -> ADC one bit */
- unsigned int dl1:1; // Digital Loopback ADC -> DAC one bit
+ unsigned int dl1:1; /* Digital Loopback ADC -> DAC one bit */
- unsigned int pll:1; // 1 = div 10, 0 = div 5
+ unsigned int pll:1; /* 1 = div 10, 0 = div 5 */
- unsigned int hpd:1; // HPF disable
+ unsigned int hpd:1; /* HPF disable */
- unsigned int x:3; // unused bits
+ unsigned int x:3; /* unused bits */
} Si3CONTROL2;
} Si3C2;
typedef struct {
- unsigned int iir:1; // 1 enables IIR, 0 enables FIR
+ unsigned int iir:1; /* 1 enables IIR, 0 enables FIR */
- unsigned int him:1; // Handset Input Mute
+ unsigned int him:1; /* Handset Input Mute */
- unsigned int mcm:1; // MIC In Mute
+ unsigned int mcm:1; /* MIC In Mute */
- unsigned int mcg:2; // MIC In Gain
+ unsigned int mcg:2; /* MIC In Gain */
- unsigned int lim:1; // Line In Mute
+ unsigned int lim:1; /* Line In Mute */
- unsigned int lig:2; // Line In Gain
+ unsigned int lig:2; /* Line In Gain */
} Si3RXGAIN;
} Si3RXG;
typedef struct {
- unsigned int hom:1; // Handset Out Mute
+ unsigned int hom:1; /* Handset Out Mute */
- unsigned int lom:1; // Line Out Mute
+ unsigned int lom:1; /* Line Out Mute */
- unsigned int rxg:5; // RX PGA Gain
+ unsigned int rxg:5; /* RX PGA Gain */
- unsigned int x:1; // unused bit
+ unsigned int x:1; /* unused bit */
} Si3ADCVOLUME;
} Si3ADC;
typedef struct {
- unsigned int srm:1; // Speaker Right Mute
+ unsigned int srm:1; /* Speaker Right Mute */
- unsigned int slm:1; // Speaker Left Mute
+ unsigned int slm:1; /* Speaker Left Mute */
- unsigned int txg:5; // TX PGA Gain
+ unsigned int txg:5; /* TX PGA Gain */
- unsigned int x:1; // unused bit
+ unsigned int x:1; /* unused bit */
} Si3DACVOLUME;
} Si3DAC;
typedef struct {
- unsigned int x:5; // unused bit
+ unsigned int x:5; /* unused bit */
- unsigned int losc:1; // Line Out Short Circuit
+ unsigned int losc:1; /* Line Out Short Circuit */
- unsigned int srsc:1; // Speaker Right Short Circuit
+ unsigned int srsc:1; /* Speaker Right Short Circuit */
- unsigned int slsc:1; // Speaker Left Short Circuit
+ unsigned int slsc:1; /* Speaker Left Short Circuit */
} Si3STATUSREPORT;
} Si3STAT;
typedef struct {
- unsigned int sot:2; // Speaker Out Attenuation
+ unsigned int sot:2; /* Speaker Out Attenuation */
- unsigned int lot:2; // Line Out Attenuation
+ unsigned int lot:2; /* Line Out Attenuation */
- unsigned int x:4; // unused bits
+ unsigned int x:4; /* unused bits */
} Si3ANALOGATTN;
******************************************************************************/
typedef struct _DAA_REGS {
- //-----------------------------------------------
- // SOP Registers
- //
+ /*----------------------------------------------- */
+ /* SOP Registers */
+ /* */
BYTE bySOP;
union _SOP_REGS {
struct _SOP {
- union // SOP - CR0 Register
+ union /* SOP - CR0 Register */
{
BYTE reg;
struct _CR0_BITREGS {
- BYTE CLK_EXT:1; // cr0[0:0]
+ BYTE CLK_EXT:1; /* cr0[0:0] */
- BYTE RIP:1; // cr0[1:1]
+ BYTE RIP:1; /* cr0[1:1] */
- BYTE AR:1; // cr0[2:2]
+ BYTE AR:1; /* cr0[2:2] */
- BYTE AX:1; // cr0[3:3]
+ BYTE AX:1; /* cr0[3:3] */
- BYTE FRR:1; // cr0[4:4]
+ BYTE FRR:1; /* cr0[4:4] */
- BYTE FRX:1; // cr0[5:5]
+ BYTE FRX:1; /* cr0[5:5] */
- BYTE IM:1; // cr0[6:6]
+ BYTE IM:1; /* cr0[6:6] */
- BYTE TH:1; // cr0[7:7]
+ BYTE TH:1; /* cr0[7:7] */
} bitreg;
} cr0;
- union // SOP - CR1 Register
+ union /* SOP - CR1 Register */
{
BYTE reg;
struct _CR1_REGS {
- BYTE RM:1; // cr1[0:0]
+ BYTE RM:1; /* cr1[0:0] */
- BYTE RMR:1; // cr1[1:1]
+ BYTE RMR:1; /* cr1[1:1] */
- BYTE No_auto:1; // cr1[2:2]
+ BYTE No_auto:1; /* cr1[2:2] */
- BYTE Pulse:1; // cr1[3:3]
+ BYTE Pulse:1; /* cr1[3:3] */
- BYTE P_Tone1:1; // cr1[4:4]
+ BYTE P_Tone1:1; /* cr1[4:4] */
- BYTE P_Tone2:1; // cr1[5:5]
+ BYTE P_Tone2:1; /* cr1[5:5] */
- BYTE E_Tone1:1; // cr1[6:6]
+ BYTE E_Tone1:1; /* cr1[6:6] */
- BYTE E_Tone2:1; // cr1[7:7]
+ BYTE E_Tone2:1; /* cr1[7:7] */
} bitreg;
} cr1;
- union // SOP - CR2 Register
+ union /* SOP - CR2 Register */
{
BYTE reg;
struct _CR2_REGS {
- BYTE Call_II:1; // CR2[0:0]
+ BYTE Call_II:1; /* CR2[0:0] */
- BYTE Call_I:1; // CR2[1:1]
+ BYTE Call_I:1; /* CR2[1:1] */
- BYTE Call_en:1; // CR2[2:2]
+ BYTE Call_en:1; /* CR2[2:2] */
- BYTE Call_pon:1; // CR2[3:3]
+ BYTE Call_pon:1; /* CR2[3:3] */
- BYTE IDR:1; // CR2[4:4]
+ BYTE IDR:1; /* CR2[4:4] */
- BYTE COT_R:3; // CR2[5:7]
+ BYTE COT_R:3; /* CR2[5:7] */
} bitreg;
} cr2;
- union // SOP - CR3 Register
+ union /* SOP - CR3 Register */
{
BYTE reg;
struct _CR3_REGS {
- BYTE DHP_X:1; // CR3[0:0]
+ BYTE DHP_X:1; /* CR3[0:0] */
- BYTE DHP_R:1; // CR3[1:1]
+ BYTE DHP_R:1; /* CR3[1:1] */
- BYTE Cal_pctl:1; // CR3[2:2]
+ BYTE Cal_pctl:1; /* CR3[2:2] */
- BYTE SEL:1; // CR3[3:3]
+ BYTE SEL:1; /* CR3[3:3] */
- BYTE TestLoops:4; // CR3[4:7]
+ BYTE TestLoops:4; /* CR3[4:7] */
} bitreg;
} cr3;
- union // SOP - CR4 Register
+ union /* SOP - CR4 Register */
{
BYTE reg;
struct _CR4_REGS {
- BYTE Fsc_en:1; // CR4[0:0]
+ BYTE Fsc_en:1; /* CR4[0:0] */
- BYTE Int_en:1; // CR4[1:1]
+ BYTE Int_en:1; /* CR4[1:1] */
- BYTE AGX:2; // CR4[2:3]
+ BYTE AGX:2; /* CR4[2:3] */
- BYTE AGR_R:2; // CR4[4:5]
+ BYTE AGR_R:2; /* CR4[4:5] */
- BYTE AGR_Z:2; // CR4[6:7]
+ BYTE AGR_Z:2; /* CR4[6:7] */
} bitreg;
} cr4;
- union // SOP - CR5 Register
+ union /* SOP - CR5 Register */
{
BYTE reg;
struct _CR5_REGS {
- BYTE V_0:1; // CR5[0:0]
+ BYTE V_0:1; /* CR5[0:0] */
- BYTE V_1:1; // CR5[1:1]
+ BYTE V_1:1; /* CR5[1:1] */
- BYTE V_2:1; // CR5[2:2]
+ BYTE V_2:1; /* CR5[2:2] */
- BYTE V_3:1; // CR5[3:3]
+ BYTE V_3:1; /* CR5[3:3] */
- BYTE V_4:1; // CR5[4:4]
+ BYTE V_4:1; /* CR5[4:4] */
- BYTE V_5:1; // CR5[5:5]
+ BYTE V_5:1; /* CR5[5:5] */
- BYTE V_6:1; // CR5[6:6]
+ BYTE V_6:1; /* CR5[6:6] */
- BYTE V_7:1; // CR5[7:7]
+ BYTE V_7:1; /* CR5[7:7] */
} bitreg;
} cr5;
- union // SOP - CR6 Register
+ union /* SOP - CR6 Register */
{
BYTE reg;
struct _CR6_REGS {
- BYTE reserved:8; // CR6[0:7]
+ BYTE reserved:8; /* CR6[0:7] */
} bitreg;
} cr6;
- union // SOP - CR7 Register
+ union /* SOP - CR7 Register */
{
BYTE reg;
struct _CR7_REGS {
- BYTE reserved:8; // CR7[0:7]
+ BYTE reserved:8; /* CR7[0:7] */
} bitreg;
} cr7;
} SOP_REGS;
- // DAA_REGS.SOP_REGS.SOP.CR5.reg
- // DAA_REGS.SOP_REGS.SOP.CR5.bitreg
- // DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2
- // DAA_REGS.SOP_REGS.ByteRegs[5]
+ /* DAA_REGS.SOP_REGS.SOP.CR5.reg */
+ /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg */
+ /* DAA_REGS.SOP_REGS.SOP.CR5.bitreg.V_2 */
+ /* DAA_REGS.SOP_REGS.ByteRegs[5] */
- //-----------------------------------------------
- // XOP Registers
- //
+ /*----------------------------------------------- */
+ /* XOP Registers */
+ /* */
BYTE byXOP;
union _XOP_REGS {
struct _XOP {
- union // XOP - XR0 Register - Read values
+ union XOPXR0/* XOP - XR0 Register - Read values */
{
BYTE reg;
struct _XR0_BITREGS {
- BYTE SI_0:1; // XR0[0:0] - Read
+ BYTE SI_0:1; /* XR0[0:0] - Read */
- BYTE SI_1:1; // XR0[1:1] - Read
+ BYTE SI_1:1; /* XR0[1:1] - Read */
- BYTE VDD_OK:1; // XR0[2:2] - Read
+ BYTE VDD_OK:1; /* XR0[2:2] - Read */
- BYTE Caller_ID:1; // XR0[3:3] - Read
+ BYTE Caller_ID:1; /* XR0[3:3] - Read */
- BYTE RING:1; // XR0[4:4] - Read
+ BYTE RING:1; /* XR0[4:4] - Read */
- BYTE Cadence:1; // XR0[5:5] - Read
+ BYTE Cadence:1; /* XR0[5:5] - Read */
- BYTE Wake_up:1; // XR0[6:6] - Read
+ BYTE Wake_up:1; /* XR0[6:6] - Read */
- BYTE unused:1; // XR0[7:7] - Read
+ BYTE RMR:1; /* XR0[7:7] - Read */
} bitreg;
} xr0;
- union // XOP - XR1 Register
+ union /* XOP - XR1 Register */
{
BYTE reg;
struct _XR1_BITREGS {
- BYTE M_SI_0:1; // XR1[0:0]
+ BYTE M_SI_0:1; /* XR1[0:0] */
- BYTE M_SI_1:1; // XR1[1:1]
+ BYTE M_SI_1:1; /* XR1[1:1] */
- BYTE M_VDD_OK:1; // XR1[2:2]
+ BYTE M_VDD_OK:1; /* XR1[2:2] */
- BYTE M_Caller_ID:1; // XR1[3:3]
+ BYTE M_Caller_ID:1; /* XR1[3:3] */
- BYTE M_RING:1; // XR1[4:4]
+ BYTE M_RING:1; /* XR1[4:4] */
- BYTE M_Cadence:1; // XR1[5:5]
+ BYTE M_Cadence:1; /* XR1[5:5] */
- BYTE M_Wake_up:1; // XR1[6:6]
+ BYTE M_Wake_up:1; /* XR1[6:6] */
- BYTE unused:1; // XR1[7:7]
+ BYTE unused:1; /* XR1[7:7] */
} bitreg;
} xr1;
- union // XOP - XR2 Register
+ union /* XOP - XR2 Register */
{
BYTE reg;
struct _XR2_BITREGS {
- BYTE CTO0:1; // XR2[0:0]
+ BYTE CTO0:1; /* XR2[0:0] */
- BYTE CTO1:1; // XR2[1:1]
+ BYTE CTO1:1; /* XR2[1:1] */
- BYTE CTO2:1; // XR2[2:2]
+ BYTE CTO2:1; /* XR2[2:2] */
- BYTE CTO3:1; // XR2[3:3]
+ BYTE CTO3:1; /* XR2[3:3] */
- BYTE CTO4:1; // XR2[4:4]
+ BYTE CTO4:1; /* XR2[4:4] */
- BYTE CTO5:1; // XR2[5:5]
+ BYTE CTO5:1; /* XR2[5:5] */
- BYTE CTO6:1; // XR2[6:6]
+ BYTE CTO6:1; /* XR2[6:6] */
- BYTE CTO7:1; // XR2[7:7]
+ BYTE CTO7:1; /* XR2[7:7] */
} bitreg;
} xr2;
- union // XOP - XR3 Register
+ union /* XOP - XR3 Register */
{
BYTE reg;
struct _XR3_BITREGS {
- BYTE DCR0:1; // XR3[0:0]
+ BYTE DCR0:1; /* XR3[0:0] */
- BYTE DCR1:1; // XR3[1:1]
+ BYTE DCR1:1; /* XR3[1:1] */
- BYTE DCI:1; // XR3[2:2]
+ BYTE DCI:1; /* XR3[2:2] */
- BYTE DCU0:1; // XR3[3:3]
+ BYTE DCU0:1; /* XR3[3:3] */
- BYTE DCU1:1; // XR3[4:4]
+ BYTE DCU1:1; /* XR3[4:4] */
- BYTE B_off:1; // XR3[5:5]
+ BYTE B_off:1; /* XR3[5:5] */
- BYTE AGB0:1; // XR3[6:6]
+ BYTE AGB0:1; /* XR3[6:6] */
- BYTE AGB1:1; // XR3[7:7]
+ BYTE AGB1:1; /* XR3[7:7] */
} bitreg;
} xr3;
- union // XOP - XR4 Register
+ union /* XOP - XR4 Register */
{
BYTE reg;
struct _XR4_BITREGS {
- BYTE C_0:1; // XR4[0:0]
+ BYTE C_0:1; /* XR4[0:0] */
- BYTE C_1:1; // XR4[1:1]
+ BYTE C_1:1; /* XR4[1:1] */
- BYTE C_2:1; // XR4[2:2]
+ BYTE C_2:1; /* XR4[2:2] */
- BYTE C_3:1; // XR4[3:3]
+ BYTE C_3:1; /* XR4[3:3] */
- BYTE C_4:1; // XR4[4:4]
+ BYTE C_4:1; /* XR4[4:4] */
- BYTE C_5:1; // XR4[5:5]
+ BYTE C_5:1; /* XR4[5:5] */
- BYTE C_6:1; // XR4[6:6]
+ BYTE C_6:1; /* XR4[6:6] */
- BYTE C_7:1; // XR4[7:7]
+ BYTE C_7:1; /* XR4[7:7] */
} bitreg;
} xr4;
- union // XOP - XR5 Register
+ union /* XOP - XR5 Register */
{
BYTE reg;
struct _XR5_BITREGS {
- BYTE T_0:1; // XR5[0:0]
+ BYTE T_0:1; /* XR5[0:0] */
- BYTE T_1:1; // XR5[1:1]
+ BYTE T_1:1; /* XR5[1:1] */
- BYTE T_2:1; // XR5[2:2]
+ BYTE T_2:1; /* XR5[2:2] */
- BYTE T_3:1; // XR5[3:3]
+ BYTE T_3:1; /* XR5[3:3] */
- BYTE T_4:1; // XR5[4:4]
+ BYTE T_4:1; /* XR5[4:4] */
- BYTE T_5:1; // XR5[5:5]
+ BYTE T_5:1; /* XR5[5:5] */
- BYTE T_6:1; // XR5[6:6]
+ BYTE T_6:1; /* XR5[6:6] */
- BYTE T_7:1; // XR5[7:7]
+ BYTE T_7:1; /* XR5[7:7] */
} bitreg;
} xr5;
- union // XOP - XR6 Register - Read Values
+ union /* XOP - XR6 Register - Read Values */
{
BYTE reg;
struct _XR6_BITREGS {
- BYTE CPS0:1; // XR6[0:0]
+ BYTE CPS0:1; /* XR6[0:0] */
- BYTE CPS1:1; // XR6[1:1]
+ BYTE CPS1:1; /* XR6[1:1] */
- BYTE unused1:2; // XR6[2:3]
+ BYTE unused1:2; /* XR6[2:3] */
- BYTE CLK_OFF:1; // XR6[4:4]
+ BYTE CLK_OFF:1; /* XR6[4:4] */
- BYTE unused2:3; // XR6[5:7]
+ BYTE unused2:3; /* XR6[5:7] */
} bitreg;
} xr6;
- union // XOP - XR7 Register
+ union /* XOP - XR7 Register */
{
BYTE reg;
struct _XR7_BITREGS {
- BYTE unused1:1; // XR7[0:0]
+ BYTE unused1:1; /* XR7[0:0] */
- BYTE Vdd0:1; // XR7[1:1]
+ BYTE Vdd0:1; /* XR7[1:1] */
- BYTE Vdd1:1; // XR7[2:2]
+ BYTE Vdd1:1; /* XR7[2:2] */
- BYTE unused2:5; // XR7[3:7]
+ BYTE unused2:5; /* XR7[3:7] */
} bitreg;
} xr7;
} XOP_REGS;
- // DAA_REGS.XOP_REGS.XOP.XR7.reg
- // DAA_REGS.XOP_REGS.XOP.XR7.bitreg
- // DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0
- // DAA_REGS.XOP_REGS.ByteRegs[7]
+ /* DAA_REGS.XOP_REGS.XOP.XR7.reg */
+ /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg */
+ /* DAA_REGS.XOP_REGS.XOP.XR7.bitreg.Vdd0 */
+ /* DAA_REGS.XOP_REGS.ByteRegs[7] */
- //-----------------------------------------------
- // COP Registers
- //
+ /*----------------------------------------------- */
+ /* COP Registers */
+ /* */
BYTE byCOP;
union _COP_REGS {
struct _COP {
- BYTE THFilterCoeff_1[8]; // COP - TH Filter Coefficients, CODE=0, Part 1
+ BYTE THFilterCoeff_1[8]; /* COP - TH Filter Coefficients, CODE=0, Part 1 */
- BYTE THFilterCoeff_2[8]; // COP - TH Filter Coefficients, CODE=1, Part 2
+ BYTE THFilterCoeff_2[8]; /* COP - TH Filter Coefficients, CODE=1, Part 2 */
- BYTE THFilterCoeff_3[8]; // COP - TH Filter Coefficients, CODE=2, Part 3
+ BYTE THFilterCoeff_3[8]; /* COP - TH Filter Coefficients, CODE=2, Part 3 */
- BYTE RingerImpendance_1[8]; // COP - Ringer Impendance Coefficients, CODE=3, Part 1
+ BYTE RingerImpendance_1[8]; /* COP - Ringer Impendance Coefficients, CODE=3, Part 1 */
- BYTE IMFilterCoeff_1[8]; // COP - IM Filter Coefficients, CODE=4, Part 1
+ BYTE IMFilterCoeff_1[8]; /* COP - IM Filter Coefficients, CODE=4, Part 1 */
- BYTE IMFilterCoeff_2[8]; // COP - IM Filter Coefficients, CODE=5, Part 2
+ BYTE IMFilterCoeff_2[8]; /* COP - IM Filter Coefficients, CODE=5, Part 2 */
- BYTE RingerImpendance_2[8]; // COP - Ringer Impendance Coefficients, CODE=6, Part 2
+ BYTE RingerImpendance_2[8]; /* COP - Ringer Impendance Coefficients, CODE=6, Part 2 */
- BYTE FRRFilterCoeff[8]; // COP - FRR Filter Coefficients, CODE=7
+ BYTE FRRFilterCoeff[8]; /* COP - FRR Filter Coefficients, CODE=7 */
- BYTE FRXFilterCoeff[8]; // COP - FRX Filter Coefficients, CODE=8
+ BYTE FRXFilterCoeff[8]; /* COP - FRX Filter Coefficients, CODE=8 */
- BYTE ARFilterCoeff[4]; // COP - AR Filter Coefficients, CODE=9
+ BYTE ARFilterCoeff[4]; /* COP - AR Filter Coefficients, CODE=9 */
- BYTE AXFilterCoeff[4]; // COP - AX Filter Coefficients, CODE=10
+ BYTE AXFilterCoeff[4]; /* COP - AX Filter Coefficients, CODE=10 */
- BYTE Tone1Coeff[4]; // COP - Tone1 Coefficients, CODE=11
+ BYTE Tone1Coeff[4]; /* COP - Tone1 Coefficients, CODE=11 */
- BYTE Tone2Coeff[4]; // COP - Tone2 Coefficients, CODE=12
+ BYTE Tone2Coeff[4]; /* COP - Tone2 Coefficients, CODE=12 */
- BYTE LevelmeteringRinging[4]; // COP - Levelmetering Ringing, CODE=13
+ BYTE LevelmeteringRinging[4]; /* COP - Levelmetering Ringing, CODE=13 */
- BYTE CallerID1stTone[8]; // COP - Caller ID 1st Tone, CODE=14
+ BYTE CallerID1stTone[8]; /* COP - Caller ID 1st Tone, CODE=14 */
- BYTE CallerID2ndTone[8]; // COP - Caller ID 2nd Tone, CODE=15
+ BYTE CallerID2ndTone[8]; /* COP - Caller ID 2nd Tone, CODE=15 */
} COP;
} COP_REGS;
- // DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3]
- // DAA_REGS.COP_REGS.COP.XR7.bitreg
- // DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0
- // DAA_REGS.COP_REGS.ByteRegs[57]
+ /* DAA_REGS.COP_REGS.COP.XR7.Tone1Coeff[3] */
+ /* DAA_REGS.COP_REGS.COP.XR7.bitreg */
+ /* DAA_REGS.COP_REGS.COP.XR7.bitreg.Vdd0 */
+ /* DAA_REGS.COP_REGS.ByteRegs[57] */
- //-----------------------------------------------
- // CAO Registers
- //
+ /*----------------------------------------------- */
+ /* CAO Registers */
+ /* */
BYTE byCAO;
union _CAO_REGS {
struct _CAO {
- BYTE CallerID[512]; // CAO - Caller ID Bytes
+ BYTE CallerID[512]; /* CAO - Caller ID Bytes */
} CAO;
BYTE ByteRegs[sizeof(struct _CAO)];
} CAO_REGS;
- union // XOP - XR0 Register - Write values
+ union /* XOP - XR0 Register - Write values */
{
BYTE reg;
struct _XR0_BITREGSW {
- BYTE SO_0:1; // XR1[0:0] - Write
+ BYTE SO_0:1; /* XR1[0:0] - Write */
- BYTE SO_1:1; // XR1[1:1] - Write
+ BYTE SO_1:1; /* XR1[1:1] - Write */
- BYTE SO_2:1; // XR1[2:2] - Write
+ BYTE SO_2:1; /* XR1[2:2] - Write */
- BYTE unused:5; // XR1[3:7] - Write
+ BYTE unused:5; /* XR1[3:7] - Write */
} bitreg;
} XOP_xr0_W;
- union // XOP - XR6 Register - Write values
+ union /* XOP - XR6 Register - Write values */
{
BYTE reg;
struct _XR6_BITREGSW {
- BYTE unused1:4; // XR6[0:3]
+ BYTE unused1:4; /* XR6[0:3] */
- BYTE CLK_OFF:1; // XR6[4:4]
+ BYTE CLK_OFF:1; /* XR6[4:4] */
- BYTE unused2:3; // XR6[5:7]
+ BYTE unused2:3; /* XR6[5:7] */
} bitreg;
} XOP_xr6_W;
#define ALISDAA_ID_BYTE 0x81
#define ALISDAA_CALLERID_SIZE 512
-//------------------------------
-//
-// Misc definitions
-//
+/*------------------------------ */
+/* */
+/* Misc definitions */
+/* */
-// Power Up Operation
+/* Power Up Operation */
#define SOP_PU_SLEEP 0
#define SOP_PU_RINGING 1
#define SOP_PU_CONVERSATION 2
#define SOP_PU_PULSEDIALING 3
+#define SOP_PU_RESET 4
#define ALISDAA_CALLERID_SIZE 512
-#define PLAYBACK_MODE_COMPRESSED 0 // Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729
-#define PLAYBACK_MODE_TRUESPEECH_V40 0 // Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps
-#define PLAYBACK_MODE_TRUESPEECH 8 // Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1
-#define PLAYBACK_MODE_ULAW 2 // Selects: 64 Kbit/sec MuA-law PCM
-#define PLAYBACK_MODE_ALAW 10 // Selects: 64 Kbit/sec A-law PCM
-#define PLAYBACK_MODE_16LINEAR 6 // Selects: 128 Kbit/sec 16-bit linear
-#define PLAYBACK_MODE_8LINEAR 4 // Selects: 64 Kbit/sec 8-bit signed linear
-#define PLAYBACK_MODE_8LINEAR_WSS 5 // Selects: 64 Kbit/sec WSS 8-bit unsigned linear
-
-#define RECORD_MODE_COMPRESSED 0 // Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729
-#define RECORD_MODE_TRUESPEECH 0 // Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps
-#define RECORD_MODE_ULAW 4 // Selects: 64 Kbit/sec Mu-law PCM
-#define RECORD_MODE_ALAW 12 // Selects: 64 Kbit/sec A-law PCM
-#define RECORD_MODE_16LINEAR 5 // Selects: 128 Kbit/sec 16-bit linear
-#define RECORD_MODE_8LINEAR 6 // Selects: 64 Kbit/sec 8-bit signed linear
-#define RECORD_MODE_8LINEAR_WSS 7 // Selects: 64 Kbit/sec WSS 8-bit unsigned linear
+#define PLAYBACK_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
+#define PLAYBACK_MODE_TRUESPEECH_V40 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
+#define PLAYBACK_MODE_TRUESPEECH 8 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps Version 5.1 */
+#define PLAYBACK_MODE_ULAW 2 /* Selects: 64 Kbit/sec MuA-law PCM */
+#define PLAYBACK_MODE_ALAW 10 /* Selects: 64 Kbit/sec A-law PCM */
+#define PLAYBACK_MODE_16LINEAR 6 /* Selects: 128 Kbit/sec 16-bit linear */
+#define PLAYBACK_MODE_8LINEAR 4 /* Selects: 64 Kbit/sec 8-bit signed linear */
+#define PLAYBACK_MODE_8LINEAR_WSS 5 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
+
+#define RECORD_MODE_COMPRESSED 0 /* Selects: Compressed modes, TrueSpeech 8.5-4.1, G.723.1, G.722, G.728, G.729 */
+#define RECORD_MODE_TRUESPEECH 0 /* Selects: TrueSpeech 8.5, 6.3, 5.3, 4.8 or 4.1 Kbps */
+#define RECORD_MODE_ULAW 4 /* Selects: 64 Kbit/sec Mu-law PCM */
+#define RECORD_MODE_ALAW 12 /* Selects: 64 Kbit/sec A-law PCM */
+#define RECORD_MODE_16LINEAR 5 /* Selects: 128 Kbit/sec 16-bit linear */
+#define RECORD_MODE_8LINEAR 6 /* Selects: 64 Kbit/sec 8-bit signed linear */
+#define RECORD_MODE_8LINEAR_WSS 7 /* Selects: 64 Kbit/sec WSS 8-bit unsigned linear */
enum SLIC_STATES {
PLD_SLIC_STATE_OC = 0,
char enable;
char en_filter;
unsigned int filter;
- unsigned int state; // State 0 when cadence has not started.
+ unsigned int state; /* State 0 when cadence has not started. */
- unsigned int on1; // State 1
+ unsigned int on1; /* State 1 */
- unsigned long on1min; // State 1 - 10% + jiffies
- unsigned long on1dot; // State 1 + jiffies
+ unsigned long on1min; /* State 1 - 10% + jiffies */
+ unsigned long on1dot; /* State 1 + jiffies */
- unsigned long on1max; // State 1 + 10% + jiffies
+ unsigned long on1max; /* State 1 + 10% + jiffies */
- unsigned int off1; // State 2
+ unsigned int off1; /* State 2 */
unsigned long off1min;
+ unsigned long off1dot; /* State 2 + jiffies */
unsigned long off1max;
- unsigned int on2; // State 3
+ unsigned int on2; /* State 3 */
unsigned long on2min;
unsigned long on2dot;
unsigned long on2max;
- unsigned int off2; // State 4
+ unsigned int off2; /* State 4 */
unsigned long off2min;
+ unsigned long off2dot; /* State 4 + jiffies */
unsigned long off2max;
- unsigned int on3; // State 5
+ unsigned int on3; /* State 5 */
unsigned long on3min;
unsigned long on3dot;
unsigned long on3max;
- unsigned int off3; // State 6
+ unsigned int off3; /* State 6 */
unsigned long off3min;
+ unsigned long off3dot; /* State 6 + jiffies */
unsigned long off3max;
} IXJ_CADENCE_F;
unsigned int pots_pstn:1;
unsigned int g729_loaded:1;
unsigned int ts85_loaded:1;
- unsigned int dtmf_oob:1; // DTMF Out-Of-Band
+ unsigned int dtmf_oob:1; /* DTMF Out-Of-Band */
- unsigned int pcmciascp:1; // Smart Cable Present
+ unsigned int pcmciascp:1; /* SmartCABLE Present */
- unsigned int pcmciasct:2; // Smart Cable Type
+ unsigned int pcmciasct:2; /* SmartCABLE Type */
- unsigned int pcmciastate:3; // Smart Cable Init State
+ unsigned int pcmciastate:3; /* SmartCABLE Init State */
- unsigned int inwrite:1; // Currently writing
+ unsigned int inwrite:1; /* Currently writing */
- unsigned int inread:1; // Currently reading
+ unsigned int inread:1; /* Currently reading */
- unsigned int incheck:1; // Currently checking the smart cable
+ unsigned int incheck:1; /* Currently checking the SmartCABLE */
- unsigned int cidplay:1; // Currently playing Caller ID
+ unsigned int cidplay:1; /* Currently playing Caller ID */
- unsigned int cidring:1; // This is the ring for Caller ID
+ unsigned int cidring:1; /* This is the ring for Caller ID */
- unsigned int cidsent:1; // Caller ID has been sent
+ unsigned int cidsent:1; /* Caller ID has been sent */
- unsigned int cidcw_ack:1; // Caller ID CW ACK (from CPE)
-
- unsigned int x:6; // unsed bits
+ unsigned int cidcw_ack:1; /* Caller ID CW ACK (from CPE) */
+ unsigned int firstring:1; /* First ring cadence is complete */
+ unsigned int pstncheck:1; /* Currently checking the PSTN Line */
+ unsigned int pstn_rmr:1;
+ unsigned int x:3; /* unsed bits */
} IXJ_FLAGS;
/******************************************************************************
*
-* This structure represents the Internet PhoneJACK and Internet LineJACK
+* This structure holds the state of all of the Quicknet cards
*
******************************************************************************/
typedef struct {
struct phone_device p;
+ struct timer_list timer;
unsigned int board;
unsigned int DSPbase;
unsigned int XILINXbase;
unsigned int serial;
+ atomic_t DSPWrite;
struct phone_capability caplist[30];
unsigned int caps;
- unsigned int country;
+#if LINUX_VERSION_CODE < 0x020400
+ struct pnp_dev *dev;
+#else
struct pci_dev *dev;
+#endif
unsigned int cardtype;
unsigned int rec_codec;
+ unsigned int cid_rec_codec;
+ unsigned int cid_rec_volume;
+ unsigned char cid_rec_flag;
char rec_mode;
unsigned int play_codec;
unsigned int cid_play_codec;
+ unsigned int cid_play_volume;
+ unsigned char cid_play_flag;
char play_mode;
IXJ_FLAGS flags;
+ unsigned int busyflags;
unsigned int rec_frame_size;
unsigned int play_frame_size;
+ unsigned int cid_play_frame_size;
unsigned int cid_base_frame_size;
unsigned long cidcw_wait;
int aec_level;
+ int cid_play_aec_level;
int readers, writers;
- wait_queue_head_t poll_q;
- wait_queue_head_t read_q;
+#if LINUX_VERSION_CODE < 0x020400
+ struct wait_queue *poll_q;
+ struct wait_queue *read_q;
+#else
+ wait_queue_head_t poll_q;
+ wait_queue_head_t read_q;
+#endif
char *read_buffer, *read_buffer_end;
char *read_convert_buffer;
unsigned int read_buffer_size;
unsigned int read_buffer_ready;
- wait_queue_head_t write_q;
+#if LINUX_VERSION_CODE < 0x020400
+ struct wait_queue *write_q;
+#else
+ wait_queue_head_t write_q;
+#endif
char *write_buffer, *write_buffer_end;
char *write_convert_buffer;
unsigned int write_buffer_size;
char tone_state;
char maxrings;
IXJ_CADENCE *cadence_t;
+ IXJ_CADENCE *cadence_r;
int tone_cadence_state;
- IXJ_CADENCE_F cadence_f[4];
+ IXJ_CADENCE_F cadence_f[6];
DTMF dtmf;
CPTF cptf;
BYTES dsp;
int intercom;
int m_hook;
int r_hook;
+ int p_hook;
char pstn_envelope;
char pstn_cid_intr;
unsigned char fskz;
unsigned char fskphase;
unsigned char fskcnt;
+ unsigned int cidsize;
+ unsigned int cidcnt;
unsigned pstn_cid_received;
PHONE_CID cid;
PHONE_CID cid_send;
+ unsigned long pstn_ring_int;
unsigned long pstn_ring_start;
unsigned long pstn_ring_stop;
unsigned long pstn_winkstart;
+ unsigned long pstn_last_rmr;
+ unsigned long pstn_prev_rmr;
+ unsigned long pots_winkstart;
unsigned int winktime;
unsigned long flash_end;
char port;
+ char hookstate;
union telephony_exception ex;
+ union telephony_exception ex_sig;
+ int ixj_signals[35];
+ IXJ_SIGDEF sigdef;
char daa_mode;
char daa_country;
unsigned long pstn_sleeptil;
unsigned long timerchecks;
unsigned long txreadycheck;
unsigned long rxreadycheck;
+ unsigned long statuswait;
+ unsigned long statuswaitfail;
+ unsigned long pcontrolwait;
+ unsigned long pcontrolwaitfail;
+ unsigned long iscontrolready;
+ unsigned long iscontrolreadyfail;
+ unsigned long pstnstatecheck;
+#ifdef IXJ_DYN_ALLOC
+ short *fskdata;
+#else
short fskdata[8000];
+#endif
+ int fsksize;
int fskdcnt;
} IXJ;
-int ixj_WriteDSPCommand(unsigned short, IXJ *);
-
typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
-int ixj_register(int index, IXJ_REGFUNC regfunc);
-int ixj_unregister(int index);
+extern IXJ *ixj_pcmcia_probe(unsigned long, unsigned long);
+
--- /dev/null
+#include "ixj-ver.h"
+
+#include <linux/module.h>
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/errno.h> /* error codes */
+#include <linux/slab.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "ixj.h"
+
+/*
+ * PCMCIA service support for Quicknet cards
+ */
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#else
+#define DEBUG(n, args...)
+#endif
+
+typedef struct ixj_info_t {
+ int ndev;
+ dev_node_t node;
+ struct ixj *port;
+} ixj_info_t;
+
+static dev_link_t *ixj_attach(void);
+static void ixj_detach(dev_link_t *);
+static void ixj_config(dev_link_t * link);
+static void ixj_cs_release(u_long arg);
+static int ixj_event(event_t event, int priority, event_callback_args_t * args);
+static dev_info_t dev_info = "ixj_cs";
+static dev_link_t *dev_list = NULL;
+
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+ error_info_t err =
+ {
+ func, ret
+ };
+ CardServices(ReportError, handle, &err);
+}
+
+static dev_link_t *ixj_attach(void)
+{
+ client_reg_t client_reg;
+ dev_link_t *link;
+ int ret;
+ DEBUG(0, "ixj_attach()\n");
+ /* Create new ixj device */
+ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+ if (!link)
+ return NULL;
+ memset(link, 0, sizeof(struct dev_link_t));
+ link->release.function = &ixj_cs_release;
+ link->release.data = (u_long) link;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = 3;
+ link->conf.Vcc = 50;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+ link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+ if (!link->priv)
+ return NULL;
+ memset(link->priv, 0, sizeof(struct ixj_info_t));
+ /* Register with Card Services */
+ link->next = dev_list;
+ dev_list = link;
+ client_reg.dev_info = &dev_info;
+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+ client_reg.EventMask =
+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+ client_reg.event_handler = &ixj_event;
+ client_reg.Version = 0x0210;
+ client_reg.event_callback_args.client_data = link;
+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
+ if (ret != CS_SUCCESS) {
+ cs_error(link->handle, RegisterClient, ret);
+ ixj_detach(link);
+ return NULL;
+ }
+ return link;
+}
+
+static void ixj_detach(dev_link_t * link)
+{
+ dev_link_t **linkp;
+ long flags;
+ int ret;
+ DEBUG(0, "ixj_detach(0x%p)\n", link);
+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+ if (*linkp == link)
+ break;
+ if (*linkp == NULL)
+ return;
+ save_flags(flags);
+ cli();
+ if (link->state & DEV_RELEASE_PENDING) {
+ del_timer(&link->release);
+ link->state &= ~DEV_RELEASE_PENDING;
+ }
+ restore_flags(flags);
+ if (link->state & DEV_CONFIG)
+ ixj_cs_release((u_long) link);
+ if (link->handle) {
+ ret = CardServices(DeregisterClient, link->handle);
+ if (ret != CS_SUCCESS)
+ cs_error(link->handle, DeregisterClient, ret);
+ }
+ /* Unlink device structure, free bits */
+ *linkp = link->next;
+ kfree(link->priv);
+ kfree(link);
+}
+
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+
+static void ixj_get_serial(dev_link_t * link, IXJ * j)
+{
+ client_handle_t handle;
+ tuple_t tuple;
+ u_short buf[128];
+ char *str;
+ int last_ret, last_fn, i, place;
+ handle = link->handle;
+ DEBUG(0, "ixj_get_serial(0x%p)\n", link);
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 80;
+ tuple.Attributes = 0;
+ tuple.DesiredTuple = CISTPL_VERS_1;
+ CS_CHECK(GetFirstTuple, handle, &tuple);
+ CS_CHECK(GetTupleData, handle, &tuple);
+ str = (char *) buf;
+ printk("PCMCIA Version %d.%d\n", str[0], str[1]);
+ str += 2;
+ printk("%s", str);
+ str = str + strlen(str) + 1;
+ printk(" %s", str);
+ str = str + strlen(str) + 1;
+ place = 1;
+ for (i = strlen(str) - 1; i >= 0; i--) {
+ switch (str[i]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ j->serial += (str[i] - 48) * place;
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ j->serial += (str[i] - 55) * place;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ j->serial += (str[i] - 87) * place;
+ break;
+ }
+ place = place * 0x10;
+ }
+ str = str + strlen(str) + 1;
+ printk(" version %s\n", str);
+ cs_failed:
+ return;
+}
+
+static void ixj_config(dev_link_t * link)
+{
+ IXJ *j;
+ client_handle_t handle;
+ ixj_info_t *info;
+ tuple_t tuple;
+ u_short buf[128];
+ cisparse_t parse;
+ config_info_t conf;
+ cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
+ cistpl_cftable_entry_t dflt =
+ {
+ 0
+ };
+ int last_ret, last_fn;
+ handle = link->handle;
+ info = link->priv;
+ DEBUG(0, "ixj_config(0x%p)\n", link);
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.Attributes = 0;
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ CS_CHECK(GetFirstTuple, handle, &tuple);
+ CS_CHECK(GetTupleData, handle, &tuple);
+ CS_CHECK(ParseTuple, handle, &tuple, &parse);
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+ link->state |= DEV_CONFIG;
+ CS_CHECK(GetConfigurationInfo, handle, &conf);
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
+ CS_CHECK(GetFirstTuple, handle, &tuple);
+ while (1) {
+ CFG_CHECK(GetTupleData, handle, &tuple);
+ CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->conf.ConfigIndex = cfg->index;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin == 2) {
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ CFG_CHECK(RequestIO, link->handle, &link->io);
+ /* If we've got this far, we're done */
+ break;
+ }
+ next_entry:
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ CS_CHECK(GetNextTuple, handle, &tuple);
+ }
+
+ CS_CHECK(RequestConfiguration, handle, &link->conf);
+
+ /*
+ * Register the card with the core.
+ */
+ j=ixj_pcmcia_probe(link->io.BasePort1,link->io.BasePort1 + 0x10);
+
+ info->ndev = 1;
+ info->node.major = PHONE_MAJOR;
+ link->dev = &info->node;
+ ixj_get_serial(link, j);
+ link->state &= ~DEV_CONFIG_PENDING;
+ return;
+ cs_failed:
+ cs_error(link->handle, last_fn, last_ret);
+ ixj_cs_release((u_long) link);
+}
+
+static void ixj_cs_release(u_long arg)
+{
+ dev_link_t *link = (dev_link_t *) arg;
+ ixj_info_t *info = link->priv;
+ DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+ info->ndev = 0;
+ link->dev = NULL;
+ CardServices(ReleaseConfiguration, link->handle);
+ CardServices(ReleaseIO, link->handle, &link->io);
+ link->state &= ~DEV_CONFIG;
+}
+
+static int ixj_event(event_t event, int priority, event_callback_args_t * args)
+{
+ dev_link_t *link = args->client_data;
+ DEBUG(1, "ixj_event(0x%06x)\n", event);
+ switch (event) {
+ case CS_EVENT_CARD_REMOVAL:
+ link->state &= ~DEV_PRESENT;
+ if (link->state & DEV_CONFIG) {
+ link->release.expires = jiffies + (HZ / 20);
+ link->state |= DEV_RELEASE_PENDING;
+ add_timer(&link->release);
+ }
+ break;
+ case CS_EVENT_CARD_INSERTION:
+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+ ixj_config(link);
+ break;
+ case CS_EVENT_PM_SUSPEND:
+ link->state |= DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_RESET_PHYSICAL:
+ if (link->state & DEV_CONFIG)
+ CardServices(ReleaseConfiguration, link->handle);
+ break;
+ case CS_EVENT_PM_RESUME:
+ link->state &= ~DEV_SUSPEND;
+ /* Fall through... */
+ case CS_EVENT_CARD_RESET:
+ if (DEV_OK(link))
+ CardServices(RequestConfiguration, link->handle, &link->conf);
+ break;
+ }
+ return 0;
+}
+
+int __init ixj_register_pcmcia(void)
+{
+ servinfo_t serv;
+ DEBUG(0, "%s\n", version);
+ CardServices(GetCardServicesInfo, &serv);
+ if (serv.Revision != CS_RELEASE_CODE) {
+ printk(KERN_NOTICE "ixj_cs: Card Services release does not match!\n");
+ return -EINVAL;
+ }
+ register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
+ return 0;
+}
+
+static void ixj_pcmcia_unload(void)
+{
+ DEBUG(0, "ixj_cs: unloading\n");
+ unregister_pcmcia_driver(&dev_info);
+ while (dev_list != NULL)
+ ixj_detach(dev_list);
+}
+
+module_init(ixj_register_pcmcia);
+module_exit(ixj_pcmcia_unload);
+
+MODULE_LICENSE("GPL");
+
module_init(telephony_init);
module_exit(telephony_exit);
+MODULE_LICENSE("GPL");
+
EXPORT_SYMBOL(phone_register_device);
EXPORT_SYMBOL(phone_unregister_device);
int chix;
int ret, cnt = 0;
int parent_devnum = 0;
- char *pages_start, *data_end;
+ char *pages_start, *data_end, *speed;
unsigned int length;
ssize_t total_written = 0;
* So the root hub's parent is 0 and any device that is
* plugged into the root hub has a parent of 0.
*/
- data_end = pages_start + sprintf(pages_start, format_topo, bus->busnum, level, parent_devnum, index, count,
- usbdev->devnum, usbdev->slow ? "1.5" : "12 ", usbdev->maxchild);
+ switch (usbdev->speed) {
+ case USB_SPEED_LOW:
+ speed = "1.5"; break;
+ case USB_SPEED_UNKNOWN: /* usb 1.1 root hub code */
+ case USB_SPEED_FULL:
+ speed = "12 "; break;
+ case USB_SPEED_HIGH:
+ speed = "480"; break;
+ default:
+ speed = "?? ";
+ }
+ data_end = pages_start + sprintf(pages_start, format_topo,
+ bus->busnum, level, parent_devnum,
+ index, count, usbdev->devnum,
+ speed, usbdev->maxchild);
/*
* level = topology-tier level;
* parent_devnum = parent device number;
struct usbdevfs_connectinfo ci;
ci.devnum = ps->dev->devnum;
- ci.slow = ps->dev->slow;
+ ci.slow = ps->dev->speed == USB_SPEED_LOW;
if (copy_to_user(arg, &ci, sizeof(ci)))
return -EFAULT;
return 0;
static int khubd_pid = 0; /* PID of khubd */
static DECLARE_COMPLETION(khubd_exited);
+#ifdef DEBUG
+static inline char *portspeed (int portstatus)
+{
+ if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED))
+ return "480 Mb/s";
+ else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED))
+ return "1.5 Mb/s";
+ else
+ return "12 Mb/s";
+}
+#endif
+
static int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size)
{
return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
/* Enable power to the ports */
dbg("enabling power on all ports");
- for (i = 0; i < hub->nports; i++)
+ for (i = 0; i < hub->descriptor->bNbrPorts; i++)
usb_set_port_feature(hub->dev, i + 1, USB_PORT_FEAT_POWER);
/* Wait for power to be enabled */
unsigned int pipe;
int i, maxp, ret;
- hub->descriptor = kmalloc(HUB_DESCRIPTOR_MAX_SIZE, GFP_KERNEL);
+ hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
if (!hub->descriptor) {
- err("Unable to kmalloc %d bytes for hub descriptor", HUB_DESCRIPTOR_MAX_SIZE);
+ err("Unable to kmalloc %d bytes for hub descriptor", sizeof(*hub->descriptor));
return -1;
}
/* Request the entire hub descriptor. */
- ret = usb_get_hub_descriptor(dev, hub->descriptor, HUB_DESCRIPTOR_MAX_SIZE);
+ ret = usb_get_hub_descriptor(dev, hub->descriptor, sizeof(*hub->descriptor));
/* <hub->descriptor> is large enough for a hub with 127 ports;
* the hub can/will return fewer bytes here. */
if (ret < 0) {
return -1;
}
- le16_to_cpus(&hub->descriptor->wHubCharacteristics);
+ dev->maxchild = hub->descriptor->bNbrPorts;
+ info("%d port%s detected", hub->descriptor->bNbrPorts, (hub->descriptor->bNbrPorts == 1) ? "" : "s");
- hub->nports = dev->maxchild = hub->descriptor->bNbrPorts;
- info("%d port%s detected", hub->nports, (hub->nports == 1) ? "" : "s");
+ le16_to_cpus(&hub->descriptor->wHubCharacteristics);
if (hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
dbg("part of a compound device");
break;
}
+ switch (dev->descriptor.bDeviceProtocol) {
+ case 0:
+ break;
+ case 1:
+ dbg("Single TT");
+ break;
+ case 2:
+ dbg("Multiple TT");
+ break;
+ default:
+ dbg("Unrecognized hub protocol %d",
+ dev->descriptor.bDeviceProtocol);
+ break;
+ }
+
+ switch (hub->descriptor->wHubCharacteristics & HUB_CHAR_TTTT) {
+ case 0x00:
+ if (dev->descriptor.bDeviceProtocol != 0)
+ dbg("TT requires at most 8 FS bit times");
+ break;
+ case 0x20:
+ dbg("TT requires at most 16 FS bit times");
+ break;
+ case 0x40:
+ dbg("TT requires at most 24 FS bit times");
+ break;
+ case 0x60:
+ dbg("TT requires at most 32 FS bit times");
+ break;
+ }
+
+ dbg("Port indicators are %s supported",
+ (hub->descriptor->wHubCharacteristics & HUB_CHAR_PORTIND) ? "" : "not");
+
dbg("power on to power good time: %dms", hub->descriptor->bPwrOn2PwrGood * 2);
dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent);
int i;
/* Disconnect any attached devices */
- for (i = 0; i < hub->nports; i++) {
+ for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
if (dev->children[i])
usb_disconnect(&dev->children[i]);
}
#define HUB_LONG_RESET_TIME 200
#define HUB_RESET_TIMEOUT 500
+/* return: -1 on error, 0 on success, 1 on disconnect. */
static int usb_hub_port_wait_reset(struct usb_device *hub, int port,
struct usb_device *dev, unsigned int delay)
{
portstatus = le16_to_cpu(portsts.wPortStatus);
portchange = le16_to_cpu(portsts.wPortChange);
dbg("port %d, portstatus %x, change %x, %s", port + 1,
- portstatus, portchange,
- portstatus & (1 << USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+ portstatus, portchange, portspeed (portstatus));
+
+ /* Device went away? */
+ if (!(portstatus & USB_PORT_STAT_CONNECTION))
+ return 1;
/* bomb out completely if something weird happened */
- if ((portchange & USB_PORT_STAT_C_CONNECTION) ||
- !(portstatus & USB_PORT_STAT_CONNECTION))
+ if ((portchange & USB_PORT_STAT_C_CONNECTION))
return -1;
/* if we`ve finished resetting, then break out of the loop */
if (!(portstatus & USB_PORT_STAT_RESET) &&
(portstatus & USB_PORT_STAT_ENABLE)) {
- dev->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+ if (portstatus & USB_PORT_STAT_HIGH_SPEED)
+ dev->speed = USB_SPEED_HIGH;
+ else if (portstatus & USB_PORT_STAT_LOW_SPEED)
+ dev->speed = USB_SPEED_LOW;
+ else
+ dev->speed = USB_SPEED_FULL;
return 0;
}
return -1;
}
+/* return: -1 on error, 0 on success, 1 on disconnect. */
static int usb_hub_port_reset(struct usb_device *hub, int port,
struct usb_device *dev, unsigned int delay)
{
- int i;
+ int i, status;
/* Reset the port */
for (i = 0; i < HUB_RESET_TRIES; i++) {
usb_set_port_feature(hub, port + 1, USB_PORT_FEAT_RESET);
- /* return success if the port reset OK */
- if (!usb_hub_port_wait_reset(hub, port, dev, delay)) {
+ /* return on disconnect or reset */
+ status = usb_hub_port_wait_reset(hub, port, dev, delay);
+ if (status != -1) {
usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_RESET);
- return 0;
+ return status;
}
dbg("port %d of hub %d not enabled, trying reset again...",
portstatus = le16_to_cpu(portsts->wPortStatus);
portchange = le16_to_cpu(portsts->wPortChange);
- dbg("port %d, portstatus %x, change %x, %s", port + 1, portstatus,
- portchange, portstatus & (1 << USB_PORT_FEAT_LOWSPEED) ? "1.5 Mb/s" : "12 Mb/s");
+ dbg("port %d, portstatus %x, change %x, %s",
+ port + 1, portstatus, portchange, portspeed (portstatus));
/* Clear the connection change status */
usb_clear_port_feature(hub, port + 1, USB_PORT_FEAT_C_CONNECTION);
hub->error = 0;
}
- for (i = 0; i < hub->nports; i++) {
+ for (i = 0; i < hub->descriptor->bNbrPorts; i++) {
struct usb_port_status portsts;
unsigned short portstatus, portchange;
#define USB_PORT_FEAT_RESET 4
#define USB_PORT_FEAT_POWER 8
#define USB_PORT_FEAT_LOWSPEED 9
+#define USB_PORT_FEAT_HIGHSPEED 10
#define USB_PORT_FEAT_C_CONNECTION 16
#define USB_PORT_FEAT_C_ENABLE 17
#define USB_PORT_FEAT_C_SUSPEND 18
#define USB_PORT_FEAT_C_OVER_CURRENT 19
#define USB_PORT_FEAT_C_RESET 20
+#define USB_PORT_FEAT_TEST 21
+#define USB_PORT_FEAT_INDICATOR 22
+/*
+ * Hub Status and Hub Change results
+ * See USB 2.0 spec Table 11-19 and Table 11-20
+ */
struct usb_port_status {
__u16 wPortStatus;
__u16 wPortChange;
} __attribute__ ((packed));
-/* wPortStatus bits */
+/*
+ * wPortStatus bit field
+ * See USB 2.0 spec Table 11-21
+ */
#define USB_PORT_STAT_CONNECTION 0x0001
#define USB_PORT_STAT_ENABLE 0x0002
#define USB_PORT_STAT_SUSPEND 0x0004
#define USB_PORT_STAT_OVERCURRENT 0x0008
#define USB_PORT_STAT_RESET 0x0010
+/* bits 5 for 7 are reserved */
#define USB_PORT_STAT_POWER 0x0100
#define USB_PORT_STAT_LOW_SPEED 0x0200
-
-/* wPortChange bits */
+#define USB_PORT_STAT_HIGH_SPEED 0x0400
+#define USB_PORT_STAT_TEST 0x0800
+#define USB_PORT_STAT_INDICATOR 0x1000
+/* bits 13 to 15 are reserved */
+
+/*
+ * wPortChange bit field
+ * See USB 2.0 spec Table 11-22
+ * Bits 0 to 4 shown, bits 5 to 15 are reserved
+ */
#define USB_PORT_STAT_C_CONNECTION 0x0001
#define USB_PORT_STAT_C_ENABLE 0x0002
#define USB_PORT_STAT_C_SUSPEND 0x0004
#define USB_PORT_STAT_C_OVERCURRENT 0x0008
#define USB_PORT_STAT_C_RESET 0x0010
-/* wHubCharacteristics (masks) */
-#define HUB_CHAR_LPSM 0x0003
-#define HUB_CHAR_COMPOUND 0x0004
-#define HUB_CHAR_OCPM 0x0018
+/*
+ * wHubCharacteristics (masks)
+ * See USB 2.0 spec Table 11-13, offset 3
+ */
+#define HUB_CHAR_LPSM 0x0003 /* D1 .. D0 */
+#define HUB_CHAR_COMPOUND 0x0004 /* D2 */
+#define HUB_CHAR_OCPM 0x0018 /* D4 .. D3 */
+#define HUB_CHAR_TTTT 0x0060 /* D6 .. D5 */
+#define HUB_CHAR_PORTIND 0x0080 /* D7 */
struct usb_hub_status {
__u16 wHubStatus;
} __attribute__ ((packed));
/*
- *Hub Status & Hub Change bit masks
+ * Hub Status & Hub Change bit masks
+ * See USB 2.0 spec Table 11-19 and Table 11-20
+ * Bits 0 and 1 for wHubStatus and wHubChange
+ * Bits 2 to 15 are reserved for both
*/
#define HUB_STATUS_LOCAL_POWER 0x0001
#define HUB_STATUS_OVERCURRENT 0x0002
-
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
-#define HUB_DESCRIPTOR_MAX_SIZE 39 /* enough for 127 ports on a hub */
/* Hub descriptor */
struct usb_hub_descriptor {
- __u8 bLength;
+ __u8 bDescLength;
__u8 bDescriptorType;
__u8 bNbrPorts;
__u16 wHubCharacteristics;
__u8 bPwrOn2PwrGood;
__u8 bHubContrCurrent;
-
/* DeviceRemovable and PortPwrCtrlMask want to be variable-length
bitmaps that hold max 256 entries, but for now they're ignored */
- __u8 bitmap[0];
+ __u8 bitmap[2 * ((USB_MAXCHILDREN + 1 + 7) / 8)];
} __attribute__ ((packed));
struct usb_device;
struct list_head event_list;
- /* Number of ports on the hub */
- int nports;
-
struct usb_hub_descriptor *descriptor;
atomic_t refcnt;
/* create frame buffers, and make circular ring */
for (i = 0; i < default_fbufs; i++) {
if (pdev->fbuf[i].data == NULL) {
- kbuf = vmalloc(FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
+ kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
if (kbuf == NULL) {
Err("Failed to allocate frame buffer %d.\n", i);
return -ENOMEM;
}
pdev->fbuf[i].data = kbuf;
- memset(kbuf, 0, FRAME_SIZE);
+ memset(kbuf, 0, PWC_FRAME_SIZE);
}
}
MODULE_DESCRIPTION("Philips USB webcam driver");
MODULE_AUTHOR("Nemosoft Unv. <nemosoft@smcc.demon.nl>");
+MODULE_LICENSE("GPL");
static int __init usb_pwc_init(void)
{
/* Frame buffers: contains compressed or uncompressed video data. */
#define MAX_FRAMES 5
/* Maximum size after decompression is 640x480 YUV data, 1.5 * 640 * 480 */
-#define FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
+#define PWC_FRAME_SIZE (460800 + TOUCAM_HEADER_SIZE + TOUCAM_TRAILER_SIZE)
/* Absolute maximum number of buffers available for mmap() */
#define MAX_IMAGES 4
* - Jeroen Vreeken
*/
-static const char version[] = "0.22";
+static const char version[] = "0.23";
#include <linux/config.h>
#include <linux/module.h>
}
}
}
-
- if (se401->frame[framenr].grabstate==FRAME_DONE)
+
+ if (se401->frame[framenr].grabstate==FRAME_DONE)
if (se401->enhance)
enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
return 0;
struct usb_se401 *se401 = (struct usb_se401 *)dev;
int err = 0;
+ /* we are called with the BKL held */
MOD_INC_USE_COUNT;
- down(&se401->lock);
+ se401->user=1;
se401->fbuf=rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
if(!se401->fbuf) err=-ENOMEM;
if (err) {
MOD_DEC_USE_COUNT;
- up(&se401->lock);
- return err;
+ se401->user = 0;
}
-
- se401->user=1;
- up(&se401->lock);
-
- return 0;
+ return err;
}
static void se401_close(struct video_device *dev)
{
+ /* called with BKL held */
struct usb_se401 *se401 = (struct usb_se401 *)dev;
int i;
- down(&se401->lock);
-
for (i=0; i<SE401_NUMFRAMES; i++)
se401->frame[i].grabstate=FRAME_UNUSED;
if (se401->streaming)
rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
se401->user=0;
- up(&se401->lock);
- if (!se401->dev) {
+ if (se401->removed) {
video_unregister_device(&se401->vdev);
kfree(se401->width);
kfree(se401->height);
return -EINVAL;
if (se401_set_size(se401, vw.width, vw.height))
return -EINVAL;
-
+
return 0;
}
case VIDIOCGWIN:
if(frame <0 || frame >= SE401_NUMFRAMES)
return -EINVAL;
-
+
ret=se401_newframe(se401, frame);
se401->frame[frame].grabstate=FRAME_UNUSED;
return ret;
ret=se401_newframe(se401, 0);
- if (!ret) {
- copy_to_user(buf, se401->frame[0].data, realcount);
- } else {
- realcount=ret;
- }
se401->frame[0].grabstate=FRAME_UNUSED;
+ if (ret)
+ return ret;
+ if (copy_to_user(buf, se401->frame[0].data, realcount))
+ return -EFAULT;
+ return realcount;
return realcount;
}
unsigned long page, pos;
down(&se401->lock);
-
+
if (se401->dev == NULL) {
up(&se401->lock);
return -EIO;
info("int urb burned down");
return 1;
}
-
+
/* Flash the led */
se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
- if (se401_init(se401))
+ if (se401_init(se401)) {
+ kfree(se401);
return NULL;
+ }
+
memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
+ init_waitqueue_head(&se401->wq);
+ init_MUTEX(&se401->lock);
+ wmb();
+
if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+ kfree(se401);
err("video_register_device failed");
return NULL;
}
info("registered new video device: video%d", se401->vdev.minor);
- init_waitqueue_head(&se401->wq);
- init_MUTEX(&se401->lock);
-
return se401;
}
static void se401_disconnect(struct usb_device *dev, void *ptr)
{
- int i;
struct usb_se401 *se401 = (struct usb_se401 *) ptr;
+ lock_kernel();
/* We don't want people trying to open up the device */
- if (!se401->user)
- video_unregister_device(&se401->vdev);
+ if (!se401->user){
+ video_unregister_device(&se401->vdev);
+ usb_se401_remove_disconnected(se401);
+ } else {
+ se401->removed = 1;
+ }
+ unlock_kernel();
+}
- usb_driver_release_interface(&se401_driver,
- &se401->dev->actconfig->interface[se401->iface]);
+static inline void usb_se401_remove_disconnected (struct usb_se401 *se401)
+{
+ int i;
se401->dev = NULL;
se401->frame[0].grabstate = FRAME_ERROR;
se401->streaming = 0;
- if (waitqueue_active(&se401->wq))
- wake_up_interruptible(&se401->wq);
+ wake_up_interruptible(&se401->wq);
for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
se401->urb[i]->next = NULL;
#endif
/* Free the memory */
- if (!se401->user) {
- kfree(se401->width);
- kfree(se401->height);
- kfree(se401);
- se401 = NULL;
- }
+ kfree(se401->width);
+ kfree(se401->height);
+ kfree(se401);
}
-
static struct usb_driver se401_driver = {
name: "se401",
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
struct semaphore lock;
int user; /* user count for exclusive use */
+ int removed; /* device disconnected */
int streaming; /* Are we streaming video? */
int nullpackets;
};
+static inline void usb_se401_remove_disconnected (struct usb_se401 *se401);
+
#endif
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * 2001_Aug_30 gkh
+ * fixed oops in write_bulk_callback.
+ *
+ * 2001_Aug_28 gkh
+ * reworked buffer logic to be like other usb-serial drivers. Hopefully
+ * removing some reported problems.
+ *
* 2001_Jun_06 gkh
* finished porting to 2.4 format.
*
/*
* Version Information
*/
-#define DRIVER_VERSION "v0.5"
+#define DRIVER_VERSION "v0.7"
#define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
-#ifndef MIN
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-
-#define PL2303_LOCK(port,flags) \
- do { \
- spin_lock_irqsave(&((struct pl2303_private *)(port->private))->lock, flags); \
- } while (0)
-
-#define PL2303_UNLOCK(port,flags) \
- do { \
- spin_unlock_irqrestore(&((struct pl2303_private *)(port->private))->lock, flags); \
- } while (0)
-
-
static __devinitdata struct usb_device_id id_table [] = {
{ USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID) },
MODULE_DEVICE_TABLE (usb, id_table);
-struct pl2303_private {
- spinlock_t lock;
- unsigned char *xmit_buf;
- int xmit_head;
- int xmit_tail;
- int xmit_cnt;
-};
/* function prototypes for a PL2303 serial converter */
-static int pl2303_startup (struct usb_serial *serial);
static int pl2303_open (struct usb_serial_port *port, struct file *filp);
static void pl2303_close (struct usb_serial_port *port, struct file *filp);
static void pl2303_set_termios (struct usb_serial_port *port,
struct termios *old);
static int pl2303_ioctl (struct usb_serial_port *port, struct file *file,
unsigned int cmd, unsigned long arg);
-static void pl2303_throttle (struct usb_serial_port *port);
-static void pl2303_unthrottle (struct usb_serial_port *port);
static void pl2303_read_int_callback (struct urb *urb);
static void pl2303_read_bulk_callback (struct urb *urb);
static void pl2303_write_bulk_callback (struct urb *urb);
static int pl2303_write (struct usb_serial_port *port, int from_user,
const unsigned char *buf, int count);
-static int pl2303_write_room(struct usb_serial_port *port);
-static int pl2303_chars_in_buffer(struct usb_serial_port *port);
static void pl2303_break_ctl(struct usb_serial_port *port,int break_state);
-static void start_xmit (struct usb_serial_port *port);
/* All of the device info needed for the PL2303 SIO serial converter */
num_ports: 1,
open: pl2303_open,
close: pl2303_close,
- throttle: pl2303_throttle,
- unthrottle: pl2303_unthrottle,
write: pl2303_write,
ioctl: pl2303_ioctl,
- write_room: pl2303_write_room,
- chars_in_buffer: pl2303_chars_in_buffer,
break_ctl: pl2303_break_ctl,
set_termios: pl2303_set_termios,
read_bulk_callback: pl2303_read_bulk_callback,
read_int_callback: pl2303_read_int_callback,
write_bulk_callback: pl2303_write_bulk_callback,
- startup: pl2303_startup,
};
-#define WDR_TIMEOUT (HZ * 5 ) /* default urb timeout */
-
-static unsigned char *tmp_buf;
-static DECLARE_MUTEX (tmp_buf_sem);
-
+static int pl2303_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
+{
+ int result;
-static int
-pl2303_write (struct usb_serial_port *port, int from_user,
- const unsigned char *buf, int count)
-{ /* pl2303_write */
- struct pl2303_private *info = (struct pl2303_private *)port->private;
- unsigned long flags;
- int c,ret=0;
- struct tty_struct *tty=port->tty;
-
- dbg ("pl2303_write port %d, %d bytes", port->number, count);
+ dbg (__FUNCTION__ " - port %d, %d bytes", port->number, count);
- if (!info) {
- return -ENODEV;
+ if (!port->tty) {
+ err (__FUNCTION__ " - no tty???");
+ return 0;
}
- if (!tty || !info->xmit_buf || !tmp_buf) {
+ if (port->write_urb->status == -EINPROGRESS) {
+ dbg (__FUNCTION__ " - already writing");
return 0;
}
-
- PL2303_LOCK(port,flags);
-
-
+ count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
if (from_user) {
- down(&tmp_buf_sem);
- while (1) {
- c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- if (c <= 0)
- break;
-
- c -= copy_from_user(tmp_buf, buf, c);
- if (!c) {
- if (!ret) {
- ret = -EFAULT;
- }
- break;
- }
- c = MIN(c, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- memcpy(info->xmit_buf + info->xmit_head, tmp_buf, c);
- info->xmit_head = ((info->xmit_head + c) & (SERIAL_XMIT_SIZE-1));
- info->xmit_cnt += c;
- buf += c;
- count -= c;
- ret += c;
- }
- up(&tmp_buf_sem);
+ if (copy_from_user (port->write_urb->transfer_buffer, buf, count))
+ return -EFAULT;
} else {
- while (1) {
- c = MIN(count, MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
- SERIAL_XMIT_SIZE - info->xmit_head));
- if (c <= 0) {
- break;
- }
- memcpy(info->xmit_buf + info->xmit_head, buf, c);
- info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
- info->xmit_cnt += c;
- buf += c;
- count -= c;
- ret += c;
- }
+ memcpy (port->write_urb->transfer_buffer, buf, count);
}
- PL2303_UNLOCK(port, flags);
-
- if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) {
- start_xmit(port);
- }
- return ret;
-}
-
-static int pl2303_write_room(struct usb_serial_port *port)
-{
- struct pl2303_private *info = (struct pl2303_private *)port->private;
- int ret;
-
- if (!info)
- return 0;
-
- ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
- if (ret < 0)
- ret = 0;
- return ret;
+
+ usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);
+
+ port->write_urb->transfer_buffer_length = count;
+ port->write_urb->dev = port->serial->dev;
+ result = usb_submit_urb (port->write_urb);
+ if (result)
+ err(__FUNCTION__ " - failed submitting write urb, error %d", result);
+ else
+ result = count;
+
+ return result;
}
-static int pl2303_chars_in_buffer(struct usb_serial_port *port)
-{
- struct pl2303_private *info = (struct pl2303_private *)port->private;
-
- if (!info)
- return 0;
-
- return info->xmit_cnt;
-}
-
-static void pl2303_throttle(struct usb_serial_port *port)
-{
-#if 0
- //struct usb_serial *serial = port->serial;
- struct tty_struct *tty=port->tty;
- unsigned long flags;
-
-
- char buf[64];
-
- dbg("throttle %s: %d....", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
-
-//FIXME FIXME FIXME
- if (I_IXOFF(tty))
- rs_send_xchar(tty, STOP_CHAR(tty));
-
- PL2303_LOCK(port,flags);
- //Should remove read request if one is present
- PL2303_UNLOCK(port,flags);
-#endif
-}
-
-static void pl2303_unthrottle(struct usb_serial_port *port)
-{
-#if 0
- //struct usb_serial *serial = port->serial;
- struct tty_struct *tty=port->tty;
- unsigned long flags;
-
-
- char buf[64];
-
- dbg("unthrottle %s: %d....", tty_name(tty, buf),
- tty->ldisc.chars_in_buffer(tty));
-
- //FIXME FIXME FIXME FIXME FIXME
- if (I_IXOFF(tty)) {
- if (info->x_char)
- info->x_char = 0;
- else
- rs_send_xchar(tty, START_CHAR(tty));
- }
-
- PL2303_LOCK(port,flags);
- //Should add read request if one is not present
- PL2303_UNLOCK(fport,flags);
-#endif
-}
static void
if (cflag & CSIZE) {
switch (cflag & CSIZE) {
+ case CS5:
+ buf[6] = 5;
+ dbg ("Setting CS5");
+ break;
case CS6:
buf[6] = 6;
dbg ("Setting CS6");
dbg ("Setting CS8");
break;
default:
- err ("CSIZE was set but not CS6-CS8");
+ err ("CSIZE was set but not CS5-CS8");
}
}
baud = 0;
switch (cflag & CBAUD) {
- case B0:
- err ("Can't do B0 yet"); //FIXME
- break;
- case B300:
- baud = 300;
- break;
- case B600:
- baud = 600;
- break;
- case B1200:
- baud = 1200;
- break;
- case B2400:
- baud = 2400;
- break;
- case B4800:
- baud = 4800;
- break;
- case B9600:
- baud = 9600;
- break;
- case B19200:
- baud = 19200;
- break;
- case B38400:
- baud = 38400;
- break;
- case B57600:
- baud = 57600;
- break;
- case B115200:
- baud = 115200;
- break;
+ case B75: baud = 75; break;
+ case B150: baud = 150; break;
+ case B300: baud = 300; break;
+ case B600: baud = 600; break;
+ case B1200: baud = 1200; break;
+ case B1800: baud = 1800; break;
+ case B2400: baud = 2400; break;
+ case B4800: baud = 4800; break;
+ case B9600: baud = 9600; break;
+ case B19200: baud = 19200; break;
+ case B38400: baud = 38400; break;
+ case B57600: baud = 57600; break;
+ case B115200: baud = 115200; break;
+ case B230400: baud = 230400; break;
+ case B460800: baud = 460800; break;
default:
- dbg ("pl2303 driver does not support the baudrate requested (fix it)");
+ err ("pl2303 driver does not support the baudrate requested (fix it)");
break;
}
}
+ /* For reference buf[4]=0 is 1 stop bits */
/* For reference buf[4]=1 is 1.5 stop bits */
+ /* For reference buf[4]=2 is 2 stop bits */
if (cflag & CSTOPB) {
buf[4] = 2;
if (cflag & PARENB) {
+ /* For reference buf[5]=0 is none parity */
+ /* For reference buf[5]=1 is odd parity */
+ /* For reference buf[5]=2 is even parity */
/* For reference buf[5]=3 is mark parity */
/* For reference buf[5]=4 is space parity */
if (cflag & PARODD) {
}
-static int
-pl2303_open (struct usb_serial_port *port, struct file *filp)
-{ /* pl2303_open */
+static int pl2303_open (struct usb_serial_port *port, struct file *filp)
+{
struct termios tmp_termios;
struct usb_serial *serial = port->serial;
unsigned char buf[10];
- int i;
-
- dbg ("pl2303_open port %d", port->number);
+ int result;
- port->active++;
-
-#define FISH(a,b,c,d) \
- i=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \
- b, a,c , d, buf, 1, 100); \
- dbg("0x%x:0x%x:0x%x:0x%x %d - %x",a,b,c,d,i,buf[0]);
-
-#define SOUP(a,b,c,d) \
- i=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \
- b, a,c , d, NULL, 0, 100); \
- dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,i);
-
-
- FISH (0xc0, 1, 0x8484, 0);
- SOUP (0x40, 1, 0x0404, 0);
- FISH (0xc0, 1, 0x8484, 0);
- FISH (0xc0, 1, 0x8383, 0);
- FISH (0xc0, 1, 0x8484, 0);
- SOUP (0x40, 1, 0x0404, 1);
- FISH (0xc0, 1, 0x8484, 0);
- FISH (0xc0, 1, 0x8383, 0);
- SOUP (0x40, 1, 0, 1);
- SOUP (0x40, 1, 1, 0xc0);
- SOUP (0x40, 1, 2, 4);
-
- /* Setup termios */
-
- if (port->active == 1) {
+ if (port_paranoia_check (port, __FUNCTION__))
+ return -ENODEV;
+
+ dbg (__FUNCTION__ "- port %d", port->number);
+
+ down (&port->sem);
+
+ ++port->open_count;
+ MOD_INC_USE_COUNT;
+
+ if (!port->active) {
+ port->active = 1;
+
+#define FISH(a,b,c,d) \
+ result=usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev,0), \
+ b, a, c, d, buf, 1, 100); \
+ dbg("0x%x:0x%x:0x%x:0x%x %d - %x",a,b,c,d,result,buf[0]);
+
+#define SOUP(a,b,c,d) \
+ result=usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev,0), \
+ b, a, c , d, NULL, 0, 100); \
+ dbg("0x%x:0x%x:0x%x:0x%x %d",a,b,c,d,result);
+
+ FISH (0xc0, 1, 0x8484, 0);
+ SOUP (0x40, 1, 0x0404, 0);
+ FISH (0xc0, 1, 0x8484, 0);
+ FISH (0xc0, 1, 0x8383, 0);
+ FISH (0xc0, 1, 0x8484, 0);
+ SOUP (0x40, 1, 0x0404, 1);
+ FISH (0xc0, 1, 0x8484, 0);
+ FISH (0xc0, 1, 0x8383, 0);
+ SOUP (0x40, 1, 0, 1);
+ SOUP (0x40, 1, 1, 0xc0);
+ SOUP (0x40, 1, 2, 4);
+
+ /* Setup termios */
*(port->tty->termios) = tty_std_termios;
port->tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- }
-
- pl2303_set_termios (port, &tmp_termios);
+ pl2303_set_termios (port, &tmp_termios);
- //FIXME: need to assert RTS and DTR if CRTSCTS off
+ //FIXME: need to assert RTS and DTR if CRTSCTS off
-
- if (port->active == 1) {
- struct pl2303_private *info;
- unsigned long flags,page;
- int i;
-
- info = (struct pl2303_private *)kmalloc (sizeof(struct pl2303_private), GFP_KERNEL);
- if (info == NULL) {
- err(__FUNCTION__ " - out of memory");
- pl2303_close (port, NULL);
- return -ENOMEM;
- }
- spin_lock_init(&info->lock);
- port->private = info;
-
-
- page = get_free_page(GFP_KERNEL);
- if (!page) {
- pl2303_close (port, NULL);
- return -ENOMEM;
- }
-
- PL2303_LOCK(port,flags);
-
- info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
-
- if (tmp_buf)
- free_page(page);
- else
- tmp_buf = (unsigned char *) page;
-
- PL2303_UNLOCK(port,flags);
-
- page = get_free_page(GFP_KERNEL);
- if (!page) {
- pl2303_close (port, NULL);
- return -ENOMEM;
- }
-
- PL2303_LOCK(port,flags);
-
- if (info->xmit_buf)
- free_page(page);
- else
- info->xmit_buf=(unsigned char *) page;
-
- PL2303_UNLOCK(port,flags);
-
-
- if ((i = usb_submit_urb (port->read_urb))) {
- err ("usb_submit_urb(read bulk 1) failed");
- dbg ("i=%d", i);
+ port->read_urb->dev = serial->dev;
+ result = usb_submit_urb (port->read_urb);
+ if (result) {
+ err(__FUNCTION__ " - failed submitting read urb, error %d", result);
+ up (&port->sem);
pl2303_close (port, NULL);
return -EPROTO;
-
}
- if ((i = usb_submit_urb (port->interrupt_in_urb))) {
- err ("usb_submit_urb(interrupt ink) failed");
- dbg ("i=%d", i);
+ port->interrupt_in_urb->dev = serial->dev;
+ result = usb_submit_urb (port->interrupt_in_urb);
+ if (result) {
+ err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result);
+ up (&port->sem);
pl2303_close (port, NULL);
-
return -EPROTO;
}
}
+ up (&port->sem);
+ return 0;
+}
- return(0);
-} /* pl2303_open */
+static void pl2303_close (struct usb_serial_port *port, struct file *filp)
+{
+ unsigned int c_cflag;
-static void
-pl2303_close (struct usb_serial_port *port, struct file *filp)
-{ /* pl2303_close */
- struct pl2303_private *info;
- unsigned int c_cflag = port->tty->termios->c_cflag;
- unsigned long flags;
+ if (port_paranoia_check (port, __FUNCTION__))
+ return;
- dbg ("pl2303_close port %d", port->number);
+ dbg (__FUNCTION__ " - port %d", port->number);
- /* shutdown our bulk reads and writes */
- if (port->active == 1) {
+ down (&port->sem);
+ --port->open_count;
+ if (port->open_count <= 0) {
+ c_cflag = port->tty->termios->c_cflag;
if (c_cflag & HUPCL) {
//FIXME: Do drop DTR
//FIXME: Do drop RTS
}
+ /* shutdown our urbs */
usb_unlink_urb (port->write_urb);
usb_unlink_urb (port->read_urb);
usb_unlink_urb (port->interrupt_in_urb);
- info = (struct pl2303_private *)port->private;
- if (info) {
- PL2303_LOCK(port,flags);
- if (info->xmit_buf) {
- unsigned char * temp;
- temp = info->xmit_buf;
- info->xmit_buf = 0;
- free_page((unsigned long) temp);
- }
- PL2303_UNLOCK(port,flags);
- }
-
- //FIXME: tmp_buf memory leak
-
-
+ port->active = 0;
+ port->open_count = 0;
}
- port->active--;
-} /* pl2303_close */
-
-/* do some startup allocations not currently performed by usb_serial_probe() */
-static int
-pl2303_startup (struct usb_serial *serial)
-{
- return(0);
+ up (&port->sem);
}
return;
}
-
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, urb->transfer_buffer);
#if 0
//FIXME need to update state of terminal lines variable
- if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": INT data read - length = %d, data = ",
- urb->actual_length);
- for (i = 0; i < urb->actual_length; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
#endif
return;
}
-static void
-pl2303_read_bulk_callback (struct urb *urb)
+
+static void pl2303_read_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
- struct usb_serial *serial = get_usb_serial (port, "pl2303_read_bulk_callback");
+ struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
int i;
+ int result;
+
+ if (port_paranoia_check (port, __FUNCTION__))
+ return;
+
+ dbg(__FUNCTION__ " - port %d", port->number);
if (!serial) {
+ dbg(__FUNCTION__ " - bad serial pointer, exiting");
return;
}
-// PL2303 mysteriously fails with -EPROTO reschedule the read
+ /* PL2303 mysteriously fails with -EPROTO reschedule the read */
if (urb->status) {
urb->status = 0;
- if (usb_submit_urb (urb))
- dbg ("failed resubmitting read bulk urb");
+ urb->dev = serial->dev;
+ result = usb_submit_urb(urb);
+ if (result)
+ err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
return;
}
- if (debug) {
- if (urb->actual_length) {
- printk (KERN_DEBUG __FILE__ ": BULK data read - length = %d, data = ",
- urb->actual_length);
- for (i = 0; i < urb->actual_length; ++i) {
- printk ("%.2x ", data[i]);
- }
- printk ("\n");
- }
- }
+ usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
tty = port->tty;
if (urb->actual_length) {
for (i = 0; i < urb->actual_length; ++i) {
if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
- dbg ("ARGH ------------ Flip buffer overrun...");
-
- break;
+ tty_flip_buffer_push(tty);
}
tty_insert_flip_char (tty, data[i], 0);
}
tty_flip_buffer_push (tty);
}
-
/* Schedule the next read*/
- if (usb_submit_urb (urb))
- dbg ("failed submitting read bulk urb");
+ urb->dev = serial->dev;
+ result = usb_submit_urb(urb);
+ if (result)
+ err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
return;
}
-static void
-pl2303_write_bulk_callback (struct urb *urb)
+static void pl2303_write_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *) urb->context;
- struct usb_serial *serial;
- struct tty_struct *tty = port->tty;
-
- dbg ("pl2303_write_bulk_callback");
-
-
- if (port_paranoia_check (port, "pl2303_write_bulk_callback")) {
- return;
- }
+ int result;
- serial = port->serial;
- if (serial_paranoia_check (serial, "pl2303_write_bulk_callback")) {
+ if (port_paranoia_check (port, __FUNCTION__))
return;
- }
-
-
+
+ dbg(__FUNCTION__ " - port %d", port->number);
+
if (urb->status) {
- dbg ("Overflow in write");
- dbg ("nonzero write bulk status received: %d", urb->status);
- //need to resubmit frame;
-
+ /* error in the urb, so we have to resubmit it */
+ if (serial_paranoia_check (port->serial, __FUNCTION__)) {
+ return;
+ }
+ dbg (__FUNCTION__ " - Overflow in write");
+ dbg (__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
port->write_urb->transfer_buffer_length = 1;
-
- //Resubmit ourselves
-
- if (usb_submit_urb (port->write_urb))
- err ("usb_submit_urb(write bulk) failed");
+ port->write_urb->dev = port->serial->dev;
+ result = usb_submit_urb (port->write_urb);
+ if (result)
+ err(__FUNCTION__ " - failed resubmitting write urb, error %d", result);
return;
}
- wake_up_interruptible (&port->write_wait);
-
- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
- (tty->ldisc.write_wakeup) (tty);
-
- wake_up_interruptible (&tty->write_wait);
-
- start_xmit(port);
+ queue_task(&port->tqueue, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
return;
}
-
-static void
-start_xmit (struct usb_serial_port *port)
-{
- struct usb_serial *serial;
- struct pl2303_private *info;
- unsigned long flags;
-
- serial = port->serial;
- info = (struct pl2303_private *)port->private;
-
- if (info) {
- PL2303_LOCK(port,flags);
-
- if (port->write_urb->status != -EINPROGRESS) {
- if (info->xmit_tail != info->xmit_head) {
-
- memcpy (port->write_urb->transfer_buffer, &info->xmit_buf[info->xmit_tail],1);
- info->xmit_cnt--;
- info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1);
-
-
- port->write_urb->transfer_buffer_length = 1;
-
-
- if (usb_submit_urb (port->write_urb))
- err ("usb_submit_urb(write bulk) failed");
-
-
- }
- }
-
- PL2303_UNLOCK(port,flags);
- }
-}
-
-
static int __init pl2303_init (void)
{
usb_serial_register (&pl2303_device);
- info(DRIVER_VERSION " : " DRIVER_DESC);
+ info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
}
/*
- * USB HandSpring Visor driver
+ * USB HandSpring Visor, Palm m50x, and Sony Clie driver
+ * (supports all of the Palm OS USB devices)
*
* Copyright (C) 1999 - 2001
* Greg Kroah-Hartman (greg@kroah.com)
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (08/30/2001) gkh
+ * Added support for the Clie devices, both the 3.5 and 4.0 os versions.
+ * Many thanks to Daniel Burke, and Bryan Payne for helping with this.
+ *
* (08/23/2001) gkh
* fixed a few potential bugs pointed out by Oliver Neukum.
*
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.3"
+#define DRIVER_VERSION "v1.4"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC "USB HandSpring Visor driver"
+#define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clie driver"
/* function prototypes for a handspring visor */
static int visor_open (struct usb_serial_port *port, struct file *filp);
{ } /* Terminating entry */
};
-static __devinitdata struct usb_device_id clie_id_table [] = {
- { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_ID) },
+static __devinitdata struct usb_device_id clie_id_3_5_table [] = {
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
+ { } /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id clie_id_4_0_table [] = {
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
{ } /* Terminating entry */
};
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
- { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
+ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
{ } /* Terminating entry */
};
read_bulk_callback: visor_read_bulk_callback,
};
-/* device info for the Sony Clie */
-static struct usb_serial_device_type clie_device = {
- name: "Sony Clie",
- id_table: clie_id_table,
+/* device info for the Sony Clie OS version 3.5 */
+static struct usb_serial_device_type clie_3_5_device = {
+ name: "Sony Clie 3.5",
+ id_table: clie_id_3_5_table,
needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
close: visor_close,
throttle: visor_throttle,
unthrottle: visor_unthrottle,
+ ioctl: visor_ioctl,
+ set_termios: visor_set_termios,
+ write: visor_write,
+ write_room: visor_write_room,
+ chars_in_buffer: visor_chars_in_buffer,
+ write_bulk_callback: visor_write_bulk_callback,
+ read_bulk_callback: visor_read_bulk_callback,
+};
+
+/* device info for the Sony Clie OS version 4.0 */
+static struct usb_serial_device_type clie_4_0_device = {
+ name: "Sony Clie 4.0",
+ id_table: clie_id_4_0_table,
+ needs_interrupt_in: MUST_HAVE_NOT, /* this device must not have an interrupt in endpoint */
+ needs_bulk_in: MUST_HAVE, /* this device must have a bulk in endpoint */
+ needs_bulk_out: MUST_HAVE, /* this device must have a bulk out endpoint */
+ num_interrupt_in: 0,
+ num_bulk_in: 2,
+ num_bulk_out: 2,
+ num_ports: 2,
+ open: visor_open,
+ close: visor_close,
+ throttle: visor_throttle,
+ unthrottle: visor_unthrottle,
+ startup: visor_startup,
shutdown: visor_shutdown,
ioctl: visor_ioctl,
set_termios: visor_set_termios,
return -ENOMEM;
}
- /* force debugging on for the palm devices for now */
- if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID)
- debug = 1;
-
dbg(__FUNCTION__);
dbg(__FUNCTION__ " - Set config to 1");
}
}
- if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID) {
- /* Palm USB Hack */
+ if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) ||
+ (serial->dev->descriptor.idVendor == SONY_VENDOR_ID)) {
+ /* Palm OS 4.0 Hack */
response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0),
PALM_GET_SOME_UNKNOWN_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
usb_serial_register (&handspring_device);
usb_serial_register (&palm_m500_device);
usb_serial_register (&palm_m505_device);
- usb_serial_register (&clie_device);
+ usb_serial_register (&clie_3_5_device);
+ usb_serial_register (&clie_4_0_device);
/* create our write urb pool and transfer buffers */
spin_lock_init (&write_urb_pool_lock);
usb_serial_deregister (&handspring_device);
usb_serial_deregister (&palm_m500_device);
usb_serial_deregister (&palm_m505_device);
- usb_serial_deregister (&clie_device);
+ usb_serial_deregister (&clie_3_5_device);
+ usb_serial_deregister (&clie_4_0_device);
spin_lock_irqsave (&write_urb_pool_lock, flags);
#define PALM_M505_ID 0x0002
#define SONY_VENDOR_ID 0x054C
-#define SONY_CLIE_ID 0x0038
-#define SONY_CLIE_320_ID 0x0066
+#define SONY_CLIE_3_5_ID 0x0038
+#define SONY_CLIE_4_0_ID 0x0066
/****************************************************************************
* Handspring Visor Vendor specific request codes (bRequest values)
* (C) Copyright 1999 Randy Dunlap
* (C) Copyright 1999 Gregory P. Smith
*
- * $Id: usb-uhci.c,v 1.267 2001/08/28 16:45:00 acher Exp $
+ * $Id: usb-uhci.c,v 1.268 2001/08/29 14:08:43 acher Exp $
*/
#include <linux/config.h>
/* This enables an extra UHCI slab for memory debugging */
#define DEBUG_SLAB
-#define VERSTR "$Revision: 1.267 $ time " __TIME__ " " __DATE__
+#define VERSTR "$Revision: 1.268 $ time " __TIME__ " " __DATE__
#include <linux/usb.h>
#include "usb-uhci.h"
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.267"
+#define DRIVER_VERSION "v1.268"
#define DRIVER_AUTHOR "Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber"
#define DRIVER_DESC "USB Universal Host Controller Interface driver"
spin_lock_irqsave (&s->urb_list_lock, flags);
- if (!in_interrupt()) // shouldn't be called from interrupt at all...
- spin_lock(&urb->lock);
-
if (urb->status == -EINPROGRESS) {
// move descriptors out the the running chains, dequeue urb
uhci_unlink_urb_async(s, urb, UNLINK_ASYNC_DONT_STORE);
- if (!in_interrupt())
- spin_unlock(&urb->lock);
-
urb_priv = urb->hcpriv;
-
+ urb->status = -ENOENT; // prevent from double deletion after unlock
+ spin_unlock_irqrestore (&s->urb_list_lock, flags);
+
// cleanup the rest
switch (usb_pipetype (urb->pipe)) {
uhci_clean_transfer(s, urb, qh, CLEAN_TRANSFER_DELETION_MARK);
uhci_wait_ms(1);
}
-
- spin_unlock_irqrestore (&s->urb_list_lock, flags);
-
- uhci_urb_dma_unmap(s, urb, urb->hcpriv);
-
urb->status = -ENOENT; // mark urb as killed
+
+ uhci_urb_dma_unmap(s, urb, urb->hcpriv);
#ifdef DEBUG_SLAB
kmem_cache_free (urb_priv_kmem, urb->hcpriv);
}
usb_dec_dev_use (usb_dev);
}
- else {
- if (!in_interrupt())
- spin_unlock(&urb->lock);
+ else
spin_unlock_irqrestore (&s->urb_list_lock, flags);
- }
return 0;
}
if (urb->transfer_flags & USB_ASYNC_UNLINK) {
int ret;
-
spin_lock_irqsave (&s->urb_list_lock, flags);
-
- // The URB needs to be locked if called outside completion context
-
- if (!in_interrupt())
- spin_lock(&urb->lock);
-
+
uhci_release_bandwidth(urb);
ret = uhci_unlink_urb_async(s, urb, UNLINK_ASYNC_STORE_URB);
- if (!in_interrupt())
- spin_unlock(&urb->lock);
-
spin_unlock_irqrestore (&s->urb_list_lock, flags);
-
return ret;
}
else
{
uhci_t *s = (uhci_t*) urb->dev->bus->hcpriv;
urb_priv_t *urb_priv = urb->hcpriv;
- int nint, n, ret;
+ int nint, n;
uhci_desc_t *td;
int status, destination;
int info;
if (next_urb == urb)
is_ring=1;
- }
-
- spin_lock(&urb->lock);
+ }
// Submit idle/non-killed URBs linked with urb->next
// Stop before the current URB
if (is_ring && !was_unlinked && !contains_killed) {
urb->dev=usb_dev;
uhci_submit_urb (urb);
-
}
- spin_unlock(&urb->lock);
spin_lock(&s->urb_list_lock);
}
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/slab.h>
+#define __NO_VERSION__ /* Temporary: usbvideo is not a module yet */
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/vmalloc.h>
+#include <linux/wrapper.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+
+#include "usbvideo.h"
+
+#if defined(MAP_NR)
+#define virt_to_page(v) MAP_NR(v) /* Kernels 2.2.x */
+#endif
+
+static int video_nr = -1;
+MODULE_PARM(video_nr, "i");
+
+/*
+ * Local prototypes.
+ */
+#if USES_PROC_FS
+static void usbvideo_procfs_level1_create(usbvideo_t *ut);
+static void usbvideo_procfs_level1_destroy(usbvideo_t *ut);
+static void usbvideo_procfs_level2_create(uvd_t *uvd);
+static void usbvideo_procfs_level2_destroy(uvd_t *uvd);
+static int usbvideo_default_procfs_read_proc(
+ char *page, char **start, off_t off, int count,
+ int *eof, void *data);
+static int usbvideo_default_procfs_write_proc(
+ struct file *file, const char *buffer,
+ unsigned long count, void *data);
+#endif
+
+/*******************************/
+/* Memory management functions */
+/*******************************/
+
+#define MDEBUG(x) do { } while(0) /* Debug memory management */
+
+/* Given PGD from the address space's page table, return the kernel
+ * virtual mapping of the physical memory mapped at ADR.
+ */
+unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr)
+{
+ unsigned long ret = 0UL;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+
+ if (!pgd_none(*pgd)) {
+ pmd = pmd_offset(pgd, adr);
+ if (!pmd_none(*pmd)) {
+ ptep = pte_offset(pmd, adr);
+ pte = *ptep;
+ if (pte_present(pte)) {
+ ret = (unsigned long) page_address(pte_page(pte));
+ ret |= (adr & (PAGE_SIZE-1));
+ }
+ }
+ }
+ MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+unsigned long usbvideo_uvirt_to_bus(unsigned long adr)
+{
+ unsigned long kva, ret;
+
+ kva = usbvideo_uvirt_to_kva(pgd_offset(current->mm, adr), adr);
+ ret = virt_to_bus((void *)kva);
+ MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+unsigned long usbvideo_kvirt_to_bus(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = usbvideo_uvirt_to_kva(pgd_offset_k(va), va);
+ ret = virt_to_bus((void *)kva);
+ MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+/*
+ * Here we want the physical address of the memory.
+ * This is used when initializing the contents of the
+ * area and marking the pages as reserved.
+ */
+unsigned long usbvideo_kvirt_to_pa(unsigned long adr)
+{
+ unsigned long va, kva, ret;
+
+ va = VMALLOC_VMADDR(adr);
+ kva = usbvideo_uvirt_to_kva(pgd_offset_k(va), va);
+ ret = __pa(kva);
+ MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
+ return ret;
+}
+
+void *usbvideo_rvmalloc(unsigned long size)
+{
+ void *mem;
+ unsigned long adr, page;
+
+ /* Round it off to PAGE_SIZE */
+ size += (PAGE_SIZE - 1);
+ size &= ~(PAGE_SIZE - 1);
+
+ mem = vmalloc_32(size);
+ if (!mem)
+ return NULL;
+
+ memset(mem, 0, size); /* Clear the ram out, no junk to the user */
+ adr = (unsigned long) mem;
+ while (size > 0) {
+ page = usbvideo_kvirt_to_pa(adr);
+ mem_map_reserve(virt_to_page(__va(page)));
+ adr += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+
+ return mem;
+}
+
+void usbvideo_rvfree(void *mem, unsigned long size)
+{
+ unsigned long adr, page;
+
+ if (!mem)
+ return;
+
+ size += (PAGE_SIZE - 1);
+ size &= ~(PAGE_SIZE - 1);
+
+ adr=(unsigned long) mem;
+ while (size > 0) {
+ page = usbvideo_kvirt_to_pa(adr);
+ mem_map_unreserve(virt_to_page(__va(page)));
+ adr += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+ vfree(mem);
+}
+
+void RingQueue_Initialize(RingQueue_t *rq)
+{
+ assert(rq != NULL);
+ init_waitqueue_head(&rq->wqh);
+}
+
+void RingQueue_Allocate(RingQueue_t *rq, int rqLen)
+{
+ assert(rq != NULL);
+ assert(rqLen > 0);
+ rq->length = rqLen;
+ rq->queue = usbvideo_rvmalloc(rq->length);
+ assert(rq->queue != NULL);
+}
+
+int RingQueue_IsAllocated(const RingQueue_t *rq)
+{
+ if (rq == NULL)
+ return 0;
+ return (rq->queue != NULL) && (rq->length > 0);
+}
+
+void RingQueue_Free(RingQueue_t *rq)
+{
+ assert(rq != NULL);
+ if (RingQueue_IsAllocated(rq)) {
+ usbvideo_rvfree(rq->queue, rq->length);
+ rq->queue = NULL;
+ rq->length = 0;
+ }
+}
+
+int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len)
+{
+ int i;
+ assert(rq != NULL);
+ assert(dst != NULL);
+ for (i=0; i < len; i++) {
+ dst[i] = rq->queue[rq->ri];
+ RING_QUEUE_DEQUEUE_BYTES(rq,1);
+ }
+ return len;
+}
+
+int RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n)
+{
+ int enqueued = 0;
+
+ assert(rq != NULL);
+ assert(cdata != NULL);
+ assert(rq->length > 0);
+ while (n > 0) {
+ int m, q_avail;
+
+ /* Calculate the largest chunk that fits the tail of the ring */
+ q_avail = rq->length - rq->wi;
+ if (q_avail <= 0) {
+ rq->wi = 0;
+ q_avail = rq->length;
+ }
+ m = n;
+ assert(q_avail > 0);
+ if (m > q_avail)
+ m = q_avail;
+
+ memmove(rq->queue + rq->wi, cdata, m);
+ RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
+ cdata += m;
+ enqueued += m;
+ n -= m;
+ }
+ return enqueued;
+}
+
+int RingQueue_GetLength(const RingQueue_t *rq)
+{
+ int ri, wi;
+
+ assert(rq != NULL);
+
+ ri = rq->ri;
+ wi = rq->wi;
+ if (ri == wi)
+ return 0;
+ else if (ri < wi)
+ return wi - ri;
+ else
+ return wi + (rq->length - ri);
+}
+
+void RingQueue_InterruptibleSleepOn(RingQueue_t *rq)
+{
+ assert(rq != NULL);
+ interruptible_sleep_on(&rq->wqh);
+}
+
+void RingQueue_WakeUpInterruptible(RingQueue_t *rq)
+{
+ assert(rq != NULL);
+ if (waitqueue_active(&rq->wqh))
+ wake_up_interruptible(&rq->wqh);
+}
+
+/*
+ * usbvideo_VideosizeToString()
+ *
+ * This procedure converts given videosize value to readable string.
+ *
+ * History:
+ * 07-Aug-2000 Created.
+ * 19-Oct-2000 Reworked for usbvideo module.
+ */
+void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
+{
+ char tmp[40];
+ int n;
+
+ n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs));
+ assert(n < sizeof(tmp));
+ if ((buf == NULL) || (bufLen < n))
+ err("usbvideo_VideosizeToString: buffer is too small.");
+ else
+ memmove(buf, tmp, n);
+}
+
+/*
+ * usbvideo_OverlayChar()
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_OverlayChar(uvd_t *uvd, usbvideo_frame_t *frame,
+ int x, int y, int ch)
+{
+ static const unsigned short digits[16] = {
+ 0xF6DE, /* 0 */
+ 0x2492, /* 1 */
+ 0xE7CE, /* 2 */
+ 0xE79E, /* 3 */
+ 0xB792, /* 4 */
+ 0xF39E, /* 5 */
+ 0xF3DE, /* 6 */
+ 0xF492, /* 7 */
+ 0xF7DE, /* 8 */
+ 0xF79E, /* 9 */
+ 0x77DA, /* a */
+ 0xD75C, /* b */
+ 0xF24E, /* c */
+ 0xD6DC, /* d */
+ 0xF34E, /* e */
+ 0xF348 /* f */
+ };
+ unsigned short digit;
+ int ix, iy;
+
+ if ((uvd == NULL) || (frame == NULL))
+ return;
+
+ if (ch >= '0' && ch <= '9')
+ ch -= '0';
+ else if (ch >= 'A' && ch <= 'F')
+ ch = 10 + (ch - 'A');
+ else if (ch >= 'a' && ch <= 'f')
+ ch = 10 + (ch - 'a');
+ else
+ return;
+ digit = digits[ch];
+
+ for (iy=0; iy < 5; iy++) {
+ for (ix=0; ix < 3; ix++) {
+ if (digit & 0x8000) {
+ if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24)) {
+/* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
+ }
+ }
+ digit = digit << 1;
+ }
+ }
+}
+
+/*
+ * usbvideo_OverlayString()
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_OverlayString(uvd_t *uvd, usbvideo_frame_t *frame,
+ int x, int y, const char *str)
+{
+ while (*str) {
+ usbvideo_OverlayChar(uvd, frame, x, y, *str);
+ str++;
+ x += 4; /* 3 pixels character + 1 space */
+ }
+}
+
+/*
+ * usbvideo_OverlayStats()
+ *
+ * Overlays important debugging information.
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_OverlayStats(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+ const int y_diff = 8;
+ char tmp[16];
+ int x = 10, y=10;
+ long i, j, barLength;
+ const int qi_x1 = 60, qi_y1 = 10;
+ const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10;
+
+ /* Call the user callback, see if we may proceed after that */
+ if (VALID_CALLBACK(uvd, overlayHook)) {
+ if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0)
+ return;
+ }
+
+ /*
+ * We draw a (mostly) hollow rectangle with qi_xxx coordinates.
+ * Left edge symbolizes the queue index 0; right edge symbolizes
+ * the full capacity of the queue.
+ */
+ barLength = qi_x2 - qi_x1 - 2;
+ if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) {
+/* TODO */ long u_lo, u_hi, q_used;
+ long m_ri, m_wi, m_lo, m_hi;
+
+ /*
+ * Determine fill zones (used areas of the queue):
+ * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length
+ *
+ * if u_lo < 0 then there is no first filler.
+ */
+
+ q_used = RingQueue_GetLength(&uvd->dp);
+ if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
+ u_hi = uvd->dp.length;
+ u_lo = (q_used + uvd->dp.ri) % uvd->dp.length;
+ } else {
+ u_hi = (q_used + uvd->dp.ri);
+ u_lo = -1;
+ }
+
+ /* Convert byte indices into screen units */
+ m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length);
+ m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length);
+ m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1;
+ m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length);
+
+ for (j=qi_y1; j < (qi_y1 + qi_h); j++) {
+ for (i=qi_x1; i < qi_x2; i++) {
+ /* Draw border lines */
+ if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) ||
+ (i == qi_x1) || (i == (qi_x2 - 1))) {
+ RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF);
+ continue;
+ }
+ /* For all other points the Y coordinate does not matter */
+ if ((i >= m_ri) && (i <= (m_ri + 3))) {
+ RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00);
+ } else if ((i >= m_wi) && (i <= (m_wi + 3))) {
+ RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00);
+ } else if ((i < m_lo) || ((i > m_ri) && (i < m_hi)))
+ RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF);
+ }
+ }
+ }
+
+ sprintf(tmp, "%8lx", uvd->stats.frame_num);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", uvd->stats.urb_count);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", uvd->stats.urb_length);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", uvd->stats.data_count);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", uvd->stats.header_count);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", uvd->stats.iso_skip_count);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8lx", uvd->stats.iso_err_count);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", uvd->vpic.colour);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", uvd->vpic.hue);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", uvd->vpic.brightness >> 8);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8x", uvd->vpic.contrast >> 12);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+
+ sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8);
+ usbvideo_OverlayString(uvd, frame, x, y, tmp);
+ y += y_diff;
+}
+
+/*
+ * usbvideo_ReportStatistics()
+ *
+ * This procedure prints packet and transfer statistics.
+ *
+ * History:
+ * 14-Jan-2000 Corrected default multiplier.
+ */
+void usbvideo_ReportStatistics(const uvd_t *uvd)
+{
+ if ((uvd != NULL) && (uvd->stats.urb_count > 0)) {
+ unsigned long allPackets, badPackets, goodPackets, percent;
+ allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES;
+ badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count;
+ goodPackets = allPackets - badPackets;
+ /* Calculate percentage wisely, remember integer limits */
+ assert(allPackets != 0);
+ if (goodPackets < (((unsigned long)-1)/100))
+ percent = (100 * goodPackets) / allPackets;
+ else
+ percent = goodPackets / (allPackets / 100);
+ info("Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%",
+ allPackets, badPackets, percent);
+ if (uvd->iso_packet_len > 0) {
+ unsigned long allBytes, xferBytes;
+ char multiplier = ' ';
+ allBytes = allPackets * uvd->iso_packet_len;
+ xferBytes = uvd->stats.data_count;
+ assert(allBytes != 0);
+ if (xferBytes < (((unsigned long)-1)/100))
+ percent = (100 * xferBytes) / allBytes;
+ else
+ percent = xferBytes / (allBytes / 100);
+ /* Scale xferBytes for easy reading */
+ if (xferBytes > 10*1024) {
+ xferBytes /= 1024;
+ multiplier = 'K';
+ if (xferBytes > 10*1024) {
+ xferBytes /= 1024;
+ multiplier = 'M';
+ if (xferBytes > 10*1024) {
+ xferBytes /= 1024;
+ multiplier = 'G';
+ if (xferBytes > 10*1024) {
+ xferBytes /= 1024;
+ multiplier = 'T';
+ }
+ }
+ }
+ }
+ info("Transfer Statistics: Transferred=%lu%cB Usage=%lu%%",
+ xferBytes, multiplier, percent);
+ }
+ }
+}
+
+/*
+ * usbvideo_DrawLine()
+ *
+ * A standard implementation of Bresenham's line drawing algorithm.
+ * This procedure is provided primarily for debugging or demo
+ * purposes.
+ */
+void usbvideo_DrawLine(
+ usbvideo_frame_t *frame,
+ int x1, int y1,
+ int x2, int y2,
+ unsigned char cr, unsigned char cg, unsigned char cb)
+{
+ int i, dx, dy, np, d;
+ int dinc1, dinc2, x, xinc1, xinc2, y, yinc1, yinc2;
+
+ if ((dx = x2 - x1) < 0)
+ dx = -dx;
+ if ((dy = y2 - y1) < 0)
+ dy = -dy;
+ if (dx >= dy) {
+ np = dx + 1;
+ d = (2 * dy) - dx;
+ dinc1 = dy << 1;
+ dinc2 = (dy - dx) << 1;
+ xinc1 = 1;
+ xinc2 = 1;
+ yinc1 = 0;
+ yinc2 = 1;
+ } else {
+ np = dy + 1;
+ d = (2 * dx) - dy;
+ dinc1 = dx << 1;
+ dinc2 = (dx - dy) << 1;
+ xinc1 = 0;
+ xinc2 = 1;
+ yinc1 = 1;
+ yinc2 = 1;
+ }
+ /* Make sure x and y move in the right directions */
+ if (x1 > x2) {
+ xinc1 = -xinc1;
+ xinc2 = -xinc2;
+ }
+ if (y1 > y2) {
+ yinc1 = -yinc1;
+ yinc2 = -yinc2;
+ }
+ for (i=0, x=x1, y=y1; i < np; i++) {
+ if (frame->palette == VIDEO_PALETTE_RGB24) {
+/* TODO */ RGB24_PUTPIXEL(frame, x, y, cr, cg, cb);
+ }
+ if (d < 0) {
+ d += dinc1;
+ x += xinc1;
+ y += yinc1;
+ } else {
+ d += dinc2;
+ x += xinc2;
+ y += yinc2;
+ }
+ }
+}
+
+/*
+ * usbvideo_TestPattern()
+ *
+ * Procedure forms a test pattern (yellow grid on blue background).
+ *
+ * Parameters:
+ * fullframe: if TRUE then entire frame is filled, otherwise the procedure
+ * continues from the current scanline.
+ * pmode 0: fill the frame with solid blue color (like on VCR or TV)
+ * 1: Draw a colored grid
+ *
+ * History:
+ * 01-Feb-2000 Created.
+ */
+void usbvideo_TestPattern(uvd_t *uvd, int fullframe, int pmode)
+{
+ static const char proc[] = "usbvideo_TestPattern";
+ usbvideo_frame_t *frame;
+ int num_cell = 0;
+ int scan_length = 0;
+ static int num_pass = 0;
+
+ if (uvd == NULL) {
+ err("%s: uvd == NULL", proc);
+ return;
+ }
+ if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
+ err("%s: uvd->curframe=%d.", proc, uvd->curframe);
+ return;
+ }
+
+ /* Grab the current frame */
+ frame = &uvd->frame[uvd->curframe];
+
+ /* Optionally start at the beginning */
+ if (fullframe) {
+ frame->curline = 0;
+ frame->seqRead_Length = 0;
+ }
+#if 0
+ { /* For debugging purposes only */
+ char tmp[20];
+ usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request);
+ info("testpattern: frame=%s", tmp);
+ }
+#endif
+ /* Form every scan line */
+ for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) {
+ int i;
+ unsigned char *f = frame->data +
+ (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline);
+ for (i=0; i < VIDEOSIZE_X(frame->request); i++) {
+ unsigned char cb=0x80;
+ unsigned char cg = 0;
+ unsigned char cr = 0;
+
+ if (pmode == 1) {
+ if (frame->curline % 32 == 0)
+ cb = 0, cg = cr = 0xFF;
+ else if (i % 32 == 0) {
+ if (frame->curline % 32 == 1)
+ num_cell++;
+ cb = 0, cg = cr = 0xFF;
+ } else {
+ cb = ((num_cell*7) + num_pass) & 0xFF;
+ cg = ((num_cell*5) + num_pass*2) & 0xFF;
+ cr = ((num_cell*3) + num_pass*3) & 0xFF;
+ }
+ } else {
+ /* Just the blue screen */
+ }
+
+ *f++ = cb;
+ *f++ = cg;
+ *f++ = cr;
+ scan_length += 3;
+ }
+ }
+
+ frame->frameState = FrameState_Done;
+ frame->seqRead_Length += scan_length;
+ ++num_pass;
+
+ /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
+ usbvideo_OverlayStats(uvd, frame);
+}
+
+/*
+ * usbvideo_HexDump()
+ *
+ * A debugging tool. Prints hex dumps.
+ *
+ * History:
+ * 29-Jul-2000 Added printing of offsets.
+ */
+void usbvideo_HexDump(const unsigned char *data, int len)
+{
+ const int bytes_per_line = 32;
+ char tmp[128]; /* 32*3 + 5 */
+ int i, k;
+
+ for (i=k=0; len > 0; i++, len--) {
+ if (i > 0 && ((i % bytes_per_line) == 0)) {
+ printk("%s\n", tmp);
+ k=0;
+ }
+ if ((i % bytes_per_line) == 0)
+ k += sprintf(&tmp[k], "%04x: ", i);
+ k += sprintf(&tmp[k], "%02x ", data[i]);
+ }
+ if (k > 0)
+ printk("%s\n", tmp);
+}
+
+/* Debugging aid */
+void usbvideo_SayAndWait(const char *what)
+{
+ wait_queue_head_t wq;
+ init_waitqueue_head(&wq);
+ info("Say: %s", what);
+ interruptible_sleep_on_timeout (&wq, HZ*3); /* Timeout */
+}
+
+/* ******************************************************************** */
+
+static void usbvideo_ClientIncModCount(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_ClientIncModCount";
+ if (uvd == NULL) {
+ err("%s: uvd == NULL", proc);
+ return;
+ }
+ if (uvd->handle == NULL) {
+ err("%s: uvd->handle == NULL", proc);
+ return;
+ }
+ if (uvd->handle->md_module == NULL) {
+ err("%s: uvd->handle->md_module == NULL", proc);
+ return;
+ }
+ __MOD_INC_USE_COUNT(uvd->handle->md_module);
+}
+
+static void usbvideo_ClientDecModCount(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_ClientDecModCount";
+ if (uvd == NULL) {
+ err("%s: uvd == NULL", proc);
+ return;
+ }
+ if (uvd->handle == NULL) {
+ err("%s: uvd->handle == NULL", proc);
+ return;
+ }
+ if (uvd->handle->md_module == NULL) {
+ err("%s: uvd->handle->md_module == NULL", proc);
+ return;
+ }
+ __MOD_DEC_USE_COUNT(uvd->handle->md_module);
+}
+
+int usbvideo_register(
+ usbvideo_t **pCams,
+ const int num_cams,
+ const int num_extra,
+ const char *driverName,
+ const usbvideo_cb_t *cbTbl,
+ struct module *md )
+{
+ static const char proc[] = "usbvideo_register";
+ usbvideo_t *cams;
+ int i, base_size;
+
+ /* Check parameters for sanity */
+ if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
+ err("%s: Illegal call", proc);
+ return -EINVAL;
+ }
+
+ /* Check registration callback - must be set! */
+ if (cbTbl->probe == NULL) {
+ err("%s: probe() is required!", proc);
+ return -EINVAL;
+ }
+
+ base_size = num_cams * sizeof(uvd_t) + sizeof(usbvideo_t);
+ cams = (usbvideo_t *) kmalloc(base_size, GFP_KERNEL);
+ if (cams == NULL) {
+ err("Failed to allocate %d. bytes for usbvideo_t", base_size);
+ return -ENOMEM;
+ }
+ dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
+ proc, cams, base_size, num_cams);
+ memset(cams, 0, base_size);
+
+ /* Copy callbacks, apply defaults for those that are not set */
+ memmove(&cams->cb, cbTbl, sizeof(cams->cb));
+ if (cams->cb.getFrame == NULL)
+ cams->cb.getFrame = usbvideo_GetFrame;
+ if (cams->cb.disconnect == NULL)
+ cams->cb.disconnect = usbvideo_Disconnect;
+#if USES_PROC_FS
+ /*
+ * If both /proc fs callbacks are NULL then we assume that the driver
+ * does not need procfs services at all. Leave them NULL.
+ */
+ cams->uses_procfs = (cams->cb.procfs_read != NULL) || (cams->cb.procfs_write == NULL);
+ if (cams->uses_procfs) {
+ if (cams->cb.procfs_read == NULL)
+ cams->cb.procfs_read = usbvideo_default_procfs_read_proc;
+ if (cams->cb.procfs_write == NULL)
+ cams->cb.procfs_write = usbvideo_default_procfs_write_proc;
+ }
+#else /* !USES_PROC_FS */
+ /* Report a warning so that user knows why there is no /proc entries */
+ if ((cams->cb.procfs_read != NULL) || (cams->cb.procfs_write == NULL)) {
+ dbg("%s: /proc fs support requested but not configured!", proc);
+ }
+#endif
+ cams->num_cameras = num_cams;
+ cams->cam = (uvd_t *) &cams[1];
+ cams->md_module = md;
+ if (cams->md_module == NULL)
+ warn("%s: module == NULL!", proc);
+ init_MUTEX(&cams->lock); /* to 1 == available */
+
+ for (i = 0; i < num_cams; i++) {
+ uvd_t *up = &cams->cam[i];
+
+ up->handle = cams;
+
+ /* Allocate user_data separately because of kmalloc's limits */
+ if (num_extra > 0) {
+ up->user_size = num_cams * num_extra;
+ up->user_data = (char *) kmalloc(up->user_size, GFP_KERNEL);
+ if (up->user_data == NULL) {
+ up->user_size = 0;
+ err("%s: Failed to allocate user_data (%d. bytes)",
+ proc, up->user_size);
+ return -ENOMEM;
+ }
+ dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
+ proc, i, up->user_data, up->user_size);
+ }
+ }
+
+ /*
+ * Register ourselves with USB stack.
+ */
+ strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown");
+ cams->usbdrv.name = cams->drvName;
+ cams->usbdrv.probe = cams->cb.probe;
+ cams->usbdrv.disconnect = cams->cb.disconnect;
+
+#if USES_PROC_FS
+ if (cams->uses_procfs) {
+ dbg("%s: Creating /proc filesystem entries.", proc);
+ usbvideo_procfs_level1_create(cams);
+ }
+#endif
+
+ /*
+ * Update global handle to usbvideo. This is very important
+ * because probe() can be called before usb_register() returns.
+ * If the handle is not yet updated then the probe() will fail.
+ */
+ *pCams = cams;
+ usb_register(&cams->usbdrv);
+
+ return 0;
+}
+
+/*
+ * usbvideo_Deregister()
+ *
+ * Procedure frees all usbvideo and user data structures. Be warned that
+ * if you had some dynamically allocated components in ->user field then
+ * you should free them before calling here.
+ */
+void usbvideo_Deregister(usbvideo_t **pCams)
+{
+ static const char proc[] = "usbvideo_deregister";
+ usbvideo_t *cams;
+ int i;
+
+ if (pCams == NULL) {
+ err("%s: pCams == NULL", proc);
+ return;
+ }
+ cams = *pCams;
+ if (cams == NULL) {
+ err("%s: cams == NULL", proc);
+ return;
+ }
+
+#if USES_PROC_FS
+ if (cams->uses_procfs) {
+ dbg("%s: Deregistering filesystem entries.", proc);
+ usbvideo_procfs_level1_destroy(cams);
+ }
+#endif
+
+ dbg("%s: Deregistering %s driver.", proc, cams->drvName);
+ usb_deregister(&cams->usbdrv);
+
+ dbg("%s: Deallocating cams=$%p (%d. cameras)", proc, cams, cams->num_cameras);
+ for (i=0; i < cams->num_cameras; i++) {
+ uvd_t *up = &cams->cam[i];
+ int warning = 0;
+
+ if (up->user_data != NULL) {
+ if (up->user_size <= 0)
+ ++warning;
+ } else {
+ if (up->user_size > 0)
+ ++warning;
+ }
+ if (warning) {
+ err("%s: Warning: user_data=$%p user_size=%d.",
+ proc, up->user_data, up->user_size);
+ } else {
+ dbg("%s: Freeing %d. $%p->user_data=$%p",
+ proc, i, up, up->user_data);
+ kfree(up->user_data);
+ }
+ }
+ /* Whole array was allocated in one chunk */
+ dbg("%s: Freed %d uvd_t structures",
+ proc, cams->num_cameras);
+ kfree(cams);
+ *pCams = NULL;
+}
+
+/*
+ * usbvideo_Disconnect()
+ *
+ * This procedure stops all driver activity. Deallocation of
+ * the interface-private structure (pointed by 'ptr') is done now
+ * (if we don't have any open files) or later, when those files
+ * are closed. After that driver should be removable.
+ *
+ * This code handles surprise removal. The uvd->user is a counter which
+ * increments on open() and decrements on close(). If we see here that
+ * this counter is not 0 then we have a client who still has us opened.
+ * We set uvd->remove_pending flag as early as possible, and after that
+ * all access to the camera will gracefully fail. These failures should
+ * prompt client to (eventually) close the video device, and then - in
+ * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter.
+ *
+ * History:
+ * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone.
+ * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close()
+ * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
+ * 19-Oct-2000 Moved to usbvideo module.
+ */
+void usbvideo_Disconnect(struct usb_device *dev, void *ptr)
+{
+ static const char proc[] = "usbvideo_Disconnect";
+ uvd_t *uvd = (uvd_t *) ptr;
+ int i;
+
+ if ((dev == NULL) || (uvd == NULL)) {
+ err("%s($%p,$%p): Illegal call.", proc, dev, ptr);
+ return;
+ }
+ usbvideo_ClientIncModCount(uvd);
+ if (uvd->debug > 0)
+ info("%s(%p,%p.)", proc, dev, ptr);
+
+ down(&uvd->lock);
+ uvd->remove_pending = 1; /* Now all ISO data will be ignored */
+
+ /* At this time we ask to cancel outstanding URBs */
+ usbvideo_StopDataPump(uvd);
+
+ for (i=0; i < USBVIDEO_NUMSBUF; i++)
+ usb_free_urb(uvd->sbuf[i].urb);
+
+ usb_dec_dev_use(uvd->dev);
+ uvd->dev = NULL; /* USB device is no more */
+
+ if (uvd->user)
+ info("%s: In use, disconnect pending.", proc);
+ else
+ usbvideo_CameraRelease(uvd);
+ up(&uvd->lock);
+ info("USB camera disconnected.");
+
+ usbvideo_ClientDecModCount(uvd);
+}
+
+/*
+ * usbvideo_CameraRelease()
+ *
+ * This code does final release of uvd_t. This happens
+ * after the device is disconnected -and- all clients
+ * closed their files.
+ *
+ * History:
+ * 27-Jan-2000 Created.
+ */
+void usbvideo_CameraRelease(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_CameraRelease";
+ if (uvd == NULL) {
+ err("%s: Illegal call", proc);
+ return;
+ }
+ video_unregister_device(&uvd->vdev);
+ if (uvd->debug > 0)
+ info("%s: Video unregistered.", proc);
+
+#if USES_PROC_FS
+ assert(uvd->handle != NULL);
+ if (uvd->handle->uses_procfs) {
+ dbg("%s: Removing /proc/%s/ filesystem entries.", proc, uvd->handle->drvName);
+ usbvideo_procfs_level2_destroy(uvd);
+ }
+#endif
+
+ RingQueue_Free(&uvd->dp);
+ if (VALID_CALLBACK(uvd, userFree))
+ GET_CALLBACK(uvd, userFree)(uvd);
+ uvd->uvd_used = 0; /* This is atomic, no need to take mutex */
+}
+
+/*
+ * usbvideo_find_struct()
+ *
+ * This code searches the array of preallocated (static) structures
+ * and returns index of the first one that isn't in use. Returns -1
+ * if there are no free structures.
+ *
+ * History:
+ * 27-Jan-2000 Created.
+ */
+static int usbvideo_find_struct(usbvideo_t *cams)
+{
+ int u, rv = -1;
+
+ if (cams == NULL) {
+ err("No usbvideo_t handle?");
+ return -1;
+ }
+ down(&cams->lock);
+ for (u = 0; u < cams->num_cameras; u++) {
+ uvd_t *uvd = &cams->cam[u];
+ if (!uvd->uvd_used) /* This one is free */
+ {
+ uvd->uvd_used = 1; /* In use now */
+ init_MUTEX(&uvd->lock); /* to 1 == available */
+ uvd->dev = NULL;
+ rv = u;
+ break;
+ }
+ }
+ up(&cams->lock);
+ return rv;
+}
+
+uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams)
+{
+ int i, devnum;
+ uvd_t *uvd = NULL;
+
+ if (cams == NULL) {
+ err("No usbvideo_t handle?");
+ return NULL;
+ }
+
+ devnum = usbvideo_find_struct(cams);
+ if (devnum == -1) {
+ err("IBM USB camera driver: Too many devices!");
+ return NULL;
+ }
+ uvd = &cams->cam[devnum];
+ dbg("Device entry #%d. at $%p", devnum, uvd);
+
+ /* Not relying upon caller we increase module counter ourselves */
+ usbvideo_ClientIncModCount(uvd);
+
+ down(&uvd->lock);
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC);
+ if (uvd->sbuf[i].urb == NULL) {
+ err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC);
+ uvd->uvd_used = 0;
+ uvd = NULL;
+ goto allocate_done;
+ }
+ }
+ uvd->user=0;
+ uvd->remove_pending = 0;
+ uvd->last_error = 0;
+ RingQueue_Initialize(&uvd->dp);
+
+ /* Initialize video device structure */
+ memset(&uvd->vdev, 0, sizeof(uvd->vdev));
+ i = sprintf(uvd->vdev.name, "%s USB Camera", cams->drvName);
+ if (i >= sizeof(uvd->vdev.name)) {
+ err("Wrote too much into uvd->vdev.name, expect trouble!");
+ }
+ uvd->vdev.type = VID_TYPE_CAPTURE;
+ uvd->vdev.hardware = VID_HARDWARE_CPIA;
+ uvd->vdev.open = usbvideo_v4l_open;
+ uvd->vdev.close = usbvideo_v4l_close;
+ uvd->vdev.read = usbvideo_v4l_read;
+ uvd->vdev.write = usbvideo_v4l_write;
+ uvd->vdev.ioctl = usbvideo_v4l_ioctl;
+ uvd->vdev.mmap = usbvideo_v4l_mmap;
+ uvd->vdev.initialize = usbvideo_v4l_initialize;
+ /*
+ * The client is free to overwrite those because we
+ * return control to the client's probe function right now.
+ */
+allocate_done:
+ up (&uvd->lock);
+ usbvideo_ClientDecModCount(uvd);
+ return uvd;
+}
+
+int usbvideo_RegisterVideoDevice(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_RegisterVideoDevice";
+ char tmp1[20], tmp2[20]; /* Buffers for printing */
+
+ if (uvd == NULL) {
+ err("%s: Illegal call.", proc);
+ return -EINVAL;
+ }
+ if (uvd->video_endp == 0) {
+ info("%s: No video endpoint specified; data pump disabled.", proc);
+ }
+ if (uvd->paletteBits == 0) {
+ err("%s: No palettes specified!", proc);
+ return -EINVAL;
+ }
+ if (uvd->defaultPalette == 0) {
+ info("%s: No default palette!", proc);
+ }
+
+ uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) *
+ VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL;
+ usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize);
+ usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas);
+
+ if (uvd->debug > 0) {
+ info("%s: iface=%d. endpoint=$%02x paletteBits=$%08lx",
+ proc, uvd->iface, uvd->video_endp, uvd->paletteBits);
+ }
+ if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
+ err("%s: video_register_device failed", proc);
+ return -EPIPE;
+ }
+ if (uvd->debug > 1) {
+ info("%s: video_register_device() successful", proc);
+ }
+ if (uvd->dev == NULL) {
+ err("%s: uvd->dev == NULL", proc);
+ return -EINVAL;
+ }
+
+ info("%s on /dev/video%d: canvas=%s videosize=%s",
+ (uvd->handle != NULL) ? uvd->handle->drvName : "???",
+ uvd->vdev.minor, tmp2, tmp1);
+
+#if USES_PROC_FS
+ assert(uvd->handle != NULL);
+ if (uvd->handle->uses_procfs) {
+ if (uvd->debug > 0) {
+ info("%s: Creating /proc/%s/ filesystem entries.",
+ proc, uvd->handle->drvName);
+ }
+ usbvideo_procfs_level2_create(uvd);
+ }
+#endif
+
+ usb_inc_dev_use(uvd->dev);
+ return 0;
+}
+
+/* ******************************************************************** */
+
+int usbvideo_v4l_initialize(struct video_device *dev)
+{
+ return 0;
+}
+
+long usbvideo_v4l_write(struct video_device *dev, const char *buf,
+ unsigned long count, int noblock)
+{
+ return -EINVAL;
+}
+
+int usbvideo_v4l_mmap(struct video_device *dev, const char *adr, unsigned long size)
+{
+ uvd_t *uvd = (uvd_t *) dev;
+ unsigned long start = (unsigned long) adr;
+ unsigned long page, pos;
+
+ if (!CAMERA_IS_OPERATIONAL(uvd))
+ return -EFAULT;
+
+ if (size > (((2 * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
+ return -EINVAL;
+
+ pos = (unsigned long) uvd->fbuf;
+ while (size > 0) {
+ page = usbvideo_kvirt_to_pa(pos);
+ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
+ return -EAGAIN;
+
+ start += PAGE_SIZE;
+ pos += PAGE_SIZE;
+ if (size > PAGE_SIZE)
+ size -= PAGE_SIZE;
+ else
+ size = 0;
+ }
+
+ return 0;
+}
+
+/*
+ * usbvideo_v4l_open()
+ *
+ * This is part of Video 4 Linux API. The driver can be opened by one
+ * client only (checks internal counter 'uvdser'). The procedure
+ * then allocates buffers needed for video processing.
+ *
+ * History:
+ * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the
+ * camera is also initialized here (once per connect), at
+ * expense of V4L client (it waits on open() call).
+ * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
+ * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
+ */
+int usbvideo_v4l_open(struct video_device *dev, int flags)
+{
+ static const char proc[] = "usbvideo_v4l_open";
+ uvd_t *uvd = (uvd_t *) dev;
+ const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len;
+ int i, errCode = 0;
+
+ if (uvd->debug > 1)
+ info("%s($%p,$%08x", proc, dev, flags);
+
+ usbvideo_ClientIncModCount(uvd);
+ down(&uvd->lock);
+
+ if (uvd->user) {
+ err("%s: Someone tried to open an already opened device!", proc);
+ errCode = -EBUSY;
+ } else {
+ /* Clear statistics */
+ memset(&uvd->stats, 0, sizeof(uvd->stats));
+
+ /* Clean pointers so we know if we allocated something */
+ for (i=0; i < USBVIDEO_NUMSBUF; i++)
+ uvd->sbuf[i].data = NULL;
+
+ /* Allocate memory for the frame buffers */
+ uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
+ uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
+ RingQueue_Allocate(&uvd->dp, 128*1024); /* FIXME #define */
+ if ((uvd->fbuf == NULL) ||
+ (!RingQueue_IsAllocated(&uvd->dp))) {
+ err("%s: Failed to allocate fbuf or dp", proc);
+ errCode = -ENOMEM;
+ } else {
+ /* Allocate all buffers */
+ for (i=0; i < USBVIDEO_NUMFRAMES; i++) {
+ uvd->frame[i].frameState = FrameState_Unused;
+ uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size);
+ /*
+ * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
+ * is not used (using read() instead).
+ */
+ uvd->frame[i].canvas = uvd->canvas;
+ uvd->frame[i].seqRead_Index = 0;
+ }
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
+ if (uvd->sbuf[i].data == NULL) {
+ errCode = -ENOMEM;
+ break;
+ }
+ }
+ }
+ if (errCode != 0) {
+ /* Have to free all that memory */
+ if (uvd->fbuf != NULL) {
+ usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
+ uvd->fbuf = NULL;
+ }
+ RingQueue_Free(&uvd->dp);
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ if (uvd->sbuf[i].data != NULL) {
+ kfree (uvd->sbuf[i].data);
+ uvd->sbuf[i].data = NULL;
+ }
+ }
+ }
+ }
+
+ /* If so far no errors then we shall start the camera */
+ if (errCode == 0) {
+ /* Start data pump if we have valid endpoint */
+ if (uvd->video_endp != 0)
+ errCode = usbvideo_StartDataPump(uvd);
+ if (errCode == 0) {
+ if (VALID_CALLBACK(uvd, setupOnOpen)) {
+ if (uvd->debug > 1)
+ info("%s: setupOnOpen callback", proc);
+ errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd);
+ if (errCode < 0) {
+ err("%s: setupOnOpen callback failed (%d.).",
+ proc, errCode);
+ } else if (uvd->debug > 1) {
+ info("%s: setupOnOpen callback successful", proc);
+ }
+ }
+ if (errCode == 0) {
+ uvd->settingsAdjusted = 0;
+ if (uvd->debug > 1)
+ info("%s: Open succeeded.", proc);
+ uvd->user++;
+ }
+ }
+ }
+ up(&uvd->lock);
+ if (errCode != 0)
+ usbvideo_ClientDecModCount(uvd);
+ if (uvd->debug > 0)
+ info("%s: Returning %d.", proc, errCode);
+ return errCode;
+}
+
+/*
+ * usbvideo_v4l_close()
+ *
+ * This is part of Video 4 Linux API. The procedure
+ * stops streaming and deallocates all buffers that were earlier
+ * allocated in usbvideo_v4l_open().
+ *
+ * History:
+ * 22-Jan-2000 Moved scratch buffer deallocation here.
+ * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
+ * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
+ */
+void usbvideo_v4l_close(struct video_device *dev)
+{
+ static const char proc[] = "usbvideo_v4l_close";
+ uvd_t *uvd = (uvd_t *)dev;
+ int i;
+
+ if (uvd->debug > 1)
+ info("%s($%p)", proc, dev);
+
+ down(&uvd->lock);
+ usbvideo_StopDataPump(uvd);
+ usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
+ uvd->fbuf = NULL;
+ RingQueue_Free(&uvd->dp);
+
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ kfree(uvd->sbuf[i].data);
+ uvd->sbuf[i].data = NULL;
+ }
+
+#if USBVIDEO_REPORT_STATS
+ usbvideo_ReportStatistics(uvd);
+#endif
+
+ uvd->user--;
+ if (uvd->remove_pending) {
+ if (uvd->debug > 0)
+ info("usbvideo_v4l_close: Final disconnect.");
+ usbvideo_CameraRelease(uvd);
+ }
+ up(&uvd->lock);
+ usbvideo_ClientDecModCount(uvd);
+
+ if (uvd->debug > 1)
+ info("%s: Completed.", proc);
+}
+
+/*
+ * usbvideo_v4l_ioctl()
+ *
+ * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
+ *
+ * History:
+ * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
+ */
+int usbvideo_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+ uvd_t *uvd = (uvd_t *)dev;
+
+ if (!CAMERA_IS_OPERATIONAL(uvd))
+ return -EFAULT;
+
+ switch (cmd) {
+ case VIDIOCGCAP:
+ {
+ if (copy_to_user(arg, &uvd->vcap, sizeof(uvd->vcap)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGCHAN:
+ {
+ if (copy_to_user(arg, &uvd->vchan, sizeof(uvd->vchan)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSCHAN:
+ { /* Not used but we return success */
+ int v;
+ if (copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGPICT:
+ {
+ if (copy_to_user(arg, &uvd->vpic, sizeof(uvd->vpic)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSPICT:
+ {
+ struct video_picture tmp;
+ /*
+ * Use temporary 'video_picture' structure to preserve our
+ * own settings (such as color depth, palette) that we
+ * aren't allowing everyone (V4L client) to change.
+ */
+ if (copy_from_user(&tmp, arg, sizeof(tmp)))
+ return -EFAULT;
+ uvd->vpic.brightness = tmp.brightness;
+ uvd->vpic.hue = tmp.hue;
+ uvd->vpic.colour = tmp.colour;
+ uvd->vpic.contrast = tmp.contrast;
+ uvd->settingsAdjusted = 0; /* Will force new settings */
+ return 0;
+ }
+ case VIDIOCSWIN:
+ {
+ struct video_window vw;
+
+ if (copy_from_user(&vw, arg, sizeof(vw)))
+ return -EFAULT;
+ if (vw.flags)
+ return -EINVAL;
+ if (vw.clipcount)
+ return -EINVAL;
+ if (vw.width != VIDEOSIZE_X(uvd->canvas))
+ return -EINVAL;
+ if (vw.height != VIDEOSIZE_Y(uvd->canvas))
+ return -EINVAL;
+
+ return 0;
+ }
+ case VIDIOCGWIN:
+ {
+ struct video_window vw;
+
+ vw.x = 0;
+ vw.y = 0;
+ vw.width = VIDEOSIZE_X(uvd->canvas);
+ vw.height = VIDEOSIZE_Y(uvd->canvas);
+ vw.chromakey = 0;
+ if (VALID_CALLBACK(uvd, getFPS))
+ vw.flags = GET_CALLBACK(uvd, getFPS)(uvd);
+ else
+ vw.flags = 10; /* FIXME: do better! */
+
+ if (copy_to_user(arg, &vw, sizeof(vw)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDIOCGMBUF:
+ {
+ struct video_mbuf vm;
+
+ memset(&vm, 0, sizeof(vm));
+ vm.size = uvd->max_frame_size * 2;
+ vm.frames = 2;
+ vm.offsets[0] = 0;
+ vm.offsets[1] = uvd->max_frame_size;
+
+ if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDIOCMCAPTURE:
+ {
+ struct video_mmap vm;
+
+ if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm))) {
+ err("VIDIOCMCAPTURE: copy_from_user() failed.");
+ return -EFAULT;
+ }
+ if (uvd->debug >= 1) {
+ info("VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.",
+ vm.frame, vm.width, vm.height, vm.format);
+ }
+ /*
+ * Check if the requested size is supported. If the requestor
+ * requests too big a frame then we may be tricked into accessing
+ * outside of own preallocated frame buffer (in uvd->frame).
+ * This will cause oops or a security hole. Theoretically, we
+ * could only clamp the size down to acceptable bounds, but then
+ * we'd need to figure out how to insert our smaller buffer into
+ * larger caller's buffer... this is not an easy question. So we
+ * here just flatly reject too large requests, assuming that the
+ * caller will resubmit with smaller size. Callers should know
+ * what size we support (returned by VIDIOCGCAP). However vidcat,
+ * for one, does not care and allows to ask for any size.
+ */
+ if ((vm.width > VIDEOSIZE_X(uvd->canvas)) ||
+ (vm.height > VIDEOSIZE_Y(uvd->canvas))) {
+ if (uvd->debug > 0) {
+ info("VIDIOCMCAPTURE: Size=%dx%d too large; "
+ "allowed only up to %ldx%ld", vm.width, vm.height,
+ VIDEOSIZE_X(uvd->canvas), VIDEOSIZE_Y(uvd->canvas));
+ }
+ return -EINVAL;
+ }
+ /* Check if the palette is supported */
+ if (((1L << vm.format) & uvd->paletteBits) == 0) {
+ if (uvd->debug > 0) {
+ info("VIDIOCMCAPTURE: format=%d. not supported"
+ " (paletteBits=$%08lx)",
+ vm.format, uvd->paletteBits);
+ }
+ return -EINVAL;
+ }
+ if ((vm.frame != 0) && (vm.frame != 1)) {
+ err("VIDIOCMCAPTURE: vm.frame=%d. !E [0,1]", vm.frame);
+ return -EINVAL;
+ }
+ if (uvd->frame[vm.frame].frameState == FrameState_Grabbing) {
+ /* Not an error - can happen */
+ }
+ uvd->frame[vm.frame].request = VIDEOSIZE(vm.width, vm.height);
+ uvd->frame[vm.frame].palette = vm.format;
+
+ /* Mark it as ready */
+ uvd->frame[vm.frame].frameState = FrameState_Ready;
+
+ return usbvideo_NewFrame(uvd, vm.frame);
+ }
+ case VIDIOCSYNC:
+ {
+ int frameNum, ret;
+
+ if (copy_from_user((void *)&frameNum, arg, sizeof(frameNum))) {
+ err("VIDIOCSYNC: copy_from_user() failed.");
+ return -EFAULT;
+ }
+ if(frameNum < 0 || frameNum >= USBVIDEO_NUMFRAMES)
+ return -EINVAL;
+
+ if (uvd->debug >= 1)
+ info("VIDIOCSYNC: syncing to frame %d.", frameNum);
+ if (uvd->flags & FLAGS_NO_DECODING)
+ ret = usbvideo_GetFrame(uvd, frameNum);
+ else if (VALID_CALLBACK(uvd, getFrame)) {
+ ret = GET_CALLBACK(uvd, getFrame)(uvd, frameNum);
+ if ((ret < 0) && (uvd->debug >= 1)) {
+ err("VIDIOCSYNC: getFrame() returned %d.", ret);
+ }
+ } else {
+ err("VIDIOCSYNC: getFrame is not set");
+ ret = -EFAULT;
+ }
+
+ /*
+ * The frame is in FrameState_Done_Hold state. Release it
+ * right now because its data is already mapped into
+ * the user space and it's up to the application to
+ * make use of it until it asks for another frame.
+ */
+ uvd->frame[frameNum].frameState = FrameState_Unused;
+ return ret;
+ }
+ case VIDIOCGFBUF:
+ {
+ struct video_buffer vb;
+
+ memset(&vb, 0, sizeof(vb));
+ vb.base = NULL; /* frame buffer not supported, not used */
+
+ if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
+ return -EFAULT;
+
+ return 0;
+ }
+ case VIDIOCKEY:
+ return 0;
+
+ case VIDIOCCAPTURE:
+ return -EINVAL;
+
+ case VIDIOCSFBUF:
+
+ case VIDIOCGTUNER:
+ case VIDIOCSTUNER:
+
+ case VIDIOCGFREQ:
+ case VIDIOCSFREQ:
+
+ case VIDIOCGAUDIO:
+ case VIDIOCSAUDIO:
+ return -EINVAL;
+
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+/*
+ * usbvideo_v4l_read()
+ *
+ * This is mostly boring stuff. We simply ask for a frame and when it
+ * arrives copy all the video data from it into user space. There is
+ * no obvious need to override this method.
+ *
+ * History:
+ * 20-Oct-2000 Created.
+ * 01-Nov-2000 Added mutex (uvd->lock).
+ */
+long usbvideo_v4l_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
+{
+ static const char proc[] = "usbvideo_v4l_read";
+ uvd_t *uvd = (uvd_t *) dev;
+ int frmx = -1;
+ usbvideo_frame_t *frame;
+
+ if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
+ return -EFAULT;
+
+ if (uvd->debug >= 1)
+ info("%s: %ld. bytes, noblock=%d.", proc, count, noblock);
+
+ down(&uvd->lock);
+
+ /* See if a frame is completed, then use it. */
+ if ((uvd->frame[0].frameState == FrameState_Done) ||
+ (uvd->frame[0].frameState == FrameState_Done_Hold) ||
+ (uvd->frame[0].frameState == FrameState_Error)) {
+ frmx = 0;
+ } else if ((uvd->frame[1].frameState >= FrameState_Done) ||
+ (uvd->frame[1].frameState == FrameState_Done_Hold) ||
+ (uvd->frame[1].frameState >= FrameState_Done)) {
+ frmx = 1;
+ }
+
+ /* FIXME: If we don't start a frame here then who ever does? */
+ if (noblock && (frmx == -1)) {
+ count = -EAGAIN;
+ goto read_done;
+ }
+
+ /*
+ * If no FrameState_Done, look for a FrameState_Grabbing state.
+ * See if a frame is in process (grabbing), then use it.
+ * We will need to wait until it becomes cooked, of course.
+ */
+ if (frmx == -1) {
+ if (uvd->frame[0].frameState == FrameState_Grabbing)
+ frmx = 0;
+ else if (uvd->frame[1].frameState == FrameState_Grabbing)
+ frmx = 1;
+ }
+
+ /*
+ * If no frame is active, start one. We don't care which one
+ * it will be, so #0 is as good as any.
+ * In read access mode we don't have convenience of VIDIOCMCAPTURE
+ * to specify the requested palette (video format) on per-frame
+ * basis. This means that we have to return data in -some- format
+ * and just hope that the client knows what to do with it.
+ * The default format is configured in uvd->defaultPalette field
+ * as one of VIDEO_PALETTE_xxx values. We stuff it into the new
+ * frame and initiate the frame filling process.
+ */
+ if (frmx == -1) {
+ if (uvd->defaultPalette == 0) {
+ err("%s: No default palette; don't know what to do!", proc);
+ count = -EFAULT;
+ goto read_done;
+ }
+ frmx = 0;
+ /*
+ * We have no per-frame control over video size.
+ * Therefore we only can use whatever size was
+ * specified as default.
+ */
+ uvd->frame[frmx].request = uvd->videosize;
+ uvd->frame[frmx].palette = uvd->defaultPalette;
+ uvd->frame[frmx].frameState = FrameState_Ready;
+ usbvideo_NewFrame(uvd, frmx);
+ /* Now frame 0 is supposed to start filling... */
+ }
+
+ /*
+ * Get a pointer to the active frame. It is either previously
+ * completed frame or frame in progress but not completed yet.
+ */
+ frame = &uvd->frame[frmx];
+
+ /*
+ * Sit back & wait until the frame gets filled and postprocessed.
+ * If we fail to get the picture [in time] then return the error.
+ * In this call we specify that we want the frame to be waited for,
+ * postprocessed and switched into FrameState_Done_Hold state. This
+ * state is used to hold the frame as "fully completed" between
+ * subsequent partial reads of the same frame.
+ */
+ if (frame->frameState != FrameState_Done_Hold) {
+ long rv = -EFAULT;
+ if (uvd->flags & FLAGS_NO_DECODING)
+ rv = usbvideo_GetFrame(uvd, frmx);
+ else if (VALID_CALLBACK(uvd, getFrame))
+ rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx);
+ else
+ err("getFrame is not set");
+ if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) {
+ count = rv;
+ goto read_done;
+ }
+ }
+
+ /*
+ * Copy bytes to user space. We allow for partial reads, which
+ * means that the user application can request read less than
+ * the full frame size. It is up to the application to issue
+ * subsequent calls until entire frame is read.
+ *
+ * First things first, make sure we don't copy more than we
+ * have - even if the application wants more. That would be
+ * a big security embarassment!
+ */
+ if ((count + frame->seqRead_Index) > frame->seqRead_Length)
+ count = frame->seqRead_Length - frame->seqRead_Index;
+
+ /*
+ * Copy requested amount of data to user space. We start
+ * copying from the position where we last left it, which
+ * will be zero for a new frame (not read before).
+ */
+ if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) {
+ count = -EFAULT;
+ goto read_done;
+ }
+
+ /* Update last read position */
+ frame->seqRead_Index += count;
+ if (uvd->debug >= 1) {
+ err("%s: {copy} count used=%ld, new seqRead_Index=%ld",
+ proc, count, frame->seqRead_Index);
+ }
+
+ /* Finally check if the frame is done with and "release" it */
+ if (frame->seqRead_Index >= frame->seqRead_Length) {
+ /* All data has been read */
+ frame->seqRead_Index = 0;
+
+ /* Mark it as available to be used again. */
+ uvd->frame[frmx].frameState = FrameState_Unused;
+ if (usbvideo_NewFrame(uvd, frmx ? 0 : 1)) {
+ err("%s: usbvideo_NewFrame failed.", proc);
+ }
+ }
+read_done:
+ up(&uvd->lock);
+ return count;
+}
+
+/*
+ * Make all of the blocks of data contiguous
+ */
+static int usbvideo_CompressIsochronous(uvd_t *uvd, urb_t *urb)
+{
+ char *cdata;
+ int i, totlen = 0;
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int n = urb->iso_frame_desc[i].actual_length;
+ int st = urb->iso_frame_desc[i].status;
+
+ cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+
+ /* Detect and ignore errored packets */
+ if (st < 0) {
+ if (uvd->debug >= 1)
+ err("Data error: packet=%d. len=%d. status=%d.", i, n, st);
+ uvd->stats.iso_err_count++;
+ continue;
+ }
+
+ /* Detect and ignore empty packets */
+ if (n <= 0) {
+ uvd->stats.iso_skip_count++;
+ continue;
+ }
+ totlen += n; /* Little local accounting */
+ RingQueue_Enqueue(&uvd->dp, cdata, n);
+ }
+ return totlen;
+}
+
+static void usbvideo_IsocIrq(struct urb *urb)
+{
+ int i, len;
+ uvd_t *uvd = urb->context;
+
+ /* We don't want to do anything if we are about to be removed! */
+ if (!CAMERA_IS_OPERATIONAL(uvd))
+ return;
+#if 0
+ if (urb->actual_length > 0) {
+ info("urb=$%p status=%d. errcount=%d. length=%d.",
+ urb, urb->status, urb->error_count, urb->actual_length);
+ } else {
+ static int c = 0;
+ if (c++ % 100 == 0)
+ info("No Isoc data");
+ }
+#endif
+
+ if (!uvd->streaming) {
+ if (uvd->debug >= 1)
+ info("Not streaming, but interrupt!");
+ return;
+ }
+
+ uvd->stats.urb_count++;
+ if (urb->actual_length <= 0)
+ goto urb_done_with;
+
+ /* Copy the data received into ring queue */
+ len = usbvideo_CompressIsochronous(uvd, urb);
+ uvd->stats.urb_length = len;
+ if (len <= 0)
+ goto urb_done_with;
+
+ /* Here we got some data */
+ uvd->stats.data_count += len;
+ RingQueue_WakeUpInterruptible(&uvd->dp);
+
+urb_done_with:
+ for (i = 0; i < FRAMES_PER_DESC; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ return;
+}
+
+/*
+ * usbvideo_StartDataPump()
+ *
+ * History:
+ * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead
+ * of hardcoded values. Simplified by using for loop,
+ * allowed any number of URBs.
+ */
+int usbvideo_StartDataPump(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_StartDataPump";
+ struct usb_device *dev = uvd->dev;
+ int i, errFlag;
+
+ if (uvd->debug > 1)
+ info("%s($%p)", proc, uvd);
+
+ if (!CAMERA_IS_OPERATIONAL(uvd)) {
+ err("%s: Camera is not operational",proc);
+ return -EFAULT;
+ }
+ uvd->curframe = -1;
+
+ /* Alternate interface 1 is is the biggest frame size */
+ i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
+ if (i < 0) {
+ err("%s: usb_set_interface error", proc);
+ uvd->last_error = i;
+ return -EBUSY;
+ }
+ if (VALID_CALLBACK(uvd, videoStart))
+ GET_CALLBACK(uvd, videoStart)(uvd);
+ else
+ err("%s: videoStart not set", proc);
+
+ /* We double buffer the Iso lists */
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ int j, k;
+ urb_t *urb = uvd->sbuf[i].urb;
+ urb->dev = dev;
+ urb->context = uvd;
+ urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
+ urb->transfer_flags = USB_ISO_ASAP;
+ urb->transfer_buffer = uvd->sbuf[i].data;
+ urb->complete = usbvideo_IsocIrq;
+ urb->number_of_packets = FRAMES_PER_DESC;
+ urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
+ for (j=k=0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length = uvd->iso_packet_len;
+ }
+ }
+
+ /* Link URBs into a ring so that they invoke each other infinitely */
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ if ((i+1) < USBVIDEO_NUMSBUF)
+ uvd->sbuf[i].urb->next = uvd->sbuf[i+1].urb;
+ else
+ uvd->sbuf[i].urb->next = uvd->sbuf[0].urb;
+ }
+
+ /* Submit all URBs */
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ errFlag = usb_submit_urb(uvd->sbuf[i].urb);
+ if (errFlag)
+ err("%s: usb_submit_isoc(%d) ret %d", proc, i, errFlag);
+ }
+
+ uvd->streaming = 1;
+ if (uvd->debug > 1)
+ info("%s: streaming=1 video_endp=$%02x", proc, uvd->video_endp);
+ return 0;
+}
+
+/*
+ * usbvideo_StopDataPump()
+ *
+ * This procedure stops streaming and deallocates URBs. Then it
+ * activates zero-bandwidth alt. setting of the video interface.
+ *
+ * History:
+ * 22-Jan-2000 Corrected order of actions to work after surprise removal.
+ * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
+ */
+void usbvideo_StopDataPump(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_StopDataPump";
+ int i, j;
+
+ if (uvd->debug > 1)
+ info("%s($%p)", proc, uvd);
+
+ if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
+ return;
+
+ /* Unschedule all of the iso td's */
+ for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+ j = usb_unlink_urb(uvd->sbuf[i].urb);
+ if (j < 0)
+ err("%s: usb_unlink_urb() error %d.", proc, j);
+ }
+ if (uvd->debug > 1)
+ info("%s: streaming=0", proc);
+ uvd->streaming = 0;
+
+ if (!uvd->remove_pending) {
+ /* Invoke minidriver's magic to stop the camera */
+ if (VALID_CALLBACK(uvd, videoStop))
+ GET_CALLBACK(uvd, videoStop)(uvd);
+ else
+ err("%s: videoStop not set" ,proc);
+
+ /* Set packet size to 0 */
+ j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
+ if (j < 0) {
+ err("%s: usb_set_interface() error %d.", proc, j);
+ uvd->last_error = j;
+ }
+ }
+}
+
+/*
+ * usbvideo_NewFrame()
+ *
+ * History:
+ * 29-Mar-00 Added copying of previous frame into the current one.
+ * 6-Aug-00 Added model 3 video sizes, removed redundant width, height.
+ */
+int usbvideo_NewFrame(uvd_t *uvd, int framenum)
+{
+ usbvideo_frame_t *frame;
+ int n;
+
+ if (uvd->debug > 1)
+ info("usbvideo_NewFrame($%p,%d.)", uvd, framenum);
+
+ /* If we're not grabbing a frame right now and the other frame is */
+ /* ready to be grabbed into, then use it instead */
+ if (uvd->curframe != -1)
+ return 0;
+
+ /* If necessary we adjust picture settings between frames */
+ if (!uvd->settingsAdjusted) {
+ if (VALID_CALLBACK(uvd, adjustPicture))
+ GET_CALLBACK(uvd, adjustPicture)(uvd);
+ uvd->settingsAdjusted = 1;
+ }
+
+ n = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
+ if (uvd->frame[n].frameState == FrameState_Ready)
+ framenum = n;
+
+ frame = &uvd->frame[framenum];
+
+ frame->frameState = FrameState_Grabbing;
+ frame->scanstate = ScanState_Scanning;
+ frame->seqRead_Length = 0; /* Accumulated in xxx_parse_data() */
+ frame->deinterlace = Deinterlace_None;
+ frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */
+ uvd->curframe = framenum;
+
+ /*
+ * Normally we would want to copy previous frame into the current one
+ * before we even start filling it with data; this allows us to stop
+ * filling at any moment; top portion of the frame will be new and
+ * bottom portion will stay as it was in previous frame. If we don't
+ * do that then missing chunks of video stream will result in flickering
+ * portions of old data whatever it was before.
+ *
+ * If we choose not to copy previous frame (to, for example, save few
+ * bus cycles - the frame can be pretty large!) then we have an option
+ * to clear the frame before using. If we experience losses in this
+ * mode then missing picture will be black (no flickering).
+ *
+ * Finally, if user chooses not to clean the current frame before
+ * filling it with data then the old data will be visible if we fail
+ * to refill entire frame with new data.
+ */
+ if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
+ /* This copies previous frame into this one to mask losses */
+ memmove(frame->data, uvd->frame[1-framenum].data, uvd->max_frame_size);
+ } else {
+ if (uvd->flags & FLAGS_CLEAN_FRAMES) {
+ /* This provides a "clean" frame but slows things down */
+ memset(frame->data, 0, uvd->max_frame_size);
+ }
+ }
+ return 0;
+}
+
+/*
+ * usbvideo_CollectRawData()
+ *
+ * This procedure can be used instead of 'processData' callback if you
+ * only want to dump the raw data from the camera into the output
+ * device (frame buffer). You can look at it with V4L client, but the
+ * image will be unwatchable. The main purpose of this code and of the
+ * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from
+ * new, unknown cameras. This procedure will be automatically invoked
+ * instead of the specified callback handler when uvd->flags has bit
+ * FLAGS_NO_DECODING set. Therefore, any regular build of any driver
+ * based on usbvideo can use this feature at any time.
+ */
+void usbvideo_CollectRawData(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+ int n;
+
+ assert(uvd != NULL);
+ assert(frame != NULL);
+
+ /* Try to move data from queue into frame buffer */
+ n = RingQueue_GetLength(&uvd->dp);
+ if (n > 0) {
+ int m;
+ /* See how much space we have left */
+ m = uvd->max_frame_size - frame->seqRead_Length;
+ if (n > m)
+ n = m;
+ /* Now move that much data into frame buffer */
+ RingQueue_Dequeue(
+ &uvd->dp,
+ frame->data + frame->seqRead_Length,
+ m);
+ frame->seqRead_Length += m;
+ }
+ /* See if we filled the frame */
+ if (frame->seqRead_Length >= uvd->max_frame_size) {
+ frame->frameState = FrameState_Done;
+ uvd->curframe = -1;
+ uvd->stats.frame_num++;
+ }
+}
+
+int usbvideo_GetFrame(uvd_t *uvd, int frameNum)
+{
+ static const char proc[] = "usbvideo_GetFrame";
+ usbvideo_frame_t *frame = &uvd->frame[frameNum];
+
+ if (uvd->debug >= 2)
+ info("%s($%p,%d.)", proc, uvd, frameNum);
+
+ switch (frame->frameState) {
+ case FrameState_Unused:
+ if (uvd->debug >= 2)
+ info("%s: FrameState_Unused", proc);
+ return -EINVAL;
+ case FrameState_Ready:
+ case FrameState_Grabbing:
+ case FrameState_Error:
+ {
+ int ntries, signalPending;
+ redo:
+ if (!CAMERA_IS_OPERATIONAL(uvd)) {
+ if (uvd->debug >= 2)
+ info("%s: Camera is not operational (1)", proc);
+ return -EIO;
+ }
+ ntries = 0;
+ do {
+ RingQueue_InterruptibleSleepOn(&uvd->dp);
+ signalPending = signal_pending(current);
+ if (!CAMERA_IS_OPERATIONAL(uvd)) {
+ if (uvd->debug >= 2)
+ info("%s: Camera is not operational (2)", proc);
+ return -EIO;
+ }
+ assert(uvd->fbuf != NULL);
+ if (signalPending) {
+ if (uvd->debug >= 2)
+ info("%s: Signal=$%08x", proc, signalPending);
+ if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) {
+ usbvideo_TestPattern(uvd, 1, 0);
+ uvd->curframe = -1;
+ uvd->stats.frame_num++;
+ if (uvd->debug >= 2)
+ info("%s: Forced test pattern screen", proc);
+ return 0;
+ } else {
+ /* Standard answer: Interrupted! */
+ if (uvd->debug >= 2)
+ info("%s: Interrupted!", proc);
+ return -EINTR;
+ }
+ } else {
+ /* No signals - we just got new data in dp queue */
+ if (uvd->flags & FLAGS_NO_DECODING)
+ usbvideo_CollectRawData(uvd, frame);
+ else if (VALID_CALLBACK(uvd, processData))
+ GET_CALLBACK(uvd, processData)(uvd, frame);
+ else
+ err("%s: processData not set", proc);
+ }
+ } while (frame->frameState == FrameState_Grabbing);
+ if (uvd->debug >= 2) {
+ info("%s: Grabbing done; state=%d. (%lu. bytes)",
+ proc, frame->frameState, frame->seqRead_Length);
+ }
+ if (frame->frameState == FrameState_Error) {
+ int ret = usbvideo_NewFrame(uvd, frameNum);
+ if (ret < 0) {
+ err("%s: usbvideo_NewFrame() failed (%d.)", proc, ret);
+ return ret;
+ }
+ goto redo;
+ }
+ /* Note that we fall through to meet our destiny below */
+ }
+ case FrameState_Done:
+ /*
+ * Do all necessary postprocessing of data prepared in
+ * "interrupt" code and the collecting code above. The
+ * frame gets marked as FrameState_Done by queue parsing code.
+ * This status means that we collected enough data and
+ * most likely processed it as we went through. However
+ * the data may need postprocessing, such as deinterlacing
+ * or picture adjustments implemented in software (horror!)
+ *
+ * As soon as the frame becomes "final" it gets promoted to
+ * FrameState_Done_Hold status where it will remain until the
+ * caller consumed all the video data from the frame. Then
+ * the empty shell of ex-frame is thrown out for dogs to eat.
+ * But we, worried about pets, will recycle the frame!
+ */
+ uvd->stats.frame_num++;
+ if ((uvd->flags & FLAGS_NO_DECODING) == 0) {
+ if (VALID_CALLBACK(uvd, postProcess))
+ GET_CALLBACK(uvd, postProcess)(uvd, frame);
+ if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST)
+ usbvideo_SoftwareContrastAdjustment(uvd, frame);
+ }
+ frame->frameState = FrameState_Done_Hold;
+ if (uvd->debug >= 2)
+ info("%s: Entered FrameState_Done_Hold state.", proc);
+ return 0;
+
+ case FrameState_Done_Hold:
+ /*
+ * We stay in this state indefinitely until someone external,
+ * like ioctl() or read() call finishes digesting the frame
+ * data. Then it will mark the frame as FrameState_Unused and
+ * it will be released back into the wild to roam freely.
+ */
+ if (uvd->debug >= 2)
+ info("%s: FrameState_Done_Hold state.", proc);
+ return 0;
+ }
+
+ /* Catch-all for other cases. We shall not be here. */
+ err("%s: Invalid state %d.", proc, frame->frameState);
+ frame->frameState = FrameState_Unused;
+ return 0;
+}
+
+/*
+ * usbvideo_DeinterlaceFrame()
+ *
+ * This procedure deinterlaces the given frame. Some cameras produce
+ * only half of scanlines - sometimes only even lines, sometimes only
+ * odd lines. The deinterlacing method is stored in frame->deinterlace
+ * variable.
+ *
+ * Here we scan the frame vertically and replace missing scanlines with
+ * average between surrounding ones - before and after. If we have no
+ * line above then we just copy next line. Similarly, if we need to
+ * create a last line then preceding line is used.
+ */
+void usbvideo_DeinterlaceFrame(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+ if ((uvd == NULL) || (frame == NULL))
+ return;
+
+ if ((frame->deinterlace == Deinterlace_FillEvenLines) ||
+ (frame->deinterlace == Deinterlace_FillOddLines))
+ {
+ const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
+ int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1;
+
+ for (; i < VIDEOSIZE_Y(frame->request); i += 2) {
+ const unsigned char *fs1, *fs2;
+ unsigned char *fd;
+ int ip, in, j; /* Previous and next lines */
+
+ /*
+ * Need to average lines before and after 'i'.
+ * If we go out of bounds seeking those lines then
+ * we point back to existing line.
+ */
+ ip = i - 1; /* First, get rough numbers */
+ in = i + 1;
+
+ /* Now validate */
+ if (ip < 0)
+ ip = in;
+ if (in >= VIDEOSIZE_Y(frame->request))
+ in = ip;
+
+ /* Sanity check */
+ if ((ip < 0) || (in < 0) ||
+ (ip >= VIDEOSIZE_Y(frame->request)) ||
+ (in >= VIDEOSIZE_Y(frame->request)))
+ {
+ err("Error: ip=%d. in=%d. req.height=%ld.",
+ ip, in, VIDEOSIZE_Y(frame->request));
+ break;
+ }
+
+ /* Now we need to average lines 'ip' and 'in' to produce line 'i' */
+ fs1 = frame->data + (v4l_linesize * ip);
+ fs2 = frame->data + (v4l_linesize * in);
+ fd = frame->data + (v4l_linesize * i);
+
+ /* Average lines around destination */
+ for (j=0; j < v4l_linesize; j++) {
+ fd[j] = (unsigned char)((((unsigned) fs1[j]) +
+ ((unsigned)fs2[j])) >> 1);
+ }
+ }
+ }
+
+ /* Optionally display statistics on the screen */
+ if (uvd->flags & FLAGS_OVERLAY_STATS)
+ usbvideo_OverlayStats(uvd, frame);
+}
+
+/*
+ * usbvideo_SoftwareContrastAdjustment()
+ *
+ * This code adjusts the contrast of the frame, assuming RGB24 format.
+ * As most software image processing, this job is CPU-intensive.
+ * Get a camera that supports hardware adjustment!
+ *
+ * History:
+ * 09-Feb-2001 Created.
+ */
+void usbvideo_SoftwareContrastAdjustment(uvd_t *uvd, usbvideo_frame_t *frame)
+{
+ static const char proc[] = "usbvideo_SoftwareContrastAdjustment";
+ int i, j, v4l_linesize;
+ signed long adj;
+ const int ccm = 128; /* Color correction median - see below */
+
+ if ((uvd == NULL) || (frame == NULL)) {
+ err("%s: Illegal call.", proc);
+ return;
+ }
+ adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
+ RESTRICT_TO_RANGE(adj, -ccm, ccm+1);
+ if (adj == 0) {
+ /* In rare case of no adjustment */
+ return;
+ }
+ v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
+ for (i=0; i < VIDEOSIZE_Y(frame->request); i++) {
+ unsigned char *fd = frame->data + (v4l_linesize * i);
+ for (j=0; j < v4l_linesize; j++) {
+ signed long v = (signed long) fd[j];
+ /* Magnify up to 2 times, reduce down to zero */
+ v = 128 + ((ccm + adj) * (v - 128)) / ccm;
+ RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */
+ fd[j] = (unsigned char) v;
+ }
+ }
+}
+
+/*
+ * /proc interface
+ *
+ * We will be creating directories and entries under /proc/video using
+ * external 'video_proc_entry' directory which is exported by videodev.o
+ * module. Within that directory we will create $driver/ directory to
+ * uniquely and uniformly refer to our specific $driver. Within that
+ * directory we will finally create an entry that is named after the
+ * video device node - video3, for example. The format of that file
+ * is determined by callbacks that the minidriver may provide. If no
+ * callbacks are provided (neither read nor write) then we don't create
+ * the entry.
+ *
+ * Here is a sample directory entry: /proc/video/ibmcam/video3
+ *
+ * The "file" video3 (in example above) is readable and writeable, in
+ * theory. If the minidriver provides callbacks to do reading and
+ * writing then both those procedures are supported. However if the
+ * driver leaves callbacks in default (NULL) state the default
+ * read and write handlers are used. The default read handler reports
+ * that the driver does not support /proc fs. The default write handler
+ * returns error code on any write attempt.
+ */
+
+#if USES_PROC_FS
+
+extern struct proc_dir_entry *video_proc_entry;
+
+static void usbvideo_procfs_level1_create(usbvideo_t *ut)
+{
+ static const char proc[] = "usbvideo_procfs_level1_create";
+
+ if (ut == NULL) {
+ err("%s: ut == NULL", proc);
+ return;
+ }
+ if (video_proc_entry == NULL) {
+ err("%s: /proc/video/ doesn't exist.", proc);
+ return;
+ }
+ ut->procfs_dEntry = create_proc_entry(ut->drvName, S_IFDIR, video_proc_entry);
+ if (ut->procfs_dEntry != NULL) {
+ if (ut->md_module != NULL)
+ ut->procfs_dEntry->owner = ut->md_module;
+ } else {
+ err("%s: Unable to initialize /proc/video/%s", proc, ut->drvName);
+ }
+}
+
+static void usbvideo_procfs_level1_destroy(usbvideo_t *ut)
+{
+ static const char proc[] = "usbvideo_procfs_level1_destroy";
+
+ if (ut == NULL) {
+ err("%s: ut == NULL", proc);
+ return;
+ }
+ if (ut->procfs_dEntry != NULL) {
+ remove_proc_entry(ut->drvName, video_proc_entry);
+ ut->procfs_dEntry = NULL;
+ }
+}
+
+static void usbvideo_procfs_level2_create(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_procfs_level2_create";
+
+ if (uvd == NULL) {
+ err("%s: uvd == NULL", proc);
+ return;
+ }
+ assert(uvd->handle != NULL);
+ if (uvd->handle->procfs_dEntry == NULL) {
+ err("%s: uvd->handle->procfs_dEntry == NULL", proc);
+ return;
+ }
+
+ sprintf(uvd->videoName, "video%d", uvd->vdev.minor);
+ uvd->procfs_vEntry = create_proc_entry(
+ uvd->videoName,
+ S_IFREG | S_IRUGO | S_IWUSR,
+ uvd->handle->procfs_dEntry);
+ if (uvd->procfs_vEntry != NULL) {
+ uvd->procfs_vEntry->data = uvd;
+ uvd->procfs_vEntry->read_proc = uvd->handle->cb.procfs_read;
+ uvd->procfs_vEntry->write_proc = uvd->handle->cb.procfs_write;
+ } else {
+ err("%s: Failed to create entry \"%s\"", proc, uvd->videoName);
+ }
+}
+
+static void usbvideo_procfs_level2_destroy(uvd_t *uvd)
+{
+ static const char proc[] = "usbvideo_procfs_level2_destroy";
+
+ if (uvd == NULL) {
+ err("%s: uvd == NULL", proc);
+ return;
+ }
+ if (uvd->procfs_vEntry != NULL) {
+ remove_proc_entry(uvd->videoName, uvd->procfs_vEntry);
+ uvd->procfs_vEntry = NULL;
+ }
+}
+
+static int usbvideo_default_procfs_read_proc(
+ char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ char *out = page;
+ int len;
+
+ /* Stay under PAGE_SIZE or else */
+ out += sprintf(out, "This driver does not support /proc services.\n");
+ len = out - page;
+ len -= off;
+ if (len < count) {
+ *eof = 1;
+ if (len <= 0)
+ return 0;
+ } else
+ len = count;
+ *start = page + off;
+ return len;
+}
+
+static int usbvideo_default_procfs_write_proc(
+ struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ return -EINVAL;
+}
+
+#endif /* USES_PROC_FS */
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef usbvideo_h
+#define usbvideo_h
+
+#include <linux/config.h>
+#include <linux/proc_fs.h>
+#include <linux/videodev.h>
+#include <linux/usb.h>
+
+/* Most helpful debugging aid */
+#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
+
+#define USES_PROC_FS (defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS))
+#define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */
+
+/* Bit flags (options) */
+#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
+#define FLAGS_MONOCHROME (1 << 1)
+#define FLAGS_DISPLAY_HINTS (1 << 2)
+#define FLAGS_OVERLAY_STATS (1 << 3)
+#define FLAGS_FORCE_TESTPATTERN (1 << 4)
+#define FLAGS_SEPARATE_FRAMES (1 << 5)
+#define FLAGS_CLEAN_FRAMES (1 << 6)
+#define FLAGS_NO_DECODING (1 << 7)
+
+/* Bit flags for frames (apply to the frame where they are specified) */
+#define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST (1 << 0)
+
+/* Camera capabilities (maximum) */
+#define CAMERA_URB_FRAMES 32
+#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
+#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
+#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
+
+/* This macro restricts an int variable to an inclusive range */
+#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
+
+#define V4L_BYTES_PER_PIXEL 3 /* Because we produce RGB24 */
+
+/*
+ * Use this macro to construct constants for different video sizes.
+ * We have to deal with different video sizes that have to be
+ * configured in the device or compared against when we receive
+ * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y
+ * #defines and that's the end of story. However this solution
+ * does not allow to convert between real pixel sizes and the
+ * constant (integer) value that may be used to tag a frame or
+ * whatever. The set of macros below constructs videosize constants
+ * from the pixel size and allows to reconstruct the pixel size
+ * from the combined value later.
+ */
+#define VIDEOSIZE(x,y) (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16))
+#define VIDEOSIZE_X(vs) ((vs) & 0xFFFFL)
+#define VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL)
+typedef unsigned long videosize_t;
+
+/*
+ * This macro checks if the camera is still operational. The 'uvd'
+ * pointer must be valid, uvd->dev must be valid, we are not
+ * removing the device and the device has not erred on us.
+ */
+#define CAMERA_IS_OPERATIONAL(uvd) (\
+ (uvd != NULL) && \
+ ((uvd)->dev != NULL) && \
+ ((uvd)->last_error == 0) && \
+ (!(uvd)->remove_pending))
+
+/*
+ * We use macros to do YUV -> RGB conversion because this is
+ * very important for speed and totally unimportant for size.
+ *
+ * YUV -> RGB Conversion
+ * ---------------------
+ *
+ * B = 1.164*(Y-16) + 2.018*(V-128)
+ * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
+ * R = 1.164*(Y-16) + 1.596*(U-128)
+ *
+ * If you fancy integer arithmetics (as you should), hear this:
+ *
+ * 65536*B = 76284*(Y-16) + 132252*(V-128)
+ * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
+ * 65536*R = 76284*(Y-16) + 104595*(U-128)
+ *
+ * Make sure the output values are within [0..255] range.
+ */
+#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
+#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
+ int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
+ mm_y = (my) - 16; \
+ mm_u = (mu) - 128; \
+ mm_v = (mv) - 128; \
+ mm_yc= mm_y * 76284; \
+ mm_b = (mm_yc + 132252*mm_v ) >> 16; \
+ mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
+ mm_r = (mm_yc + 104595*mm_u ) >> 16; \
+ mb = LIMIT_RGB(mm_b); \
+ mg = LIMIT_RGB(mm_g); \
+ mr = LIMIT_RGB(mm_r); \
+}
+
+#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) % (rq)->length
+#define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
+#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) % (rq)->length])
+
+typedef struct {
+ unsigned char *queue; /* Data from the Isoc data pump */
+ int length; /* How many bytes allocated for the queue */
+ int wi; /* That's where we write */
+ int ri; /* Read from here until you hit write index */
+ wait_queue_head_t wqh; /* Processes waiting */
+} RingQueue_t;
+
+typedef enum {
+ ScanState_Scanning, /* Scanning for header */
+ ScanState_Lines /* Parsing lines */
+} ScanState_t;
+
+/* Completion states of the data parser */
+typedef enum {
+ scan_Continue, /* Just parse next item */
+ scan_NextFrame, /* Frame done, send it to V4L */
+ scan_Out, /* Not enough data for frame */
+ scan_EndParse /* End parsing */
+} ParseState_t;
+
+typedef enum {
+ FrameState_Unused, /* Unused (no MCAPTURE) */
+ FrameState_Ready, /* Ready to start grabbing */
+ FrameState_Grabbing, /* In the process of being grabbed into */
+ FrameState_Done, /* Finished grabbing, but not been synced yet */
+ FrameState_Done_Hold, /* Are syncing or reading */
+ FrameState_Error, /* Something bad happened while processing */
+} FrameState_t;
+
+/*
+ * Some frames may contain only even or odd lines. This type
+ * specifies what type of deinterlacing is required.
+ */
+typedef enum {
+ Deinterlace_None=0,
+ Deinterlace_FillOddLines,
+ Deinterlace_FillEvenLines
+} Deinterlace_t;
+
+struct usb_device;
+
+#define USBVIDEO_NUMFRAMES 2 /* How many frames we work with */
+#define USBVIDEO_NUMSBUF 2 /* How many URBs linked in a ring */
+
+/* This structure represents one Isoc request - URB and buffer */
+typedef struct {
+ char *data;
+ urb_t *urb;
+} usbvideo_sbuf_t;
+
+typedef struct {
+ char *data; /* Frame buffer */
+ unsigned long header; /* Significant bits from the header */
+
+ videosize_t canvas; /* The canvas (max. image) allocated */
+ videosize_t request; /* That's what the application asked for */
+ unsigned short palette; /* The desired format */
+
+ FrameState_t frameState;/* State of grabbing */
+ ScanState_t scanstate; /* State of scanning */
+ Deinterlace_t deinterlace;
+ int flags; /* USBVIDEO_FRAME_FLAG_xxx bit flags */
+
+ int curline; /* Line of frame we're working on */
+
+ long seqRead_Length; /* Raw data length of frame */
+ long seqRead_Index; /* Amount of data that has been already read */
+
+ void *user; /* Additional data that user may need */
+} usbvideo_frame_t;
+
+/* Statistics that can be overlaid on screen */
+typedef struct {
+ unsigned long frame_num; /* Sequential number of the frame */
+ unsigned long urb_count; /* How many URBs we received so far */
+ unsigned long urb_length; /* Length of last URB */
+ unsigned long data_count; /* How many bytes we received */
+ unsigned long header_count; /* How many frame headers we found */
+ unsigned long iso_skip_count; /* How many empty ISO packets received */
+ unsigned long iso_err_count; /* How many bad ISO packets received */
+} usbvideo_statistics_t;
+
+struct s_usbvideo_t;
+
+typedef struct {
+ struct video_device vdev; /* Must be the first field! */
+ struct usb_device *dev;
+ struct s_usbvideo_t *handle; /* Points back to the usbvideo_t */
+ void *user_data; /* Camera-dependent data */
+ int user_size; /* Size of that camera-dependent data */
+ int debug; /* Debug level for usbvideo */
+ unsigned char iface; /* Video interface number */
+ unsigned char video_endp;
+ unsigned char ifaceAltActive;
+ unsigned char ifaceAltInactive; /* Alt settings */
+ unsigned long flags; /* FLAGS_USBVIDEO_xxx */
+ unsigned long paletteBits; /* Which palettes we accept? */
+ unsigned short defaultPalette; /* What palette to use for read() */
+ struct semaphore lock;
+ int user; /* user count for exclusive use */
+
+ videosize_t videosize; /* Current setting */
+ videosize_t canvas; /* This is the width,height of the V4L canvas */
+ int max_frame_size; /* Bytes in one video frame */
+
+ int uvd_used; /* Is this structure in use? */
+ int streaming; /* Are we streaming Isochronous? */
+ int grabbing; /* Are we grabbing? */
+ int settingsAdjusted; /* Have we adjusted contrast etc.? */
+ int last_error; /* What calamity struck us? */
+
+ char *fbuf; /* Videodev buffer area */
+ int fbuf_size; /* Videodev buffer size */
+
+ int curframe;
+ int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
+
+ RingQueue_t dp; /* Isoc data pump */
+ usbvideo_frame_t frame[USBVIDEO_NUMFRAMES];
+ usbvideo_sbuf_t sbuf[USBVIDEO_NUMSBUF];
+
+ volatile int remove_pending; /* If set then about to exit */
+
+ struct video_picture vpic, vpic_old; /* Picture settings */
+ struct video_capability vcap; /* Video capabilities */
+ struct video_channel vchan; /* May be used for tuner support */
+ usbvideo_statistics_t stats;
+ struct proc_dir_entry *procfs_vEntry; /* /proc/video/MYDRIVER/video2 */
+ char videoName[32]; /* Holds name like "video7" */
+} uvd_t;
+
+/*
+ * usbvideo callbacks (virtual methods). They are set when usbvideo
+ * services are registered. All of these default to NULL, except those
+ * that default to usbvideo-provided methods.
+ */
+typedef struct {
+#if defined(usb_device_id_ver)
+ /* New style probe (for 2.4.x kernels with hotplugging) */
+ void *(*probe)(struct usb_device *, unsigned int,const struct usb_device_id *);
+#else
+ /* Old style probe (for 2.2.x kernels) */
+ void *(*probe)(struct usb_device *, unsigned int);
+#endif
+ void (*userFree)(uvd_t *);
+ void (*disconnect)(struct usb_device *, void *);
+ int (*setupOnOpen)(uvd_t *);
+ void (*videoStart)(uvd_t *);
+ void (*videoStop)(uvd_t *);
+ void (*processData)(uvd_t *, usbvideo_frame_t *);
+ void (*postProcess)(uvd_t *, usbvideo_frame_t *);
+ void (*adjustPicture)(uvd_t *);
+ int (*getFPS)(uvd_t *);
+ int (*overlayHook)(uvd_t *, usbvideo_frame_t *);
+ int (*getFrame)(uvd_t *, int);
+ int (*procfs_read)(char *page,char **start,off_t off,int count,int *eof,void *data);
+ int (*procfs_write)(struct file *file,const char *buffer,unsigned long count,void *data);
+} usbvideo_cb_t;
+
+struct s_usbvideo_t {
+ int num_cameras; /* As allocated */
+ struct usb_driver usbdrv; /* Interface to the USB stack */
+ char drvName[80]; /* Driver name */
+ struct semaphore lock; /* Mutex protecting camera structures */
+ usbvideo_cb_t cb; /* Table of callbacks (virtual methods) */
+ struct video_device vdt; /* Video device template */
+ uvd_t *cam; /* Array of camera structures */
+ int uses_procfs; /* Non-zero if we create /proc entries */
+ struct proc_dir_entry *procfs_dEntry; /* /proc/video/MYDRIVER */
+ struct module *md_module; /* Minidriver module */
+};
+typedef struct s_usbvideo_t usbvideo_t;
+
+/*
+ * This macro retrieves callback address from the uvd_t object.
+ * No validity checks are done here, so be sure to check the
+ * callback beforehand with VALID_CALLBACK.
+ */
+#define GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName)
+
+/*
+ * This macro returns either callback pointer or NULL. This is safe
+ * macro, meaning that most of components of data structures involved
+ * may be NULL - this only results in NULL being returned. You may
+ * wish to use this macro to make sure that the callback is callable.
+ * However keep in mind that those checks take time.
+ */
+#define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
+ ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
+
+void RingQueue_Initialize(RingQueue_t *rq);
+void RingQueue_Allocate(RingQueue_t *rq, int rqLen);
+int RingQueue_IsAllocated(const RingQueue_t *rq);
+void RingQueue_Free(RingQueue_t *rq);
+int RingQueue_Dequeue(RingQueue_t *rq, unsigned char *dst, int len);
+int RingQueue_Enqueue(RingQueue_t *rq, const unsigned char *cdata, int n);
+int RingQueue_GetLength(const RingQueue_t *rq);
+void RingQueue_InterruptibleSleepOn(RingQueue_t *rq);
+void RingQueue_WakeUpInterruptible(RingQueue_t *rq);
+
+void usbvideo_CollectRawData(uvd_t *uvd, usbvideo_frame_t *frame);
+void usbvideo_DrawLine(
+ usbvideo_frame_t *frame,
+ int x1, int y1,
+ int x2, int y2,
+ unsigned char cr, unsigned char cg, unsigned char cb);
+void usbvideo_HexDump(const unsigned char *data, int len);
+void usbvideo_OverlayChar(uvd_t *uvd, usbvideo_frame_t *frame, int x, int y, int ch);
+void usbvideo_OverlayString(uvd_t *uvd, usbvideo_frame_t *frame, int x, int y, const char *str);
+void usbvideo_OverlayStats(uvd_t *uvd, usbvideo_frame_t *frame);
+void usbvideo_ReportStatistics(const uvd_t *uvd);
+void usbvideo_SayAndWait(const char *what);
+void usbvideo_TestPattern(uvd_t *uvd, int fullframe, int pmode);
+void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs);
+
+/* Memory allocation routines */
+unsigned long usbvideo_uvirt_to_kva(pgd_t *pgd, unsigned long adr);
+unsigned long usbvideo_uvirt_to_bus(unsigned long adr);
+unsigned long usbvideo_kvirt_to_bus(unsigned long adr);
+unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
+void *usbvideo_rvmalloc(unsigned long size);
+void usbvideo_rvfree(void *mem, unsigned long size);
+
+int usbvideo_register(
+ usbvideo_t **pCams,
+ const int num_cams,
+ const int num_extra,
+ const char *driverName,
+ const usbvideo_cb_t *cbTable,
+ struct module *md);
+uvd_t *usbvideo_AllocateDevice(usbvideo_t *cams);
+int usbvideo_RegisterVideoDevice(uvd_t *uvd);
+void usbvideo_Deregister(usbvideo_t **uvt);
+void usbvideo_Disconnect(struct usb_device *dev, void *ptr);
+void usbvideo_CameraRelease(uvd_t *uvd);
+
+void usbvideo_v4l_close(struct video_device *dev);
+int usbvideo_v4l_initialize(struct video_device *dev);
+int usbvideo_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg);
+int usbvideo_v4l_mmap(struct video_device *dev, const char *adr, unsigned long size);
+int usbvideo_v4l_open(struct video_device *dev, int flags);
+long usbvideo_v4l_read(struct video_device *dev, char *buf,
+ unsigned long count, int noblock);
+long usbvideo_v4l_write(struct video_device *dev, const char *buf,
+ unsigned long count, int noblock);
+
+int usbvideo_GetFrame(uvd_t *uvd, int frameNum);
+int usbvideo_NewFrame(uvd_t *uvd, int framenum);
+int usbvideo_StartDataPump(uvd_t *uvd);
+void usbvideo_StopDataPump(uvd_t *uvd);
+void usbvideo_DeinterlaceFrame(uvd_t *uvd, usbvideo_frame_t *frame);
+void usbvideo_SoftwareContrastAdjustment(uvd_t *uvd, usbvideo_frame_t *frame);
+
+/*
+ * This code performs bounds checking - use it when working with
+ * new formats, or else you may get oopses all over the place.
+ * If pixel falls out of bounds then it gets shoved back (as close
+ * to place of offence as possible) and is painted bright red.
+ *
+ * There are two important concepts: frame width, height and
+ * V4L canvas width, height. The former is the area requested by
+ * the application -for this very frame-. The latter is the largest
+ * possible frame that we can serve (we advertise that via V4L ioctl).
+ * The frame data is expected to be formatted as lines of length
+ * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines.
+ */
+static inline void RGB24_PUTPIXEL(
+ usbvideo_frame_t *fr,
+ int ix, int iy,
+ unsigned char vr,
+ unsigned char vg,
+ unsigned char vb)
+{
+ register unsigned char *pf;
+ int limiter = 0, mx, my;
+ mx = ix;
+ my = iy;
+ if (mx < 0) {
+ mx=0;
+ limiter++;
+ } else if (mx >= VIDEOSIZE_X((fr)->request)) {
+ mx= VIDEOSIZE_X((fr)->request) - 1;
+ limiter++;
+ }
+ if (my < 0) {
+ my = 0;
+ limiter++;
+ } else if (my >= VIDEOSIZE_Y((fr)->request)) {
+ my = VIDEOSIZE_Y((fr)->request) - 1;
+ limiter++;
+ }
+ pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix));
+ if (limiter) {
+ *pf++ = 0;
+ *pf++ = 0;
+ *pf++ = 0xFF;
+ } else {
+ *pf++ = (vb);
+ *pf++ = (vg);
+ *pf++ = (vr);
+ }
+}
+
+#endif /* usbvideo_h */
/* Some cards require 32bit access */
fb_writel (val, dst);
dst += 4;
+ } else if (bdepth == 2 && !((long)dst & 1)) {
+ /* others require 16bit access */
+ fb_writew (val,dst);
+ dst +=2;
} else {
#ifdef __LITTLE_ENDIAN
for( i = 0; i < bdepth; ++i )
/* Some cards require 32bit access */
fb_writel (val, dst);
dst += 4;
+ } else if (bdepth == 2 && !((long)dst & 1)) {
+ /* others require 16bit access */
+ fb_writew (val,dst);
+ dst +=2;
} else {
#ifdef __LITTLE_ENDIAN
for( i = 0; i < bdepth; ++i )
EXPORT_SYMBOL(fbcon_redraw_clear);
EXPORT_SYMBOL(fbcon_dummy);
EXPORT_SYMBOL(fb_con);
+
+MODULE_LICENSE("GPL");
--- /dev/null
+#ifndef _RADEON_H
+#define _RADEON_H
+
+
+/* radeon PCI ids */
+#define PCI_DEVICE_ID_RADEON_QD 0x5144
+#define PCI_DEVICE_ID_RADEON_QE 0x5145
+#define PCI_DEVICE_ID_RADEON_QF 0x5146
+#define PCI_DEVICE_ID_RADEON_QG 0x5147
+
+#define RADEON_REGSIZE 0x4000
+
+
+#define MM_INDEX 0x0000
+#define MM_DATA 0x0004
+#define BUS_CNTL 0x0030
+#define HI_STAT 0x004C
+#define BUS_CNTL1 0x0034
+#define I2C_CNTL_1 0x0094
+#define CONFIG_CNTL 0x00E0
+#define CONFIG_MEMSIZE 0x00F8
+#define CONFIG_APER_0_BASE 0x0100
+#define CONFIG_APER_1_BASE 0x0104
+#define CONFIG_APER_SIZE 0x0108
+#define CONFIG_REG_1_BASE 0x010C
+#define CONFIG_REG_APER_SIZE 0x0110
+#define PAD_AGPINPUT_DELAY 0x0164
+#define PAD_CTLR_STRENGTH 0x0168
+#define PAD_CTLR_UPDATE 0x016C
+#define AGP_CNTL 0x0174
+#define BM_STATUS 0x0160
+#define CAP0_TRIG_CNTL 0x0950
+#define VIPH_CONTROL 0x0C40
+#define VENDOR_ID 0x0F00
+#define DEVICE_ID 0x0F02
+#define COMMAND 0x0F04
+#define STATUS 0x0F06
+#define REVISION_ID 0x0F08
+#define REGPROG_INF 0x0F09
+#define SUB_CLASS 0x0F0A
+#define BASE_CODE 0x0F0B
+#define CACHE_LINE 0x0F0C
+#define LATENCY 0x0F0D
+#define HEADER 0x0F0E
+#define BIST 0x0F0F
+#define REG_MEM_BASE 0x0F10
+#define REG_IO_BASE 0x0F14
+#define REG_REG_BASE 0x0F18
+#define ADAPTER_ID 0x0F2C
+#define BIOS_ROM 0x0F30
+#define CAPABILITIES_PTR 0x0F34
+#define INTERRUPT_LINE 0x0F3C
+#define INTERRUPT_PIN 0x0F3D
+#define MIN_GRANT 0x0F3E
+#define MAX_LATENCY 0x0F3F
+#define ADAPTER_ID_W 0x0F4C
+#define PMI_CAP_ID 0x0F50
+#define PMI_NXT_CAP_PTR 0x0F51
+#define PMI_PMC_REG 0x0F52
+#define PM_STATUS 0x0F54
+#define PMI_DATA 0x0F57
+#define AGP_CAP_ID 0x0F58
+#define AGP_STATUS 0x0F5C
+#define AGP_COMMAND 0x0F60
+#define AIC_CTRL 0x01D0
+#define AIC_STAT 0x01D4
+#define AIC_PT_BASE 0x01D8
+#define AIC_LO_ADDR 0x01DC
+#define AIC_HI_ADDR 0x01E0
+#define AIC_TLB_ADDR 0x01E4
+#define AIC_TLB_DATA 0x01E8
+#define DAC_CNTL 0x0058
+#define CRTC_GEN_CNTL 0x0050
+#define MEM_CNTL 0x0140
+#define EXT_MEM_CNTL 0x0144
+#define MC_AGP_LOCATION 0x014C
+#define MEM_IO_CNTL_A0 0x0178
+#define MEM_INIT_LATENCY_TIMER 0x0154
+#define MEM_SDRAM_MODE_REG 0x0158
+#define AGP_BASE 0x0170
+#define MEM_IO_CNTL_A1 0x017C
+#define MEM_IO_CNTL_B0 0x0180
+#define MEM_IO_CNTL_B1 0x0184
+#define MC_DEBUG 0x0188
+#define MC_STATUS 0x0150
+#define MEM_IO_OE_CNTL 0x018C
+#define MC_FB_LOCATION 0x0148
+#define HOST_PATH_CNTL 0x0130
+#define MEM_VGA_WP_SEL 0x0038
+#define MEM_VGA_RP_SEL 0x003C
+#define HDP_DEBUG 0x0138
+#define SW_SEMAPHORE 0x013C
+#define SURFACE_CNTL 0x0B00
+#define SURFACE0_LOWER_BOUND 0x0B04
+#define SURFACE1_LOWER_BOUND 0x0B14
+#define SURFACE2_LOWER_BOUND 0x0B24
+#define SURFACE3_LOWER_BOUND 0x0B34
+#define SURFACE4_LOWER_BOUND 0x0B44
+#define SURFACE5_LOWER_BOUND 0x0B54
+#define SURFACE6_LOWER_BOUND 0x0B64
+#define SURFACE7_LOWER_BOUND 0x0B74
+#define SURFACE0_UPPER_BOUND 0x0B08
+#define SURFACE1_UPPER_BOUND 0x0B18
+#define SURFACE2_UPPER_BOUND 0x0B28
+#define SURFACE3_UPPER_BOUND 0x0B38
+#define SURFACE4_UPPER_BOUND 0x0B48
+#define SURFACE5_UPPER_BOUND 0x0B58
+#define SURFACE6_UPPER_BOUND 0x0B68
+#define SURFACE7_UPPER_BOUND 0x0B78
+#define SURFACE0_INFO 0x0B0C
+#define SURFACE1_INFO 0x0B1C
+#define SURFACE2_INFO 0x0B2C
+#define SURFACE3_INFO 0x0B3C
+#define SURFACE4_INFO 0x0B4C
+#define SURFACE5_INFO 0x0B5C
+#define SURFACE6_INFO 0x0B6C
+#define SURFACE7_INFO 0x0B7C
+#define SURFACE_ACCESS_FLAGS 0x0BF8
+#define SURFACE_ACCESS_CLR 0x0BFC
+#define GEN_INT_CNTL 0x0040
+#define GEN_INT_STATUS 0x0044
+#define CRTC_EXT_CNTL 0x0054
+#define RB3D_CNTL 0x1C3C
+#define WAIT_UNTIL 0x1720
+#define ISYNC_CNTL 0x1724
+#define RBBM_GUICNTL 0x172C
+#define RBBM_STATUS 0x0E40
+#define RBBM_STATUS_alt_1 0x1740
+#define RBBM_CNTL 0x00EC
+#define RBBM_CNTL_alt_1 0x0E44
+#define RBBM_SOFT_RESET 0x00F0
+#define RBBM_SOFT_RESET_alt_1 0x0E48
+#define NQWAIT_UNTIL 0x0E50
+#define RBBM_DEBUG 0x0E6C
+#define RBBM_CMDFIFO_ADDR 0x0E70
+#define RBBM_CMDFIFO_DATAL 0x0E74
+#define RBBM_CMDFIFO_DATAH 0x0E78
+#define RBBM_CMDFIFO_STAT 0x0E7C
+#define CRTC_STATUS 0x005C
+#define GPIO_VGA_DDC 0x0060
+#define GPIO_DVI_DDC 0x0064
+#define GPIO_MONID 0x0068
+#define PALETTE_INDEX 0x00B0
+#define PALETTE_DATA 0x00B4
+#define PALETTE_30_DATA 0x00B8
+#define CRTC_H_TOTAL_DISP 0x0200
+#define CRTC_H_SYNC_STRT_WID 0x0204
+#define CRTC_V_TOTAL_DISP 0x0208
+#define CRTC_V_SYNC_STRT_WID 0x020C
+#define CRTC_VLINE_CRNT_VLINE 0x0210
+#define CRTC_CRNT_FRAME 0x0214
+#define CRTC_GUI_TRIG_VLINE 0x0218
+#define CRTC_DEBUG 0x021C
+#define CRTC_OFFSET_RIGHT 0x0220
+#define CRTC_OFFSET 0x0224
+#define CRTC_OFFSET_CNTL 0x0228
+#define CRTC_PITCH 0x022C
+#define OVR_CLR 0x0230
+#define OVR_WID_LEFT_RIGHT 0x0234
+#define OVR_WID_TOP_BOTTOM 0x0238
+#define DISPLAY_BASE_ADDR 0x023C
+#define SNAPSHOT_VH_COUNTS 0x0240
+#define SNAPSHOT_F_COUNT 0x0244
+#define N_VIF_COUNT 0x0248
+#define SNAPSHOT_VIF_COUNT 0x024C
+#define FP_CRTC_H_TOTAL_DISP 0x0250
+#define FP_CRTC_V_TOTAL_DISP 0x0254
+#define CRT_CRTC_H_SYNC_STRT_WID 0x0258
+#define CRT_CRTC_V_SYNC_STRT_WID 0x025C
+#define CUR_OFFSET 0x0260
+#define CUR_HORZ_VERT_POSN 0x0264
+#define CUR_HORZ_VERT_OFF 0x0268
+#define CUR_CLR0 0x026C
+#define CUR_CLR1 0x0270
+#define FP_HORZ_VERT_ACTIVE 0x0278
+#define CRTC_MORE_CNTL 0x027C
+#define DAC_EXT_CNTL 0x0280
+#define FP_GEN_CNTL 0x0284
+#define FP_HORZ_STRETCH 0x028C
+#define FP_VERT_STRETCH 0x0290
+#define FP_H_SYNC_STRT_WID 0x02C4
+#define FP_V_SYNC_STRT_WID 0x02C8
+#define AUX_WINDOW_HORZ_CNTL 0x02D8
+#define AUX_WINDOW_VERT_CNTL 0x02DC
+#define DDA_CONFIG 0x02e0
+#define DDA_ON_OFF 0x02e4
+#define GRPH_BUFFER_CNTL 0x02F0
+#define VGA_BUFFER_CNTL 0x02F4
+#define OV0_Y_X_START 0x0400
+#define OV0_Y_X_END 0x0404
+#define OV0_PIPELINE_CNTL 0x0408
+#define OV0_REG_LOAD_CNTL 0x0410
+#define OV0_SCALE_CNTL 0x0420
+#define OV0_V_INC 0x0424
+#define OV0_P1_V_ACCUM_INIT 0x0428
+#define OV0_P23_V_ACCUM_INIT 0x042C
+#define OV0_P1_BLANK_LINES_AT_TOP 0x0430
+#define OV0_P23_BLANK_LINES_AT_TOP 0x0434
+#define OV0_BASE_ADDR 0x043C
+#define OV0_VID_BUF0_BASE_ADRS 0x0440
+#define OV0_VID_BUF1_BASE_ADRS 0x0444
+#define OV0_VID_BUF2_BASE_ADRS 0x0448
+#define OV0_VID_BUF3_BASE_ADRS 0x044C
+#define OV0_VID_BUF4_BASE_ADRS 0x0450
+#define OV0_VID_BUF5_BASE_ADRS 0x0454
+#define OV0_VID_BUF_PITCH0_VALUE 0x0460
+#define OV0_VID_BUF_PITCH1_VALUE 0x0464
+#define OV0_AUTO_FLIP_CNTRL 0x0470
+#define OV0_DEINTERLACE_PATTERN 0x0474
+#define OV0_SUBMIT_HISTORY 0x0478
+#define OV0_H_INC 0x0480
+#define OV0_STEP_BY 0x0484
+#define OV0_P1_H_ACCUM_INIT 0x0488
+#define OV0_P23_H_ACCUM_INIT 0x048C
+#define OV0_P1_X_START_END 0x0494
+#define OV0_P2_X_START_END 0x0498
+#define OV0_P3_X_START_END 0x049C
+#define OV0_FILTER_CNTL 0x04A0
+#define OV0_FOUR_TAP_COEF_0 0x04B0
+#define OV0_FOUR_TAP_COEF_1 0x04B4
+#define OV0_FOUR_TAP_COEF_2 0x04B8
+#define OV0_FOUR_TAP_COEF_3 0x04BC
+#define OV0_FOUR_TAP_COEF_4 0x04C0
+#define OV0_FLAG_CNTRL 0x04DC
+#define OV0_SLICE_CNTL 0x04E0
+#define OV0_VID_KEY_CLR_LOW 0x04E4
+#define OV0_VID_KEY_CLR_HIGH 0x04E8
+#define OV0_GRPH_KEY_CLR_LOW 0x04EC
+#define OV0_GRPH_KEY_CLR_HIGH 0x04F0
+#define OV0_KEY_CNTL 0x04F4
+#define OV0_TEST 0x04F8
+#define SUBPIC_CNTL 0x0540
+#define SUBPIC_DEFCOLCON 0x0544
+#define SUBPIC_Y_X_START 0x054C
+#define SUBPIC_Y_X_END 0x0550
+#define SUBPIC_V_INC 0x0554
+#define SUBPIC_H_INC 0x0558
+#define SUBPIC_BUF0_OFFSET 0x055C
+#define SUBPIC_BUF1_OFFSET 0x0560
+#define SUBPIC_LC0_OFFSET 0x0564
+#define SUBPIC_LC1_OFFSET 0x0568
+#define SUBPIC_PITCH 0x056C
+#define SUBPIC_BTN_HLI_COLCON 0x0570
+#define SUBPIC_BTN_HLI_Y_X_START 0x0574
+#define SUBPIC_BTN_HLI_Y_X_END 0x0578
+#define SUBPIC_PALETTE_INDEX 0x057C
+#define SUBPIC_PALETTE_DATA 0x0580
+#define SUBPIC_H_ACCUM_INIT 0x0584
+#define SUBPIC_V_ACCUM_INIT 0x0588
+#define DISP_MISC_CNTL 0x0D00
+#define DAC_MACRO_CNTL 0x0D04
+#define DISP_PWR_MAN 0x0D08
+#define DISP_TEST_DEBUG_CNTL 0x0D10
+#define DISP_HW_DEBUG 0x0D14
+#define DAC_CRC_SIG1 0x0D18
+#define DAC_CRC_SIG2 0x0D1C
+#define OV0_LIN_TRANS_A 0x0D20
+#define OV0_LIN_TRANS_B 0x0D24
+#define OV0_LIN_TRANS_C 0x0D28
+#define OV0_LIN_TRANS_D 0x0D2C
+#define OV0_LIN_TRANS_E 0x0D30
+#define OV0_LIN_TRANS_F 0x0D34
+#define OV0_GAMMA_0_F 0x0D40
+#define OV0_GAMMA_10_1F 0x0D44
+#define OV0_GAMMA_20_3F 0x0D48
+#define OV0_GAMMA_40_7F 0x0D4C
+#define OV0_GAMMA_380_3BF 0x0D50
+#define OV0_GAMMA_3C0_3FF 0x0D54
+#define DISP_MERGE_CNTL 0x0D60
+#define DISP_OUTPUT_CNTL 0x0D64
+#define DISP_LIN_TRANS_GRPH_A 0x0D80
+#define DISP_LIN_TRANS_GRPH_B 0x0D84
+#define DISP_LIN_TRANS_GRPH_C 0x0D88
+#define DISP_LIN_TRANS_GRPH_D 0x0D8C
+#define DISP_LIN_TRANS_GRPH_E 0x0D90
+#define DISP_LIN_TRANS_GRPH_F 0x0D94
+#define DISP_LIN_TRANS_VID_A 0x0D98
+#define DISP_LIN_TRANS_VID_B 0x0D9C
+#define DISP_LIN_TRANS_VID_C 0x0DA0
+#define DISP_LIN_TRANS_VID_D 0x0DA4
+#define DISP_LIN_TRANS_VID_E 0x0DA8
+#define DISP_LIN_TRANS_VID_F 0x0DAC
+#define RMX_HORZ_FILTER_0TAP_COEF 0x0DB0
+#define RMX_HORZ_FILTER_1TAP_COEF 0x0DB4
+#define RMX_HORZ_FILTER_2TAP_COEF 0x0DB8
+#define RMX_HORZ_PHASE 0x0DBC
+#define DAC_EMBEDDED_SYNC_CNTL 0x0DC0
+#define DAC_BROAD_PULSE 0x0DC4
+#define DAC_SKEW_CLKS 0x0DC8
+#define DAC_INCR 0x0DCC
+#define DAC_NEG_SYNC_LEVEL 0x0DD0
+#define DAC_POS_SYNC_LEVEL 0x0DD4
+#define DAC_BLANK_LEVEL 0x0DD8
+#define CLOCK_CNTL_INDEX 0x0008
+#define CLOCK_CNTL_DATA 0x000C
+#define CP_RB_CNTL 0x0704
+#define CP_RB_BASE 0x0700
+#define CP_RB_RPTR_ADDR 0x070C
+#define CP_RB_RPTR 0x0710
+#define CP_RB_WPTR 0x0714
+#define CP_RB_WPTR_DELAY 0x0718
+#define CP_IB_BASE 0x0738
+#define CP_IB_BUFSZ 0x073C
+#define SCRATCH_REG0 0x15E0
+#define GUI_SCRATCH_REG0 0x15E0
+#define SCRATCH_REG1 0x15E4
+#define GUI_SCRATCH_REG1 0x15E4
+#define SCRATCH_REG2 0x15E8
+#define GUI_SCRATCH_REG2 0x15E8
+#define SCRATCH_REG3 0x15EC
+#define GUI_SCRATCH_REG3 0x15EC
+#define SCRATCH_REG4 0x15F0
+#define GUI_SCRATCH_REG4 0x15F0
+#define SCRATCH_REG5 0x15F4
+#define GUI_SCRATCH_REG5 0x15F4
+#define SCRATCH_UMSK 0x0770
+#define SCRATCH_ADDR 0x0774
+#define DP_BRUSH_FRGD_CLR 0x147C
+#define DP_BRUSH_BKGD_CLR 0x1478
+#define DST_LINE_START 0x1600
+#define DST_LINE_END 0x1604
+#define SRC_OFFSET 0x15AC
+#define SRC_PITCH 0x15B0
+#define SRC_TILE 0x1704
+#define SRC_PITCH_OFFSET 0x1428
+#define SRC_X 0x1414
+#define SRC_Y 0x1418
+#define SRC_X_Y 0x1590
+#define SRC_Y_X 0x1434
+#define DST_Y_X 0x1438
+#define DST_WIDTH_HEIGHT 0x1598
+#define DST_HEIGHT_WIDTH 0x143c
+#define SRC_CLUT_ADDRESS 0x1780
+#define SRC_CLUT_DATA 0x1784
+#define SRC_CLUT_DATA_RD 0x1788
+#define HOST_DATA0 0x17C0
+#define HOST_DATA1 0x17C4
+#define HOST_DATA2 0x17C8
+#define HOST_DATA3 0x17CC
+#define HOST_DATA4 0x17D0
+#define HOST_DATA5 0x17D4
+#define HOST_DATA6 0x17D8
+#define HOST_DATA7 0x17DC
+#define HOST_DATA_LAST 0x17E0
+#define DP_SRC_ENDIAN 0x15D4
+#define DP_SRC_FRGD_CLR 0x15D8
+#define DP_SRC_BKGD_CLR 0x15DC
+#define SC_LEFT 0x1640
+#define SC_RIGHT 0x1644
+#define SC_TOP 0x1648
+#define SC_BOTTOM 0x164C
+#define SRC_SC_RIGHT 0x1654
+#define SRC_SC_BOTTOM 0x165C
+#define DP_CNTL 0x16C0
+#define DP_CNTL_XDIR_YDIR_YMAJOR 0x16D0
+#define DP_DATATYPE 0x16C4
+#define DP_MIX 0x16C8
+#define DP_WRITE_MSK 0x16CC
+#define DP_XOP 0x17F8
+#define CLR_CMP_CLR_SRC 0x15C4
+#define CLR_CMP_CLR_DST 0x15C8
+#define CLR_CMP_CNTL 0x15C0
+#define CLR_CMP_MSK 0x15CC
+#define DSTCACHE_MODE 0x1710
+#define DSTCACHE_CTLSTAT 0x1714
+#define DEFAULT_PITCH_OFFSET 0x16E0
+#define DEFAULT_SC_BOTTOM_RIGHT 0x16E8
+#define DP_GUI_MASTER_CNTL 0x146C
+#define SC_TOP_LEFT 0x16EC
+#define SC_BOTTOM_RIGHT 0x16F0
+#define SRC_SC_BOTTOM_RIGHT 0x16F4
+#define RB2D_DSTCACHE_CTLSTAT 0x342C
+
+
+#define CLK_PIN_CNTL 0x0001
+#define PPLL_CNTL 0x0002
+#define PPLL_REF_DIV 0x0003
+#define PPLL_DIV_0 0x0004
+#define PPLL_DIV_1 0x0005
+#define PPLL_DIV_2 0x0006
+#define PPLL_DIV_3 0x0007
+#define VCLK_ECP_CNTL 0x0008
+#define HTOTAL_CNTL 0x0009
+#define M_SPLL_REF_FB_DIV 0x000a
+#define AGP_PLL_CNTL 0x000b
+#define SPLL_CNTL 0x000c
+#define SCLK_CNTL 0x000d
+#define MPLL_CNTL 0x000e
+#define MCLK_CNTL 0x0012
+#define AGP_PLL_CNTL 0x000b
+#define PLL_TEST_CNTL 0x0013
+
+
+/* MCLK_CNTL bit constants */
+#define FORCEON_MCLKA (1 << 16)
+#define FORCEON_MCLKB (1 << 17)
+#define FORCEON_YCLKA (1 << 18)
+#define FORCEON_YCLKB (1 << 19)
+#define FORCEON_MC (1 << 20)
+#define FORCEON_AIC (1 << 21)
+
+
+/* BUS_CNTL bit constants */
+#define BUS_DBL_RESYNC 0x00000001
+#define BUS_MSTR_RESET 0x00000002
+#define BUS_FLUSH_BUF 0x00000004
+#define BUS_STOP_REQ_DIS 0x00000008
+#define BUS_ROTATION_DIS 0x00000010
+#define BUS_MASTER_DIS 0x00000040
+#define BUS_ROM_WRT_EN 0x00000080
+#define BUS_DIS_ROM 0x00001000
+#define BUS_PCI_READ_RETRY_EN 0x00002000
+#define BUS_AGP_AD_STEPPING_EN 0x00004000
+#define BUS_PCI_WRT_RETRY_EN 0x00008000
+#define BUS_MSTR_RD_MULT 0x00100000
+#define BUS_MSTR_RD_LINE 0x00200000
+#define BUS_SUSPEND 0x00400000
+#define LAT_16X 0x00800000
+#define BUS_RD_DISCARD_EN 0x01000000
+#define BUS_RD_ABORT_EN 0x02000000
+#define BUS_MSTR_WS 0x04000000
+#define BUS_PARKING_DIS 0x08000000
+#define BUS_MSTR_DISCONNECT_EN 0x10000000
+#define BUS_WRT_BURST 0x20000000
+#define BUS_READ_BURST 0x40000000
+#define BUS_RDY_READ_DLY 0x80000000
+
+
+/* CLOCK_CNTL_INDEX bit constants */
+#define PLL_WR_EN 0x00000080
+
+/* CONFIG_CNTL bit constants */
+#define CFG_VGA_RAM_EN 0x00000100
+
+/* CRTC_EXT_CNTL bit constants */
+#define VGA_ATI_LINEAR 0x00000008
+#define VGA_128KAP_PAGING 0x00000010
+#define XCRT_CNT_EN (1 << 6)
+#define CRTC_HSYNC_DIS (1 << 8)
+#define CRTC_VSYNC_DIS (1 << 9)
+#define CRTC_DISPLAY_DIS (1 << 10)
+
+
+/* DSTCACHE_CTLSTAT bit constants */
+#define RB2D_DC_FLUSH (3 << 0)
+#define RB2D_DC_FLUSH_ALL 0xf
+#define RB2D_DC_BUSY (1 << 31)
+
+
+/* CRTC_GEN_CNTL bit constants */
+#define CRTC_DBL_SCAN_EN 0x00000001
+#define CRTC_CUR_EN 0x00010000
+#define CRTC_EXT_DISP_EN (1 << 24)
+#define CRTC_EN (1 << 25)
+
+/* CRTC_STATUS bit constants */
+#define CRTC_VBLANK 0x00000001
+
+/* CUR_OFFSET, CUR_HORZ_VERT_POSN, CUR_HORZ_VERT_OFF bit constants */
+#define CUR_LOCK 0x80000000
+
+/* DAC_CNTL bit constants */
+#define DAC_8BIT_EN 0x00000100
+#define DAC_4BPP_PIX_ORDER 0x00000200
+#define DAC_CRC_EN 0x00080000
+#define DAC_MASK_ALL (0xff << 24)
+#define DAC_VGA_ADR_EN (1 << 13)
+#define DAC_RANGE_CNTL (3 << 0)
+#define DAC_BLANKING (1 << 2)
+
+/* GEN_RESET_CNTL bit constants */
+#define SOFT_RESET_GUI 0x00000001
+#define SOFT_RESET_VCLK 0x00000100
+#define SOFT_RESET_PCLK 0x00000200
+#define SOFT_RESET_ECP 0x00000400
+#define SOFT_RESET_DISPENG_XCLK 0x00000800
+
+/* MEM_CNTL bit constants */
+#define MEM_CTLR_STATUS_IDLE 0x00000000
+#define MEM_CTLR_STATUS_BUSY 0x00100000
+#define MEM_SEQNCR_STATUS_IDLE 0x00000000
+#define MEM_SEQNCR_STATUS_BUSY 0x00200000
+#define MEM_ARBITER_STATUS_IDLE 0x00000000
+#define MEM_ARBITER_STATUS_BUSY 0x00400000
+#define MEM_REQ_UNLOCK 0x00000000
+#define MEM_REQ_LOCK 0x00800000
+
+
+/* RBBM_SOFT_RESET bit constants */
+#define SOFT_RESET_CP (1 << 0)
+#define SOFT_RESET_HI (1 << 1)
+#define SOFT_RESET_SE (1 << 2)
+#define SOFT_RESET_RE (1 << 3)
+#define SOFT_RESET_PP (1 << 4)
+#define SOFT_RESET_E2 (1 << 5)
+#define SOFT_RESET_RB (1 << 6)
+#define SOFT_RESET_HDP (1 << 7)
+
+
+/* DEFAULT_SC_BOTTOM_RIGHT bit constants */
+#define DEFAULT_SC_RIGHT_MAX (0x1fff << 0)
+#define DEFAULT_SC_BOTTOM_MAX (0x1fff << 16)
+
+/* MM_INDEX bit constants */
+#define MM_APER 0x80000000
+
+/* CLR_CMP_CNTL bit constants */
+#define COMPARE_SRC_FALSE 0x00000000
+#define COMPARE_SRC_TRUE 0x00000001
+#define COMPARE_SRC_NOT_EQUAL 0x00000004
+#define COMPARE_SRC_EQUAL 0x00000005
+#define COMPARE_SRC_EQUAL_FLIP 0x00000007
+#define COMPARE_DST_FALSE 0x00000000
+#define COMPARE_DST_TRUE 0x00000100
+#define COMPARE_DST_NOT_EQUAL 0x00000400
+#define COMPARE_DST_EQUAL 0x00000500
+#define COMPARE_DESTINATION 0x00000000
+#define COMPARE_SOURCE 0x01000000
+#define COMPARE_SRC_AND_DST 0x02000000
+
+
+/* DP_CNTL bit constants */
+#define DST_X_RIGHT_TO_LEFT 0x00000000
+#define DST_X_LEFT_TO_RIGHT 0x00000001
+#define DST_Y_BOTTOM_TO_TOP 0x00000000
+#define DST_Y_TOP_TO_BOTTOM 0x00000002
+#define DST_X_MAJOR 0x00000000
+#define DST_Y_MAJOR 0x00000004
+#define DST_X_TILE 0x00000008
+#define DST_Y_TILE 0x00000010
+#define DST_LAST_PEL 0x00000020
+#define DST_TRAIL_X_RIGHT_TO_LEFT 0x00000000
+#define DST_TRAIL_X_LEFT_TO_RIGHT 0x00000040
+#define DST_TRAP_FILL_RIGHT_TO_LEFT 0x00000000
+#define DST_TRAP_FILL_LEFT_TO_RIGHT 0x00000080
+#define DST_BRES_SIGN 0x00000100
+#define DST_HOST_BIG_ENDIAN_EN 0x00000200
+#define DST_POLYLINE_NONLAST 0x00008000
+#define DST_RASTER_STALL 0x00010000
+#define DST_POLY_EDGE 0x00040000
+
+
+/* DP_CNTL_YDIR_XDIR_YMAJOR bit constants (short version of DP_CNTL) */
+#define DST_X_MAJOR_S 0x00000000
+#define DST_Y_MAJOR_S 0x00000001
+#define DST_Y_BOTTOM_TO_TOP_S 0x00000000
+#define DST_Y_TOP_TO_BOTTOM_S 0x00008000
+#define DST_X_RIGHT_TO_LEFT_S 0x00000000
+#define DST_X_LEFT_TO_RIGHT_S 0x80000000
+
+
+/* DP_DATATYPE bit constants */
+#define DST_8BPP 0x00000002
+#define DST_15BPP 0x00000003
+#define DST_16BPP 0x00000004
+#define DST_24BPP 0x00000005
+#define DST_32BPP 0x00000006
+#define DST_8BPP_RGB332 0x00000007
+#define DST_8BPP_Y8 0x00000008
+#define DST_8BPP_RGB8 0x00000009
+#define DST_16BPP_VYUY422 0x0000000b
+#define DST_16BPP_YVYU422 0x0000000c
+#define DST_32BPP_AYUV444 0x0000000e
+#define DST_16BPP_ARGB4444 0x0000000f
+#define BRUSH_SOLIDCOLOR 0x00000d00
+#define SRC_MONO 0x00000000
+#define SRC_MONO_LBKGD 0x00010000
+#define SRC_DSTCOLOR 0x00030000
+#define BYTE_ORDER_MSB_TO_LSB 0x00000000
+#define BYTE_ORDER_LSB_TO_MSB 0x40000000
+#define DP_CONVERSION_TEMP 0x80000000
+#define HOST_BIG_ENDIAN_EN (1 << 29)
+
+
+/* DP_GUI_MASTER_CNTL bit constants */
+#define GMC_SRC_PITCH_OFFSET_DEFAULT 0x00000000
+#define GMC_SRC_PITCH_OFFSET_LEAVE 0x00000001
+#define GMC_DST_PITCH_OFFSET_DEFAULT 0x00000000
+#define GMC_DST_PITCH_OFFSET_LEAVE 0x00000002
+#define GMC_SRC_CLIP_DEFAULT 0x00000000
+#define GMC_SRC_CLIP_LEAVE 0x00000004
+#define GMC_DST_CLIP_DEFAULT 0x00000000
+#define GMC_DST_CLIP_LEAVE 0x00000008
+#define GMC_BRUSH_8x8MONO 0x00000000
+#define GMC_BRUSH_8x8MONO_LBKGD 0x00000010
+#define GMC_BRUSH_8x1MONO 0x00000020
+#define GMC_BRUSH_8x1MONO_LBKGD 0x00000030
+#define GMC_BRUSH_1x8MONO 0x00000040
+#define GMC_BRUSH_1x8MONO_LBKGD 0x00000050
+#define GMC_BRUSH_32x1MONO 0x00000060
+#define GMC_BRUSH_32x1MONO_LBKGD 0x00000070
+#define GMC_BRUSH_32x32MONO 0x00000080
+#define GMC_BRUSH_32x32MONO_LBKGD 0x00000090
+#define GMC_BRUSH_8x8COLOR 0x000000a0
+#define GMC_BRUSH_8x1COLOR 0x000000b0
+#define GMC_BRUSH_1x8COLOR 0x000000c0
+#define GMC_BRUSH_SOLID_COLOR 0x000000d0
+#define GMC_DST_8BPP 0x00000200
+#define GMC_DST_15BPP 0x00000300
+#define GMC_DST_16BPP 0x00000400
+#define GMC_DST_24BPP 0x00000500
+#define GMC_DST_32BPP 0x00000600
+#define GMC_DST_8BPP_RGB332 0x00000700
+#define GMC_DST_8BPP_Y8 0x00000800
+#define GMC_DST_8BPP_RGB8 0x00000900
+#define GMC_DST_16BPP_VYUY422 0x00000b00
+#define GMC_DST_16BPP_YVYU422 0x00000c00
+#define GMC_DST_32BPP_AYUV444 0x00000e00
+#define GMC_DST_16BPP_ARGB4444 0x00000f00
+#define GMC_SRC_MONO 0x00000000
+#define GMC_SRC_MONO_LBKGD 0x00001000
+#define GMC_SRC_DSTCOLOR 0x00003000
+#define GMC_BYTE_ORDER_MSB_TO_LSB 0x00000000
+#define GMC_BYTE_ORDER_LSB_TO_MSB 0x00004000
+#define GMC_DP_CONVERSION_TEMP_9300 0x00008000
+#define GMC_DP_CONVERSION_TEMP_6500 0x00000000
+#define GMC_DP_SRC_RECT 0x02000000
+#define GMC_DP_SRC_HOST 0x03000000
+#define GMC_DP_SRC_HOST_BYTEALIGN 0x04000000
+#define GMC_3D_FCN_EN_CLR 0x00000000
+#define GMC_3D_FCN_EN_SET 0x08000000
+#define GMC_DST_CLR_CMP_FCN_LEAVE 0x00000000
+#define GMC_DST_CLR_CMP_FCN_CLEAR 0x10000000
+#define GMC_AUX_CLIP_LEAVE 0x00000000
+#define GMC_AUX_CLIP_CLEAR 0x20000000
+#define GMC_WRITE_MASK_LEAVE 0x00000000
+#define GMC_WRITE_MASK_SET 0x40000000
+#define GMC_CLR_CMP_CNTL_DIS (1 << 28)
+#define GMC_SRC_DATATYPE_COLOR (3 << 12)
+#define ROP3_S 0x00cc0000
+#define ROP3_SRCCOPY 0x00cc0000
+#define ROP3_P 0x00f00000
+#define ROP3_PATCOPY 0x00f00000
+#define DP_SRC_SOURCE_MASK (7 << 24)
+#define GMC_BRUSH_NONE (15 << 4)
+#define DP_SRC_SOURCE_MEMORY (2 << 24)
+#define GMC_BRUSH_SOLIDCOLOR 0x000000d0
+
+/* DP_MIX bit constants */
+#define DP_SRC_RECT 0x00000200
+#define DP_SRC_HOST 0x00000300
+#define DP_SRC_HOST_BYTEALIGN 0x00000400
+
+
+/* masks */
+
+#define CONFIG_MEMSIZE_MASK 0x1f000000
+#define MEM_CFG_TYPE 0x40000000
+#define DST_OFFSET_MASK 0x003fffff
+#define DST_PITCH_MASK 0x3fc00000
+#define DEFAULT_TILE_MASK 0xc0000000
+#define PPLL_DIV_SEL_MASK 0x00000300
+#define PPLL_RESET 0x00000001
+#define PPLL_ATOMIC_UPDATE_EN 0x00010000
+#define PPLL_REF_DIV_MASK 0x000003ff
+#define PPLL_FB3_DIV_MASK 0x000007ff
+#define PPLL_POST3_DIV_MASK 0x00070000
+#define PPLL_ATOMIC_UPDATE_R 0x00008000
+#define PPLL_ATOMIC_UPDATE_W 0x00008000
+#define PPLL_VGA_ATOMIC_UPDATE_EN 0x00020000
+
+#define GUI_ACTIVE 0x80000000
+
+#endif /* _RADEON_H */
+
--- /dev/null
+/*
+ * drivers/video/radeonfb.c
+ * framebuffer driver for ATI Radeon chipset video boards
+ *
+ * Copyright 2000 Ani Joshi <ajoshi@unixbox.com>
+ *
+ *
+ * ChangeLog:
+ * 2000-08-03 initial version 0.0.1
+ * 2000-09-10 more bug fixes, public release 0.0.5
+ * 2001-02-19 mode bug fixes, 0.0.7
+ * 2001-07-05 fixed scrolling issues, engine initialization,
+ * and minor mode tweaking, 0.0.9
+ *
+ *
+ * Special thanks to ATI DevRel team for their hardware donations.
+ *
+ */
+
+
+#define RADEON_VERSION "0.0.9"
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#include <asm/io.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb8.h>
+#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb24.h>
+#include <video/fbcon-cfb32.h>
+
+#include "radeon.h"
+
+
+#define DEBUG 0
+
+#if DEBUG
+#define RTRACE printk
+#else
+#define RTRACE if(0) printk
+#endif
+
+
+
+enum radeon_chips {
+ RADEON_QD,
+ RADEON_QE,
+ RADEON_QF,
+ RADEON_QG
+};
+
+
+static struct pci_device_id radeonfb_pci_table[] __devinitdata = {
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QD},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QE},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QF},
+ { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_QG},
+ { 0, }
+};
+MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
+
+
+typedef struct {
+ u16 reg;
+ u32 val;
+} reg_val;
+
+
+/* these common regs are cleared before mode setting so they do not
+ * interfere with anything
+ */
+reg_val common_regs[] = {
+ { OVR_CLR, 0 },
+ { OVR_WID_LEFT_RIGHT, 0 },
+ { OVR_WID_TOP_BOTTOM, 0 },
+ { OV0_SCALE_CNTL, 0 },
+ { SUBPIC_CNTL, 0 },
+ { VIPH_CONTROL, 0 },
+ { I2C_CNTL_1, 0 },
+ { GEN_INT_CNTL, 0 },
+ { CAP0_TRIG_CNTL, 0 },
+};
+
+#define COMMON_REGS_SIZE = (sizeof(common_regs)/sizeof(common_regs[0]))
+
+typedef struct {
+ u8 clock_chip_type;
+ u8 struct_size;
+ u8 accelerator_entry;
+ u8 VGA_entry;
+ u16 VGA_table_offset;
+ u16 POST_table_offset;
+ u16 XCLK;
+ u16 MCLK;
+ u8 num_PLL_blocks;
+ u8 size_PLL_blocks;
+ u16 PCLK_ref_freq;
+ u16 PCLK_ref_divider;
+ u32 PCLK_min_freq;
+ u32 PCLK_max_freq;
+ u16 MCLK_ref_freq;
+ u16 MCLK_ref_divider;
+ u32 MCLK_min_freq;
+ u32 MCLK_max_freq;
+ u16 XCLK_ref_freq;
+ u16 XCLK_ref_divider;
+ u32 XCLK_min_freq;
+ u32 XCLK_max_freq;
+} __attribute__ ((packed)) PLL_BLOCK;
+
+
+struct pll_info {
+ int ppll_max;
+ int ppll_min;
+ int xclk;
+ int ref_div;
+ int ref_clk;
+};
+
+
+struct ram_info {
+ int ml;
+ int mb;
+ int trcd;
+ int trp;
+ int twr;
+ int cl;
+ int tr2w;
+ int loop_latency;
+ int rloop;
+};
+
+
+struct radeon_regs {
+ u32 crtc_h_total_disp;
+ u32 crtc_h_sync_strt_wid;
+ u32 crtc_v_total_disp;
+ u32 crtc_v_sync_strt_wid;
+ u32 crtc_pitch;
+ u32 flags;
+ u32 pix_clock;
+ int xres, yres;
+ int bpp;
+ u32 crtc_gen_cntl;
+ u32 crtc_ext_cntl;
+ u32 dac_cntl;
+ u32 dda_config;
+ u32 dda_on_off;
+ u32 ppll_div_3;
+ u32 ppll_ref_div;
+};
+
+
+struct radeonfb_info {
+ struct fb_info info;
+
+ struct radeon_regs state;
+ struct radeon_regs init_state;
+
+ char name[10];
+ char ram_type[12];
+
+ u32 mmio_base_phys;
+ u32 fb_base_phys;
+
+ u32 mmio_base;
+ u32 fb_base;
+
+ struct pci_dev *pdev;
+
+ struct display disp;
+ int currcon;
+ struct display *currcon_display;
+
+ struct { u8 red, green, blue, pad; } palette[256];
+
+ int chipset;
+ int video_ram;
+ u8 rev;
+ int pitch, bpp, depth;
+ int xres, yres, pixclock;
+
+ u32 dp_gui_master_cntl;
+
+ struct pll_info pll;
+ int pll_output_freq, post_div, fb_div;
+
+ struct ram_info ram;
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+ union {
+#if defined(FBCON_HAS_CFB16)
+ u_int16_t cfb16[16];
+#endif
+#if defined(FBCON_HAS_CFB32)
+ u_int32_t cfb32[16];
+#endif
+ } con_cmap;
+#endif
+};
+
+
+static struct fb_var_screeninfo radeonfb_default_var = {
+ 640, 480, 640, 480, 0, 0, 8, 0,
+ {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+};
+
+
+/*
+ * IO macros
+ */
+
+#define INREG8(addr) readb((rinfo->mmio_base)+addr)
+#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr)
+#define INREG(addr) readl((rinfo->mmio_base)+addr)
+#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr)
+
+#define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \
+ OUTREG(CLOCK_CNTL_DATA, val)
+#define OUTPLLP(addr,val,mask) \
+ do { \
+ unsigned int _tmp = INPLL(addr); \
+ _tmp &= (mask); \
+ _tmp |= (val); \
+ OUTPLL(addr, _tmp); \
+ } while (0)
+
+#define OUTREGP(addr,val,mask) \
+ do { \
+ unsigned int _tmp = INREG(addr); \
+ _tmp &= (mask); \
+ _tmp |= (val); \
+ OUTREG(addr, _tmp); \
+ } while (0)
+
+
+static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
+{
+ OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f);
+ return (INREG(CLOCK_CNTL_DATA));
+}
+
+#define INPLL(addr) _INPLL(rinfo, addr)
+
+
+/*
+ * 2D engine routines
+ */
+
+static __inline__ void radeon_engine_flush (struct radeonfb_info *rinfo)
+{
+ int i;
+
+ /* initiate flush */
+ OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+ ~RB2D_DC_FLUSH_ALL);
+
+ for (i=0; i < 2000000; i++) {
+ if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+ break;
+ }
+}
+
+
+static __inline__ void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
+{
+ int i;
+
+ for (i=0; i<2000000; i++)
+ if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
+ return;
+}
+
+
+static __inline__ void _radeon_engine_idle (struct radeonfb_info *rinfo)
+{
+ int i;
+
+ /* ensure FIFO is empty before waiting for idle */
+ _radeon_fifo_wait (rinfo, 64);
+
+ for (i=0; i<2000000; i++) {
+ if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
+ radeon_engine_flush (rinfo);
+ return;
+ }
+ }
+}
+
+
+#define radeon_engine_idle() _radeon_engine_idle(rinfo)
+#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries)
+
+
+
+/*
+ * helper routines
+ */
+
+static __inline__ u32 radeon_get_dstbpp(u16 depth)
+{
+ switch (depth) {
+ case 8:
+ return DST_8BPP;
+ case 15:
+ return DST_15BPP;
+ case 16:
+ return DST_16BPP;
+ case 32:
+ return DST_32BPP;
+ default:
+ return 0;
+ }
+}
+
+
+static void _radeon_engine_reset(struct radeonfb_info *rinfo)
+{
+ u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+
+ radeon_engine_flush (rinfo);
+
+ clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
+ mclk_cntl = INPLL(MCLK_CNTL);
+
+ OUTPLL(MCLK_CNTL, (mclk_cntl |
+ FORCEON_MCLKA |
+ FORCEON_MCLKB |
+ FORCEON_YCLKA |
+ FORCEON_YCLKB |
+ FORCEON_MC |
+ FORCEON_AIC));
+ rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
+
+ OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
+ SOFT_RESET_CP |
+ SOFT_RESET_HI |
+ SOFT_RESET_SE |
+ SOFT_RESET_RE |
+ SOFT_RESET_PP |
+ SOFT_RESET_E2 |
+ SOFT_RESET_RB |
+ SOFT_RESET_HDP);
+ INREG(RBBM_SOFT_RESET);
+ OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
+ ~(SOFT_RESET_CP |
+ SOFT_RESET_HI |
+ SOFT_RESET_SE |
+ SOFT_RESET_RE |
+ SOFT_RESET_PP |
+ SOFT_RESET_E2 |
+ SOFT_RESET_RB |
+ SOFT_RESET_HDP));
+ INREG(RBBM_SOFT_RESET);
+
+ OUTPLL(MCLK_CNTL, mclk_cntl);
+ OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
+ OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
+
+ return;
+}
+
+#define radeon_engine_reset() _radeon_engine_reset(rinfo)
+
+
+static __inline__ u8 radeon_get_post_div_bitval(int post_div)
+{
+ switch (post_div) {
+ case 1:
+ return 0x00;
+ case 2:
+ return 0x01;
+ case 3:
+ return 0x04;
+ case 4:
+ return 0x02;
+ case 6:
+ return 0x06;
+ case 8:
+ return 0x03;
+ case 12:
+ return 0x07;
+ default:
+ return 0x02;
+ }
+}
+
+
+
+static __inline__ int round_div(int num, int den)
+{
+ return (num + (den / 2)) / den;
+}
+
+
+
+static __inline__ int min_bits_req(int val)
+{
+ int bits_req = 0;
+
+ if (val == 0)
+ bits_req = 1;
+
+ while (val) {
+ val >>= 1;
+ bits_req++;
+ }
+
+ return (bits_req);
+}
+
+
+static __inline__ int _max(int val1, int val2)
+{
+ if (val1 >= val2)
+ return val1;
+ else
+ return val2;
+}
+
+
+
+/*
+ * globals
+ */
+
+static char fontname[40] __initdata;
+static char *mode_option __initdata;
+static char noaccel __initdata = 0;
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch fbcon_radeon8;
+#endif
+
+
+/*
+ * prototypes
+ */
+
+static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg, int con, struct fb_info *info);
+static int radeonfb_switch (int con, struct fb_info *info);
+static int radeonfb_updatevar (int con, struct fb_info *info);
+static void radeonfb_blank (int blank, struct fb_info *info);
+static int radeon_get_cmap_len (const struct fb_var_screeninfo *var);
+static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *info);
+static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info);
+static void radeon_set_dispsw (struct radeonfb_info *rinfo);
+static void radeon_save_state (struct radeonfb_info *rinfo,
+ struct radeon_regs *save);
+static void radeon_engine_init (struct radeonfb_info *rinfo);
+static void radeon_load_video_mode (struct radeonfb_info *rinfo,
+ struct fb_var_screeninfo *mode);
+static void radeon_write_mode (struct radeonfb_info *rinfo,
+ struct radeon_regs *mode);
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo);
+static int __devinit radeon_init_disp (struct radeonfb_info *rinfo);
+static int radeon_init_disp_var (struct radeonfb_info *rinfo);
+static int radeonfb_pci_register (struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev);
+static char *radeon_find_rom(struct radeonfb_info *rinfo);
+static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg);
+
+
+static struct fb_ops radeon_fb_ops = {
+ fb_get_fix: radeonfb_get_fix,
+ fb_get_var: radeonfb_get_var,
+ fb_set_var: radeonfb_set_var,
+ fb_get_cmap: radeonfb_get_cmap,
+ fb_set_cmap: radeonfb_set_cmap,
+ fb_pan_display: radeonfb_pan_display,
+ fb_ioctl: radeonfb_ioctl,
+};
+
+
+static struct pci_driver radeonfb_driver = {
+ name: "radeonfb",
+ id_table: radeonfb_pci_table,
+ probe: radeonfb_pci_register,
+ remove: radeonfb_pci_unregister,
+};
+
+
+int __init radeonfb_init (void)
+{
+ return pci_module_init (&radeonfb_driver);
+}
+
+
+void __exit radeonfb_exit (void)
+{
+ pci_unregister_driver (&radeonfb_driver);
+}
+
+
+int __init radeonfb_setup (char *options)
+{
+ char *this_opt;
+
+ if (!options || !*options)
+ return 0;
+
+ for (this_opt = strtok (options, ","); this_opt;
+ this_opt = strtok (NULL, ",")) {
+ if (!strncmp (this_opt, "font:", 5)) {
+ char *p;
+ int i;
+
+ p = this_opt + 5;
+ for (i=0; i<sizeof (fontname) - 1; i++)
+ if (!*p || *p == ' ' || *p == ',')
+ break;
+ memcpy(fontname, this_opt + 5, i);
+ } else if (!strncmp(this_opt, "noaccel", 7)) {
+ noaccel = 1;
+ }
+ else mode_option = this_opt;
+ }
+
+ return 0;
+}
+
+#ifdef MODULE
+module_init(radeonfb_init);
+module_exit(radeonfb_exit);
+#endif
+
+
+MODULE_AUTHOR("Ani Joshi");
+MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
+MODULE_LICENSE("GPL");
+
+static int radeonfb_pci_register (struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct radeonfb_info *rinfo;
+ u32 tmp;
+ int i, j;
+ char *bios_seg = NULL;
+
+ rinfo = kmalloc (sizeof (struct radeonfb_info), GFP_KERNEL);
+ if (!rinfo) {
+ printk ("radeonfb: could not allocate memory\n");
+ return -ENODEV;
+ }
+
+ memset (rinfo, 0, sizeof (struct radeonfb_info));
+
+ /* enable device */
+ {
+ int err;
+
+ if ((err = pci_enable_device(pdev))) {
+ printk("radeonfb: cannot enable device\n");
+ kfree (rinfo);
+ return -ENODEV;
+ }
+ }
+
+ /* set base addrs */
+ rinfo->fb_base_phys = pci_resource_start (pdev, 0);
+ rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+
+ /* request the mem regions */
+ if (!request_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0), "radeonfb")) {
+ printk ("radeonfb: cannot reserve FB region\n");
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ if (!request_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2), "radeonfb")) {
+ printk ("radeonfb: cannot reserve MMIO region\n");
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ /* map the regions */
+ rinfo->mmio_base = (u32) ioremap (rinfo->mmio_base_phys,
+ RADEON_REGSIZE);
+ if (!rinfo->mmio_base) {
+ printk ("radeonfb: cannot map MMIO\n");
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ /* chipset */
+ switch (pdev->device) {
+ case PCI_DEVICE_ID_RADEON_QD:
+ strcpy(rinfo->name, "Radeon QD ");
+ break;
+ case PCI_DEVICE_ID_RADEON_QE:
+ strcpy(rinfo->name, "Radeon QE ");
+ break;
+ case PCI_DEVICE_ID_RADEON_QF:
+ strcpy(rinfo->name, "Radeon QF ");
+ break;
+ case PCI_DEVICE_ID_RADEON_QG:
+ strcpy(rinfo->name, "Radeon QG ");
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ /* framebuffer size */
+ tmp = INREG(CONFIG_MEMSIZE);
+
+ /* mem size is bits [28:0], mask off the rest */
+ rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+ /* ram type */
+ tmp = INREG(MEM_SDRAM_MODE_REG);
+ switch ((MEM_CFG_TYPE & tmp) >> 30) {
+ case 0:
+ /* SDR SGRAM (2:1) */
+ strcpy(rinfo->ram_type, "SDR SGRAM");
+ rinfo->ram.ml = 4;
+ rinfo->ram.mb = 4;
+ rinfo->ram.trcd = 1;
+ rinfo->ram.trp = 2;
+ rinfo->ram.twr = 1;
+ rinfo->ram.cl = 2;
+ rinfo->ram.loop_latency = 16;
+ rinfo->ram.rloop = 16;
+
+ break;
+ case 1:
+ /* DDR SGRAM */
+ strcpy(rinfo->ram_type, "DDR SGRAM");
+ rinfo->ram.ml = 4;
+ rinfo->ram.mb = 4;
+ rinfo->ram.trcd = 3;
+ rinfo->ram.trp = 3;
+ rinfo->ram.twr = 2;
+ rinfo->ram.cl = 3;
+ rinfo->ram.tr2w = 1;
+ rinfo->ram.loop_latency = 16;
+ rinfo->ram.rloop = 16;
+
+ break;
+ default:
+ /* 64-bit SDR SGRAM */
+ strcpy(rinfo->ram_type, "SDR SGRAM 64");
+ rinfo->ram.ml = 4;
+ rinfo->ram.mb = 8;
+ rinfo->ram.trcd = 3;
+ rinfo->ram.trp = 3;
+ rinfo->ram.twr = 1;
+ rinfo->ram.cl = 3;
+ rinfo->ram.tr2w = 1;
+ rinfo->ram.loop_latency = 17;
+ rinfo->ram.rloop = 17;
+
+ break;
+ }
+
+ bios_seg = radeon_find_rom(rinfo);
+ radeon_get_pllinfo(rinfo, bios_seg);
+
+ printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d\n",
+ rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+
+ RTRACE("radeonfb: probed %s %dk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+
+ rinfo->fb_base = (u32) ioremap (rinfo->fb_base_phys,
+ rinfo->video_ram);
+ if (!rinfo->fb_base) {
+ printk ("radeonfb: cannot map FB\n");
+ iounmap ((void*)rinfo->mmio_base);
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ /* XXX turn off accel for now, blts aren't working right */
+ noaccel = 1;
+
+ /* set all the vital stuff */
+ radeon_set_fbinfo (rinfo);
+
+ /* save current mode regs before we switch into the new one
+ * so we can restore this upon __exit
+ */
+ radeon_save_state (rinfo, &rinfo->init_state);
+
+ /* init palette */
+ for (i=0; i<16; i++) {
+ j = color_table[i];
+ rinfo->palette[i].red = default_red[j];
+ rinfo->palette[i].green = default_grn[j];
+ rinfo->palette[i].blue = default_blu[j];
+ }
+
+ pdev->driver_data = rinfo;
+
+ if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
+ printk ("radeonfb: could not register framebuffer\n");
+ iounmap ((void*)rinfo->fb_base);
+ iounmap ((void*)rinfo->mmio_base);
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+ kfree (rinfo);
+ return -ENODEV;
+ }
+
+ if (!noaccel) {
+ /* initialize the engine */
+ radeon_engine_init (rinfo);
+ }
+
+ printk ("radeonfb: ATI Radeon %s %d MB\n", rinfo->ram_type,
+ (rinfo->video_ram/(1024*1024)));
+
+ return 0;
+}
+
+
+
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+{
+ struct radeonfb_info *rinfo = pdev->driver_data;
+
+ if (!rinfo)
+ return;
+
+ /* restore original state */
+ radeon_write_mode (rinfo, &rinfo->init_state);
+
+ unregister_framebuffer ((struct fb_info *) rinfo);
+
+ iounmap ((void*)rinfo->mmio_base);
+ iounmap ((void*)rinfo->fb_base);
+
+ release_mem_region (rinfo->mmio_base_phys,
+ pci_resource_len(pdev, 2));
+ release_mem_region (rinfo->fb_base_phys,
+ pci_resource_len(pdev, 0));
+
+ kfree (rinfo);
+}
+
+
+
+static char *radeon_find_rom(struct radeonfb_info *rinfo)
+{
+ u32 segstart;
+ char *rom_base;
+ char *rom;
+ int stage;
+ int i;
+ char aty_rom_sig[] = "761295520";
+ char radeon_sig[] = "RG6";
+
+#if defined(__i386__)
+ for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
+ stage = 1;
+
+ rom_base = (char *)ioremap(segstart, 0x1000);
+
+ if ((*rom_base == 0x55) && (((*(rom_base + 1)) & 0xff) == 0xaa))
+ stage = 2;
+
+
+ if (stage != 2) {
+ iounmap(rom_base);
+ continue;
+ }
+
+ rom = rom_base;
+
+ for (i = 0; (i < 128 - strlen(aty_rom_sig)) && (stage != 3); i++) {
+ if (aty_rom_sig[0] == *rom)
+ if (strncmp(aty_rom_sig, rom,
+ strlen(aty_rom_sig)) == 0)
+ stage = 3;
+ rom++;
+ }
+ if (stage != 3) {
+ iounmap(rom_base);
+ continue;
+ }
+ rom = rom_base;
+
+ for (i = 0; (i < 512) && (stage != 4); i++) {
+ if (radeon_sig[0] == *rom)
+ if (strncmp(radeon_sig, rom,
+ strlen(radeon_sig)) == 0)
+ stage = 4;
+ rom++;
+ }
+ if (stage != 4) {
+ iounmap(rom_base);
+ continue;
+ }
+
+ return rom_base;
+ }
+#endif
+ return NULL;
+}
+
+
+
+static void radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
+{
+ void *bios_header;
+ void *header_ptr;
+ u16 bios_header_offset, pll_info_offset;
+ PLL_BLOCK pll;
+
+ if (bios_seg) {
+ bios_header = bios_seg + 0x48L;
+ header_ptr = bios_header;
+
+ bios_header_offset = readw(header_ptr);
+ bios_header = bios_seg + bios_header_offset;
+ bios_header += 0x30;
+
+ header_ptr = bios_header;
+ pll_info_offset = readw(header_ptr);
+ header_ptr = bios_seg + pll_info_offset;
+
+ memcpy_fromio(&pll, header_ptr, 50);
+
+ rinfo->pll.xclk = (u32)pll.XCLK;
+ rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
+ rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
+ rinfo->pll.ppll_min = pll.PCLK_min_freq;
+ rinfo->pll.ppll_max = pll.PCLK_max_freq;
+ } else {
+ /* no BIOS or BIOS not found, use defaults */
+
+ rinfo->pll.ppll_max = 35000;
+ rinfo->pll.ppll_min = 12000;
+ rinfo->pll.xclk = 16600;
+ rinfo->pll.ref_div = 67;
+ rinfo->pll.ref_clk = 2700;
+ }
+}
+
+static void radeon_engine_init (struct radeonfb_info *rinfo)
+{
+ u32 temp;
+
+ /* disable 3D engine */
+ OUTREG(RB3D_CNTL, 0);
+
+ radeon_engine_reset ();
+
+ radeon_fifo_wait (1);
+ OUTREG(DSTCACHE_MODE, 0);
+
+ /* XXX */
+ rinfo->pitch = ((rinfo->xres * (rinfo->depth / 8) + 0x3f)) >> 6;
+
+ radeon_fifo_wait (1);
+ temp = INREG(DEFAULT_PITCH_OFFSET);
+ OUTREG(DEFAULT_PITCH_OFFSET, ((temp & 0xc0000000) |
+ (rinfo->pitch << 0x16)));
+
+ radeon_fifo_wait (1);
+ OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
+
+ radeon_fifo_wait (1);
+ OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
+ DEFAULT_SC_BOTTOM_MAX));
+
+ temp = radeon_get_dstbpp(rinfo->depth);
+ rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
+ radeon_fifo_wait (1);
+ OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+ GMC_BRUSH_SOLID_COLOR |
+ GMC_SRC_DATATYPE_COLOR));
+
+ radeon_fifo_wait (7);
+
+ /* clear line drawing regs */
+ OUTREG(DST_LINE_START, 0);
+ OUTREG(DST_LINE_END, 0);
+
+ /* set brush color regs */
+ OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
+ OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
+
+ /* set source color regs */
+ OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
+ OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
+
+ /* default write mask */
+ OUTREG(DP_WRITE_MSK, 0xffffffff);
+
+ radeon_engine_idle ();
+}
+
+
+
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+{
+ struct fb_info *info;
+
+ info = &rinfo->info;
+
+ strcpy (info->modename, rinfo->name);
+ info->node = -1;
+ info->flags = FBINFO_FLAG_DEFAULT;
+ info->fbops = &radeon_fb_ops;
+ info->display_fg = NULL;
+ strncpy (info->fontname, fontname, sizeof (info->fontname));
+ info->fontname[sizeof (info->fontname) - 1] = 0;
+ info->changevar = NULL;
+ info->switch_con = radeonfb_switch;
+ info->updatevar = radeonfb_updatevar;
+ info->blank = radeonfb_blank;
+
+ if (radeon_init_disp (rinfo) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+
+static int __devinit radeon_init_disp (struct radeonfb_info *rinfo)
+{
+ struct fb_info *info;
+ struct display *disp;
+
+ info = &rinfo->info;
+ disp = &rinfo->disp;
+
+ disp->var = radeonfb_default_var;
+ info->disp = disp;
+
+ radeon_set_dispsw (rinfo);
+
+ if (noaccel)
+ disp->scrollmode = SCROLL_YREDRAW;
+ else
+ disp->scrollmode = 0;
+
+ rinfo->currcon_display = disp;
+
+ if ((radeon_init_disp_var (rinfo)) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+
+static int radeon_init_disp_var (struct radeonfb_info *rinfo)
+{
+#ifndef MODULE
+ if (mode_option)
+ fb_find_mode (&rinfo->disp.var, &rinfo->info, mode_option,
+ NULL, 0, NULL, 8);
+ else
+#endif
+ fb_find_mode (&rinfo->disp.var, &rinfo->info, "640x480-8@60",
+ NULL, 0, NULL, 0);
+
+ if (noaccel)
+ rinfo->disp.var.accel_flags &= ~FB_ACCELF_TEXT;
+ else
+ rinfo->disp.var.accel_flags |= FB_ACCELF_TEXT;
+
+ return 0;
+}
+
+
+
+static void radeon_set_dispsw (struct radeonfb_info *rinfo)
+{
+ struct display *disp = &rinfo->disp;
+ int accel;
+
+ accel = disp->var.accel_flags & FB_ACCELF_TEXT;
+
+ disp->dispsw_data = NULL;
+
+ disp->screen_base = (char*)rinfo->fb_base;
+ disp->type = FB_TYPE_PACKED_PIXELS;
+ disp->type_aux = 0;
+ disp->ypanstep = 1;
+ disp->ywrapstep = 0;
+ disp->can_soft_blank = 1;
+ disp->inverse = 0;
+
+ rinfo->depth = disp->var.bits_per_pixel;
+ switch (disp->var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
+ disp->visual = FB_VISUAL_PSEUDOCOLOR;
+ disp->line_length = disp->var.xres_virtual;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ disp->dispsw = &fbcon_cfb16;
+ disp->dispsw_data = &rinfo->con_cmap.cfb16;
+ disp->visual = FB_VISUAL_DIRECTCOLOR;
+ disp->line_length = disp->var.xres_virtual * 2;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ disp->dispsw = &fbcon_cfb32;
+ disp->dispsw_data = &rinfo->con_cmap.cfb32;
+ disp->visual = FB_VISUAL_DIRECTCOLOR;
+ disp->line_length = disp->var.xres_virtual * 4;
+ break;
+#endif
+ default:
+ printk ("radeonfb: setting fbcon_dummy renderer\n");
+ disp->dispsw = &fbcon_dummy;
+ }
+
+ return;
+}
+
+
+
+/*
+ * fb ops
+ */
+
+static int radeonfb_get_fix (struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ struct display *disp;
+
+ disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+ memset (fix, 0, sizeof (struct fb_fix_screeninfo));
+ strcpy (fix->id, rinfo->name);
+
+ fix->smem_start = rinfo->fb_base_phys;
+ fix->smem_len = rinfo->video_ram;
+
+ fix->type = disp->type;
+ fix->type_aux = disp->type_aux;
+ fix->visual = disp->visual;
+
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
+ fix->ywrapstep = 0;
+
+ fix->line_length = disp->line_length;
+
+ fix->mmio_start = rinfo->mmio_base_phys;
+ fix->mmio_len = RADEON_REGSIZE;
+ if (noaccel)
+ fix->accel = FB_ACCEL_NONE;
+ else
+ fix->accel = 40; /* XXX */
+
+ return 0;
+}
+
+
+
+static int radeonfb_get_var (struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+
+ *var = (con < 0) ? rinfo->disp.var : fb_display[con].var;
+
+ return 0;
+}
+
+
+
+static int radeonfb_set_var (struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ struct display *disp;
+ struct fb_var_screeninfo v;
+ int nom, den, i, accel;
+ unsigned chgvar = 0;
+ static struct {
+ int xres, yres;
+ } modes[] = {
+ {
+ 1600, 1280}, {
+ 1280, 1024}, {
+ 1024, 768}, {
+ 800, 600}, {
+ 640, 480}, {
+ -1, -1}
+ };
+
+ disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+ accel = var->accel_flags & FB_ACCELF_TEXT;
+
+ if (con >= 0) {
+ chgvar = ((disp->var.xres != var->xres) ||
+ (disp->var.yres != var->yres) ||
+ (disp->var.xres_virtual != var->xres_virtual) ||
+ (disp->var.yres_virtual != var->yres_virtual) ||
+ memcmp (&disp->var.red, &var->red, sizeof (var->red)) ||
+ memcmp (&disp->var.green, &var->green, sizeof (var->green)) ||
+ memcmp (&disp->var.blue, &var->blue, sizeof (var->blue)));
+ }
+
+ memcpy (&v, var, sizeof (v));
+
+ switch (v.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ v.bits_per_pixel = 8;
+ disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
+ nom = den = 1;
+ disp->line_length = v.xres_virtual;
+ disp->visual = FB_VISUAL_PSEUDOCOLOR;
+ v.red.offset = v.green.offset = v.blue.offset = 0;
+ v.red.length = v.green.length = v.blue.length = 8;
+ break;
+#endif
+
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ v.bits_per_pixel = 16;
+ disp->dispsw = &fbcon_cfb16;
+ disp->dispsw_data = &rinfo->con_cmap.cfb16;
+ nom = 2;
+ den = 1;
+ disp->line_length = v.xres_virtual * 2;
+ disp->visual = FB_VISUAL_DIRECTCOLOR;
+ v.red.offset = 11;
+ v.green.offset = 5;
+ v.blue.offset = 0;
+ v.red.length = 5;
+ v.green.length = 6;
+ v.blue.length = 5;
+ break;
+#endif
+
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ v.bits_per_pixel = 32;
+ disp->dispsw = &fbcon_cfb32;
+ disp->dispsw_data = rinfo->con_cmap.cfb32;
+ nom = 4;
+ den = 1;
+ disp->line_length = v.xres_virtual * 4;
+ disp->visual = FB_VISUAL_DIRECTCOLOR;
+ v.red.offset = 16;
+ v.green.offset = 8;
+ v.blue.offset = 0;
+ v.red.length = v.blue.length = v.green.length = 8;
+ break;
+#endif
+ default:
+ printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ if (v.xres * nom / den * v.yres > (rinfo->video_ram)) {
+ printk ("radeonfb: mode %dx%dx%d rejected, not enough video ram\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ if (v.xres_virtual == -1 && v.yres_virtual == -1) {
+ printk ("radeonfb: using maximum available virtual resolution\n");
+ for (i = 0; modes[i].xres != -1; i++) {
+ if (modes[i].xres * nom / den * modes[i].yres < (rinfo->video_ram/2))
+ break;
+ }
+ if (modes[i].xres == -1) {
+ printk ("radeonfb: could not find a virtual res\n");
+ return -EINVAL;
+ }
+ v.xres_virtual = modes[i].xres;
+ v.yres_virtual = modes[i].yres;
+
+ printk ("radeonfb: virtual resolution set to maximum of %dx%d\n",
+ v.xres_virtual, v.yres_virtual);
+ }
+
+ if (v.xoffset < 0)
+ v.xoffset = 0;
+ if (v.yoffset < 0)
+ v.yoffset = 0;
+
+ if (v.xoffset > v.xres_virtual - v.xres)
+ v.xoffset = v.xres_virtual - v.xres - 1;
+
+ if (v.yoffset > v.yres_virtual - v.yres)
+ v.yoffset = v.yres_virtual - v.yres - 1;
+
+ v.red.msb_right = v.green.msb_right = v.blue.msb_right =
+ v.transp.offset = v.transp.length =
+ v.transp.msb_right = 0;
+
+ switch (v.activate & FB_ACTIVATE_MASK) {
+ case FB_ACTIVATE_TEST:
+ return 0;
+ case FB_ACTIVATE_NXTOPEN:
+ case FB_ACTIVATE_NOW:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ disp->type = FB_TYPE_PACKED_PIXELS;
+
+ memcpy (&disp->var, &v, sizeof (v));
+
+ radeon_load_video_mode (rinfo, &v);
+
+ if (chgvar && info && info->changevar)
+ info->changevar (con);
+
+ return 0;
+}
+
+
+
+static int radeonfb_get_cmap (struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ struct display *disp;
+
+ disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+ if (con == rinfo->currcon) {
+ int rc = fb_get_cmap (cmap, kspc, radeon_getcolreg, info);
+ return rc;
+ } else if (disp->cmap.len)
+ fb_copy_cmap (&disp->cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap (fb_default_cmap (radeon_get_cmap_len (&disp->var)),
+ cmap, kspc ? 0 : 2);
+
+ return 0;
+}
+
+
+
+static int radeonfb_set_cmap (struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ struct display *disp;
+ unsigned int cmap_len;
+
+ disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+ cmap_len = radeon_get_cmap_len (&disp->var);
+ if (disp->cmap.len != cmap_len) {
+ int err = fb_alloc_cmap (&disp->cmap, cmap_len, 0);
+ if (err)
+ return err;
+ }
+
+ if (con == rinfo->currcon) {
+ int rc = fb_set_cmap (cmap, kspc, radeon_setcolreg, info);
+ return rc;
+ } else
+ fb_copy_cmap (cmap, &disp->cmap, kspc ? 0 : 1);
+
+ return 0;
+}
+
+
+
+static int radeonfb_pan_display (struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ struct display *disp;
+ unsigned int base;
+
+ disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+ if (var->xoffset > (var->xres_virtual - var->xres))
+ return -EINVAL;
+ if (var->yoffset > (var->yres_virtual - var->yres))
+ return -EINVAL;
+
+ if (var->vmode & FB_VMODE_YWRAP) {
+ if (var->yoffset < 0 ||
+ var->yoffset >= disp->var.yres_virtual ||
+ var->xoffset )
+ return -EINVAL;
+ } else {
+ if (var->xoffset + disp->var.xres > disp->var.xres_virtual ||
+ var->yoffset + disp->var.yres > disp->var.yres_virtual)
+ return -EINVAL;
+ }
+
+ base = var->yoffset * disp->line_length + var->xoffset;
+
+ disp->var.xoffset = var->xoffset;
+ disp->var.yoffset = var->yoffset;
+
+ if (var->vmode & FB_VMODE_YWRAP)
+ disp->var.vmode |= FB_VMODE_YWRAP;
+ else
+ disp->var.vmode &= ~FB_VMODE_YWRAP;
+
+ return 0;
+}
+
+
+
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+ unsigned long arg, int con, struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+
+
+static int radeonfb_switch (int con, struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ struct display *disp;
+ struct fb_cmap *cmap;
+ int switchcon = 0;
+
+ disp = (con < 0) ? rinfo->info.disp : &fb_display[con];
+
+ if (rinfo->currcon >= 0) {
+ cmap = &(rinfo->currcon_display->cmap);
+ if (cmap->len)
+ fb_get_cmap (cmap, 1, radeon_getcolreg, info);
+ }
+
+ if ((disp->var.xres != rinfo->xres) ||
+ (disp->var.yres != rinfo->yres) ||
+ (disp->var.pixclock != rinfo->pixclock) ||
+ (disp->var.bits_per_pixel != rinfo->depth))
+ switchcon = 1;
+
+ if (switchcon) {
+ rinfo->currcon = con;
+ rinfo->currcon_display = disp;
+ disp->var.activate = FB_ACTIVATE_NOW;
+
+ radeonfb_set_var (&disp->var, con, info);
+ radeon_set_dispsw (rinfo);
+ }
+
+ return 0;
+}
+
+
+
+static int radeonfb_updatevar (int con, struct fb_info *info)
+{
+ int rc;
+
+ rc = (con < 0) ? -EINVAL : radeonfb_pan_display (&fb_display[con].var,
+ con, info);
+
+ return rc;
+}
+
+static void radeonfb_blank (int blank, struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ u8 mode = 0;
+
+ switch (blank) {
+ case 0:
+ /* unblank */
+ mode = 0;
+ break;
+ case 1:
+ /* blank */
+ mode = ((INREG8(CRTC_EXT_CNTL + 1) & 3) | 4);
+ break;
+ case 2:
+ case 3:
+ case 4:
+ mode = blank | 4;
+ break;
+ }
+
+ OUTREG8(CRTC_EXT_CNTL + 1, mode);
+}
+
+
+
+static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
+{
+ int rc = 16; /* reasonable default */
+
+ switch (var->bits_per_pixel) {
+ case 8:
+ rc = 256;
+ break;
+ case 16:
+ rc = 64;
+ break;
+ default:
+ rc = 32;
+ break;
+ }
+
+ return rc;
+}
+
+
+
+static int radeon_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+
+ if (regno > 255)
+ return 1;
+
+ *red = (rinfo->palette[regno].red<<8) | rinfo->palette[regno].red;
+ *green = (rinfo->palette[regno].green<<8) | rinfo->palette[regno].green;
+ *blue = (rinfo->palette[regno].blue<<8) | rinfo->palette[regno].blue;
+ *transp = 0;
+
+ return 0;
+}
+
+
+
+static int radeon_setcolreg (unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp, struct fb_info *info)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *) info;
+ u32 pindex, col;
+
+ if (regno > 255)
+ return 1;
+
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ rinfo->palette[regno].red = red;
+ rinfo->palette[regno].green = green;
+ rinfo->palette[regno].blue = blue;
+
+ /* init gamma for hicolor */
+ if ((rinfo->depth > 8) && (regno == 0)) {
+ int i;
+ u32 tmp;
+
+ for (i=0; i<255; i++) {
+ OUTREG(PALETTE_INDEX, i);
+ tmp = (i << 16) | (i << 8) | i;
+ radeon_fifo_wait(32);
+ OUTREG(PALETTE_DATA, tmp);
+ }
+ }
+
+ /* default */
+ pindex = regno;
+ col = (red << 16) | (green << 8) | blue;
+
+ if (rinfo->depth == 16) {
+ pindex = regno << 3;
+
+ if ((rinfo->depth == 16) && (regno >= 32)) {
+ pindex -= 252;
+
+ col = (rinfo->palette[regno >> 1].red << 16) |
+ (green << 8) |
+ (rinfo->palette[regno >> 1].blue);
+ } else {
+ col = (red << 16) | (green << 8) | blue;
+ }
+ }
+
+ OUTREG8(PALETTE_INDEX, pindex);
+ radeon_fifo_wait(32);
+ OUTREG(PALETTE_DATA, col);
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB32)
+ if (regno < 32) {
+ switch (rinfo->depth) {
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ rinfo->con_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
+ regno;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32: {
+ u32 i;
+
+ i = (regno << 8) | regno;
+ rinfo->con_cmap.cfb32[regno] = (i << 16) | i;
+ break;
+ }
+#endif
+ }
+ }
+#endif
+ return 0;
+}
+
+
+
+static void radeon_save_state (struct radeonfb_info *rinfo,
+ struct radeon_regs *save)
+{
+ save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
+ save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
+ save->dac_cntl = INREG(DAC_CNTL);
+ save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
+ save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
+ save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
+ save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
+ save->crtc_pitch = INREG(CRTC_PITCH);
+}
+
+
+
+static void radeon_load_video_mode (struct radeonfb_info *rinfo,
+ struct fb_var_screeninfo *mode)
+{
+ struct radeon_regs newmode;
+ int hTotal, vTotal, hSyncStart, hSyncEnd,
+ hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
+ u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
+ u32 dotClock = 1000000000 / mode->pixclock,
+ sync, h_sync_pol, v_sync_pol;
+ int freq = dotClock / 10; /* x 100 */
+ int xclk_freq, vclk_freq, xclk_per_trans, xclk_per_trans_precise;
+ int useable_precision, roff, ron;
+ int min_bits, format = 0;
+ int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
+
+ rinfo->xres = mode->xres;
+ rinfo->yres = mode->yres;
+ rinfo->pixclock = mode->pixclock;
+
+ hSyncStart = mode->xres + mode->right_margin;
+ hSyncEnd = hSyncStart + mode->hsync_len;
+ hTotal = hSyncEnd + mode->left_margin;
+
+ vSyncStart = mode->yres + mode->lower_margin;
+ vSyncEnd = vSyncStart + mode->vsync_len;
+ vTotal = vSyncEnd + mode->upper_margin;
+
+ sync = mode->sync;
+ h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+ v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+ RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
+ hSyncStart, hSyncEnd, hTotal);
+ RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
+ vSyncStart, vSyncEnd, vTotal);
+
+ hsync_wid = (hSyncEnd - hSyncStart) / 8;
+ vsync_wid = vSyncEnd - vSyncStart;
+ if (hsync_wid == 0)
+ hsync_wid = 1;
+ else if (hsync_wid > 0x3f) /* max */
+ hsync_wid = 0x3f;
+ vsync_wid = mode->vsync_len;
+ if (vsync_wid == 0)
+ vsync_wid = 1;
+ else if (vsync_wid > 0x1f) /* max */
+ vsync_wid = 0x1f;
+
+ hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+ vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+ cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
+
+ switch (mode->bits_per_pixel) {
+ case 8:
+ format = DST_8BPP;
+ bytpp = 1;
+ break;
+ case 16:
+ format = DST_16BPP;
+ bytpp = 2;
+ break;
+ case 24:
+ format = DST_24BPP;
+ bytpp = 3;
+ break;
+ case 32:
+ format = DST_32BPP;
+ bytpp = 4;
+ break;
+ }
+
+ hsync_fudge = hsync_adj_tab[format-1];
+ hsync_start = hSyncStart - 8 + hsync_fudge;
+
+ newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
+ (format << 8);
+
+ newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+
+ newmode.dac_cntl = INREG(DAC_CNTL) | DAC_MASK_ALL | DAC_VGA_ADR_EN |
+ DAC_8BIT_EN;
+
+ newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0xffff) |
+ (((mode->xres / 8) - 1) << 16));
+
+ newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
+ (hsync_wid << 16) | (h_sync_pol << 23));
+
+ newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
+ ((mode->yres - 1) << 16);
+
+ newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
+ (vsync_wid << 16) | (v_sync_pol << 23));
+
+ newmode.crtc_pitch = (mode->xres >> 3);
+
+ rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
+ & ~(0x3f)) / 64;
+
+ RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n",
+ newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
+ RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n",
+ newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
+
+ newmode.xres = mode->xres;
+ newmode.yres = mode->yres;
+
+ rinfo->bpp = mode->bits_per_pixel;
+
+ if (freq > rinfo->pll.ppll_max)
+ freq = rinfo->pll.ppll_max;
+ if (freq*12 < rinfo->pll.ppll_min)
+ freq = rinfo->pll.ppll_min / 12;
+
+ {
+ struct {
+ int divider;
+ int bitvalue;
+ } *post_div,
+ post_divs[] = {
+ { 1, 0 },
+ { 2, 1 },
+ { 4, 2 },
+ { 8, 3 },
+ { 3, 4 },
+ { 16, 5 },
+ { 6, 6 },
+ { 12, 7 },
+ { 0, 0 },
+ };
+
+ for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+ rinfo->pll_output_freq = post_div->divider * freq;
+ if (rinfo->pll_output_freq >= rinfo->pll.ppll_min &&
+ rinfo->pll_output_freq <= rinfo->pll.ppll_max)
+ break;
+ }
+
+ rinfo->post_div = post_div->divider;
+ rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
+ rinfo->pll.ref_clk);
+ newmode.ppll_ref_div = rinfo->pll.ref_div;
+ newmode.ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
+ }
+
+ RTRACE("post div = 0x%x\n", rinfo->post_div);
+ RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
+ RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3);
+
+ /* DDA */
+ vclk_freq = round_div(rinfo->pll.ref_clk * rinfo->fb_div,
+ rinfo->pll.ref_div * rinfo->post_div);
+ xclk_freq = rinfo->pll.xclk;
+
+ xclk_per_trans = round_div(xclk_freq * 128, vclk_freq * mode->bits_per_pixel);
+
+ min_bits = min_bits_req(xclk_per_trans);
+ useable_precision = min_bits + 1;
+
+ xclk_per_trans_precise = round_div((xclk_freq * 128) << (11 - useable_precision),
+ vclk_freq * mode->bits_per_pixel);
+
+ ron = (4 * rinfo->ram.mb + 3 * _max(rinfo->ram.trcd - 2, 0) +
+ 2 * rinfo->ram.trp + rinfo->ram.twr + rinfo->ram.cl + rinfo->ram.tr2w +
+ xclk_per_trans) << (11 - useable_precision);
+ roff = xclk_per_trans_precise * (32 - 4);
+
+ RTRACE("ron = %d, roff = %d\n", ron, roff);
+ RTRACE("vclk_freq = %d, per = %d\n", vclk_freq, xclk_per_trans_precise);
+
+ if ((ron + rinfo->ram.rloop) >= roff) {
+ printk("radeonfb: error ron out of range\n");
+ return;
+ }
+
+ newmode.dda_config = (xclk_per_trans_precise |
+ (useable_precision << 16) |
+ (rinfo->ram.rloop << 20));
+ newmode.dda_on_off = (ron << 16) | roff;
+
+ /* do it! */
+ radeon_write_mode (rinfo, &newmode);
+
+ return;
+}
+
+
+
+static void radeon_write_mode (struct radeonfb_info *rinfo,
+ struct radeon_regs *mode)
+{
+ int i;
+
+ /* blank screen */
+ OUTREG8(CRTC_EXT_CNTL + 1, 4);
+
+ for (i=0; i<9; i++)
+ OUTREG(common_regs[i].reg, common_regs[i].val);
+
+ OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
+ OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+ CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
+ OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
+ OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
+ OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
+ OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
+ OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
+ OUTREG(CRTC_OFFSET, 0);
+ OUTREG(CRTC_OFFSET_CNTL, 0);
+ OUTREG(CRTC_PITCH, mode->crtc_pitch);
+
+ while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
+ PPLL_DIV_SEL_MASK) {
+ OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
+ }
+
+ OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
+
+ while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
+ (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
+ OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
+ }
+
+ while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
+ (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
+ OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
+ }
+
+ while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
+ (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
+ OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
+ }
+
+ OUTPLL(HTOTAL_CNTL, 0);
+
+ OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
+
+ OUTREG(DDA_CONFIG, mode->dda_config);
+ OUTREG(DDA_ON_OFF, mode->dda_on_off);
+
+ /* unblank screen */
+ OUTREG8(CRTC_EXT_CNTL + 1, 0);
+
+ return;
+}
+
+
+
+/*
+ * text console acceleration
+ */
+
+
+static void fbcon_radeon_bmove(struct display *p, int srcy, int srcx,
+ int dsty, int dstx, int height, int width)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
+ u32 dp_cntl = DST_LAST_PEL;
+
+ srcx *= fontwidth(p);
+ srcy *= fontheight(p);
+ dstx *= fontwidth(p);
+ dsty *= fontheight(p);
+ width *= fontwidth(p);
+ height *= fontheight(p);
+
+ if (srcy < dsty) {
+ srcy += height - 1;
+ dsty += height - 1;
+ } else
+ dp_cntl |= DST_Y_TOP_TO_BOTTOM;
+
+ if (srcx < dstx) {
+ srcx += width - 1;
+ dstx += width - 1;
+ } else
+ dp_cntl |= DST_X_LEFT_TO_RIGHT;
+
+ radeon_fifo_wait(6);
+ OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+ GMC_BRUSH_NONE |
+ GMC_SRC_DATATYPE_COLOR |
+ ROP3_S |
+ DP_SRC_SOURCE_MEMORY));
+ OUTREG(DP_WRITE_MSK, 0xffffffff);
+ OUTREG(DP_CNTL, dp_cntl);
+ OUTREG(SRC_Y_X, (srcy << 16) | srcx);
+ OUTREG(DST_Y_X, (dsty << 16) | dstx);
+ OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
+}
+
+
+
+static void fbcon_radeon_clear(struct vc_data *conp, struct display *p,
+ int srcy, int srcx, int height, int width)
+{
+ struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
+ u32 clr;
+
+ clr = attr_bgcol_ec(p, conp);
+ clr |= (clr << 8);
+ clr |= (clr << 16);
+
+ srcx *= fontwidth(p);
+ srcy *= fontheight(p);
+ width *= fontwidth(p);
+ height *= fontheight(p);
+
+ radeon_fifo_wait(6);
+ OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+ GMC_BRUSH_SOLID_COLOR |
+ GMC_SRC_DATATYPE_COLOR |
+ ROP3_P));
+ OUTREG(DP_BRUSH_FRGD_CLR, clr);
+ OUTREG(DP_WRITE_MSK, 0xffffffff);
+ OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+ OUTREG(DST_Y_X, (srcy << 16) | srcx);
+ OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+}
+
+
+
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch fbcon_radeon8 = {
+ setup: fbcon_cfb8_setup,
+ bmove: fbcon_radeon_bmove,
+ clear: fbcon_cfb8_clear,
+ putc: fbcon_cfb8_putc,
+ putcs: fbcon_cfb8_putcs,
+ revc: fbcon_cfb8_revc,
+ clear_margins: fbcon_cfb8_clear_margins,
+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
#endif
#ifndef MODULE
-static const char *mode_option __initdata = NULL;
+static char *mode_option __initdata = NULL;
#else
static char *font = NULL;
#endif
break;
#endif
#ifdef FBCON_HAS_CFB16
+ case 15:
+ rc = 15; /* fix for 15 bpp depths on Riva 128 based cards */
case 16:
rc = 16; /* directcolor... 16 entries SW palette */
break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
break; /* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */
#endif
default:
- assert(0);
/* should not occur */
break;
}
--- /dev/null
+/*
+ * linux/drivers/video/sstfb.c -- voodoo graphics frame buffer
+ *
+ * Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *
+ * Created 15 Jan 2000 by Ghozlane Toumi
+ *
+ * Contributions (and many thanks) :
+ *
+ * 03/2001 James Simmons <jsimmons@linux-fbdev.org>
+ * 04/2001 Paul Mundt <lethal@chaoticdreams.org>
+ * 05/2001 Urs Ganse <urs.ganse@t-online.de>
+ * (initial work on voodoo2 port)
+ *
+ *
+ * $Id: sstfb.c,v 1.26.4.1 2001/08/29 01:30:37 ghoz Exp $
+ */
+
+/*
+ * The voodoo1 has the following memory mapped adress space:
+ * 0x000000 - 0x3fffff : registers (4Mb)
+ * 0x400000 - 0x7fffff : linear frame buffer (4Mb)
+ * 0x800000 - 0xffffff : texture memory (8Mb)
+ */
+
+/*
+ * misc notes, TODOs, toASKs, and deep thoughts
+
+-TODO: at one time or another test that the mode is acceptable by the monitor
+-ASK: I can choose different ordering for the color bitfields (rgba argb ...)
+ wich one should i use ? is there any preferred one ? It seems ARGB is
+ the one ...
+-ASK: later: how to cope with endianness ? the fbi chip has builtin functions
+ to do byte swizling /swapping, maybe use that ...
+-TODO: check the error paths . if something get wrong, the error doesn't seem
+ to be very well handled...if handled at all.. not good.
+-ASK: ioremap ou ioremap_nocache ? : nocache is safe
+-TODO: in set_var check the validity of timings (hsync vsync)...
+-FIXME: I'm not sure i like all the functions with no parameters.. change them
+ to use a sstfb_par or sstfb_info or something like that.
+-TODO: check and recheck the use of sst_wait_idle : we dont flush the fifo via
+ a nop command . so it's ok as long as the commands we pass don't go
+ through the fifo. warning: issuing a nop command seems to need pci_fifo
+ enabled
+-ASK: the 24 bits mode is NOT packed . how do i differenciate from a packed mode ?
+ set a pseudo alpha value not used ?
+-ASK: how does the 32 bpp work ? should i enable the pipeline so alpha values
+ are used ?
+-TODO: check how the voodoo graphics can cope with 24/32 bpp (engine is 16bpp
+ only)
+-ASK: Do i ioremap the complete area devoted to the lfb (4Mb), or check the
+ real size, then unmap and remap to the real size of the lfb ?
+ ... map all the area.
+-FIXME: in case of failure in the init sequence, be sure we return to a safe
+ state.
+-FIXME: 4MB boards have banked memory (FbiInit2 bits 1 & 20)
+-ASK: I stole "inverse" but seems it doesn't work... check what it realy does...
+Notes
+-TODO: change struct sst_info fb_info from static to array/dynamic
+ TTT comments is for code i've put there for debuging the "weird peinguin
+ syndrome", it should disapear soon
+
+ *
+ */
+
+/*
+ * debug info
+ * SST_DEBUG : enable debugging
+ * SST_DEBUG_REG : debug registers
+ * 0 : no debug
+ * 1 : dac calls, [un]set_bits, FbiInit
+ * 2 : insane debug level (log every register read/write)
+ * SST_DEBUG_FUNC : functions
+ * 0 : no debug
+ * 1 : function call / debug ioctl
+ * 2 : variables
+ * 3 : flood . you don't want to do that. trust me.
+ * SST_DEBUG_VAR : debug display/var structs
+ * 0 : no debug
+ * 1 : dumps display, fb_var
+ * SST_DEBUG_IOCTL : enable sstfb specific ioctls
+ * 0 : disable
+ * 1 : enable debug ioctls :
+ * toggle vga (0x46db) : toggle vga_pass_through
+ * fill fb (0x46dc) : fills fb
+ * dump var (0x46dd) : logs display[0-5].var
+ * test disp (0x46de) : draws a test motif
+ */
+
+/* #define SST_DEBUG */
+#undef SST_DEBUG
+
+#define SST_DEBUG_REG 0
+#define SST_DEBUG_FUNC 0
+#define SST_DEBUG_VAR 0
+#define SST_DEBUG_IOCTL 1
+
+/* #define EN_24_32_BPP *//* enable 24/32 bpp functions for testing only */
+#undef EN_24_32_BPP
+
+/*
+ Default video mode .
+ 0 800x600@60 took from glide
+ 1 640x480@75 took from glide
+ 2 1024x768@76 std fb.mode
+ 3 640x480@60 glide default */
+#define DEFAULT_MODE 1
+/*
+ * Includes
+ */
+
+#include <linux/string.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <asm/ioctl.h>
+
+#include <video/fbcon.h>
+#include <video/fbcon-cfb16.h>
+#ifdef EN_24_32_BPP
+# include <video/fbcon-cfb24.h>
+# include <video/fbcon-cfb32.h>
+#endif
+
+#include "sstfb.h"
+
+/* void Dump_regs(void); */
+
+/* sst default init registers */
+#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+
+#define FBIINIT1_DEFAULT \
+ ( \
+ FAST_PCI_WRITES \
+/* SLOW_PCI_WRITES*/ \
+ | VIDEO_RESET \
+ | 10 << TILES_IN_X_SHIFT\
+ | SEL_SOURCE_VCLK_2X_SEL\
+ | EN_LFB_READ \
+ )
+
+#define FBIINIT2_DEFAULT \
+ ( \
+ SWAP_DACVSYNC \
+ | EN_DRAM_OE \
+ | DRAM_REFRESH_16 \
+ | EN_DRAM_REFRESH \
+ | EN_FAST_RAS_READ \
+ | EN_RD_AHEAD_FIFO \
+ | EN_FAST_RD_AHEAD_WR \
+ )
+
+#define FBIINIT3_DEFAULT \
+ ( DISABLE_TEXTURE )
+
+#define FBIINIT4_DEFAULT \
+ ( \
+ FAST_PCI_READS \
+/* SLOW_PCI_READS*/ \
+ | LFB_READ_AHEAD \
+ )
+/* Careful with this one : writing back the data just read will trash the DAC
+ reading some fields give logic value on pins, but setting this field will
+ set the source signal driving the pin. conclusion : just use the default
+ as a base before writing back .
+*/
+#define FBIINIT6_DEFAULT (0x0)
+
+/********/
+
+int currcon; /* =0 */
+int num_sst; /* =0*/ /* number of initialized boards */
+
+/* initialized by setup */
+static int inverse; /* =0 */ /* invert colormap */
+static int vgapass; /* =0 */ /* enable Vga passthrough cable */
+static int mem; /* =0 */ /* mem size in Mb , 0 = autodetect */
+static int clipping = 1; /* use clipping (slower, safer) */
+static int gfxclk; /* =0 */ /* force FBI freq in Mhz . Dangerous */
+static int slowpci; /* =0 */ /* slow PCI settings */
+static int dev = -1; /* specify device (0..n) */
+static char * mode_option ;
+
+
+#if defined(FBCON_HAS_CFB16) || defined(FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+union {
+# ifdef FBCON_HAS_CFB16
+ u16 cfb16[16];
+# endif
+#ifdef EN_24_32_BPP
+# if defined (FBCON_HAS_CFB24) || defined(FBCON_HAS_CFB32)
+ u32 cfb32[16];
+# endif
+#endif
+ } fbcon_cmap;
+#endif
+static struct { u_int red, green, blue, transp; } palette[16];
+static struct sstfb_info fb_info;
+static struct display disp;
+
+/********/
+
+/* Interface to ze oueurld */
+int sstfb_init(void);
+int sstfb_setup(char *options);
+
+
+/* Framebuffer API */
+static int sstfb_open(struct fb_info *info, int user);
+static int sstfb_release(struct fb_info *info, int user);
+static int sstfb_get_fix(struct fb_fix_screeninfo *fix,
+ int con, struct fb_info *info);
+static int sstfb_get_var(struct fb_var_screeninfo *var,
+ int con, struct fb_info *info);
+static int sstfb_set_var(struct fb_var_screeninfo *var,
+ int con, struct fb_info *info);
+static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
+ int con, struct fb_info *info);
+static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
+ int con, struct fb_info *info);
+static int sstfb_pan_display(struct fb_var_screeninfo *var,
+ int con, struct fb_info *info);
+static int sstfb_ioctl(struct inode *inode, struct file *file,
+ u_int cmd, u_long arg, int con,
+ struct fb_info *info);
+
+/* Interface to the low level console driver */
+static int sstfbcon_switch(int con, struct fb_info *info);
+static int sstfbcon_updatevar(int con, struct fb_info *info);
+static void sstfbcon_blank(int blank, struct fb_info *info);
+
+/* Internal routines */
+static void sstfb_install_cmap(int con, struct fb_info *info);
+static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp, struct fb_info *info);
+static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+
+static int sstfb_set_par(const struct sstfb_par *par,
+ struct sstfb_info *sst_info);
+static int sstfb_decode_var (const struct fb_var_screeninfo *var,
+ struct sstfb_par *par,
+ const struct sstfb_info *sst_info);
+static int sstfb_encode_var (struct fb_var_screeninfo *var,
+ const struct sstfb_par *par,
+ const struct sstfb_info *sst_info);
+
+static void sstfb_test16(struct sstfb_info *sst_info);
+
+#ifdef EN_24_32_BPP
+static void sstfb_test32(struct sstfb_info *sst_info);
+#endif
+
+/* Low level routines */
+static int sst_get_memsize(u_long *memsize);
+static int sst_wait_idle(void);
+static int sst_detect_dactype(void);
+static int sst_detect_att(void);
+static int sst_detect_ti(void);
+static int sst_detect_ics(void);
+static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t);
+static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock);
+static int sst_set_pll_ics(const struct pll_timing *t, const int clock);
+static void sst_set_vidmod_att_ti(const int bpp);
+static void sst_set_vidmod_ics(const int bpp);
+static int sst_init(void);
+#ifdef MODULE
+static void sst_shutdown(void);
+#endif
+
+static struct fb_ops sstfb_ops = {
+ owner : THIS_MODULE,
+ fb_open: sstfb_open,
+ fb_release: sstfb_release,
+ fb_get_fix: sstfb_get_fix,
+ fb_get_var: sstfb_get_var,
+ fb_set_var: sstfb_set_var,
+ fb_get_cmap: sstfb_get_cmap,
+ fb_set_cmap: sstfb_set_cmap,
+ fb_pan_display: sstfb_pan_display,
+ fb_ioctl: sstfb_ioctl,
+};
+
+#ifndef DEFAULT_MODE
+# define DEFAULT_MODE 0
+#endif
+static struct fb_var_screeninfo sstfb_default =
+#if ( DEFAULT_MODE == 0 )
+ { /* 800x600@60, 16 bpp .borowed from glide/sst1/include/sst1init.h */
+ 800, 600, 800, 600, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0,
+ 25000, 86, 41, 23, 1, 127, 4,
+ 0, FB_VMODE_NONINTERLACED };
+#endif
+#if ( DEFAULT_MODE == 1 )
+ {/* 640x480@75, 16 bpp .borowed from glide/sst1/include/sst1init.h */
+ 640, 480, 640, 480, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0,
+ 31746, 118, 17, 16, 1, 63, 3,
+ 0, FB_VMODE_NONINTERLACED };
+#endif
+#if ( DEFAULT_MODE == 2 )
+ { /* 1024x768@76 took from my /etc/fb.modes */
+ 1024, 768, 1024, 768,0, 0, 16,0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0,
+ 11764, 208, 8, 36, 16, 120, 3 ,
+ 0, FB_VMODE_NONINTERLACED };
+#endif
+#if ( DEFAULT_MODE == 3 )
+ { /* 640x480@60 , 16bpp glide default ?*/
+ 640, 480, 640, 480, 0, 0, 16, 0,
+ {11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0,
+ 39721 , 38, 26 , 25 ,18 , 96 ,2,
+ 0, FB_VMODE_NONINTERLACED };
+#endif
+
+static struct dac_switch dacs[] = {
+ { name: "TI TVP3409",
+ detect: sst_detect_ti,
+ set_pll: sst_set_pll_att_ti,
+ set_vidmod: sst_set_vidmod_att_ti },
+
+ { name: "AT&T ATT20C409",
+ detect: sst_detect_att,
+ set_pll: sst_set_pll_att_ti,
+ set_vidmod: sst_set_vidmod_att_ti },
+ { name: "ICS ICS5342",
+ detect: sst_detect_ics,
+ set_pll: sst_set_pll_ics,
+ set_vidmod: sst_set_vidmod_ics },
+};
+
+static struct sst_spec voodoo1_spec = {
+ name : "Voodoo Graphics",
+ default_gfx_clock : 50000,
+ max_gfxclk : 60,
+};
+
+static struct sst_spec voodoo2_spec = {
+ name : "Voodoo2",
+ default_gfx_clock : 75000,
+ max_gfxclk : 85,
+};
+
+/*
+ *
+ * Definitions
+ *
+ */
+
+#if (SST_DEBUG_VAR > 0)
+/* debug info / dump a fb_var_screeninfo */
+static void sst_dbg_print_var(struct fb_var_screeninfo *var) {
+ dprintk(" {%d, %d, %d, %d, %d, %d, %d, %d,\n",
+ var->xres, var->yres, var->xres_virtual, var->yres_virtual,
+ var->xoffset, var->yoffset,
+ var->bits_per_pixel, var->grayscale);
+ dprintk(" {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d},\n",
+ var->red.offset, var->red.length, var->red.msb_right,
+ var->green.offset, var->green.length, var->green.msb_right,
+ var->blue.offset, var->blue.length, var->blue.msb_right,
+ var->transp.offset, var->transp.length,
+ var->transp.msb_right);
+ dprintk(" %d, %d, %d, %d, %d,\n",
+ var->nonstd, var->activate,
+ var->height, var->width, var->accel_flags);
+ dprintk(" %d, %d, %d, %d, %d, %d, %d,\n",
+ var->pixclock, var->left_margin, var->right_margin,
+ var->upper_margin, var->lower_margin,
+ var->hsync_len, var->vsync_len);
+ dprintk(" %#x, %#x}\n",var->sync, var->vmode);
+}
+#endif /* (SST_DEBUG_VAR > 0) */
+
+static void sst_dbg_print_read_reg (u32 reg, u32 val) {
+#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
+ char * regname =NULL;
+ switch (reg) {
+ case FBIINIT0: regname="FbiInit0"; break;
+ case FBIINIT1: regname="FbiInit1"; break;
+ case FBIINIT2: regname="FbiInit2"; break;
+ case FBIINIT3: regname="FbiInit3"; break;
+ case FBIINIT4: regname="FbiInit4"; break;
+ case FBIINIT6: regname="FbiInit6"; break;
+ }
+ if (regname == NULL)
+ r_ddprintk("sst_read(%#x): %#x\n", reg, val);
+ else
+ r_dprintk(" sst_read(%s): %#x\n", regname, val);
+#endif /* (SST_DEBUG_REG > 0) */
+}
+
+static void sst_dbg_print_write_reg (u32 reg, u32 val) {
+#if (SST_DEBUG_REG > 0) /* i need the init registers :) */
+ char * regname = NULL;
+
+ switch (reg) {
+ case FBIINIT0: regname="FbiInit0"; break;
+ case FBIINIT1: regname="FbiInit1"; break;
+ case FBIINIT2: regname="FbiInit2"; break;
+ case FBIINIT3: regname="FbiInit3"; break;
+ case FBIINIT4: regname="FbiInit4"; break;
+ case FBIINIT6: regname="FbiInit6"; break;
+ }
+ if (regname == NULL)
+ r_ddprintk("sst_write(%#x, %#x)\n", reg, val);
+ else
+ r_dprintk(" sst_write(%s, %#x)\n", regname, val);
+#endif /* (SST_DEBUG_REG > 0) */
+}
+
+/* register access */
+static inline u32 sst_read(u32 reg)
+{
+ u32 ret;
+
+ ret = readl(fb_info.mmio.vbase + reg);
+ sst_dbg_print_read_reg(reg, ret);
+ return ret;
+}
+
+static inline void sst_write(u32 reg, u32 val)
+{
+ sst_dbg_print_write_reg(reg, val);
+ writel(val, fb_info.mmio.vbase + reg);
+}
+
+static inline void sst_set_bits(u32 reg, u32 val)
+{
+ r_dprintk("sst_set_bits(%#x, %#x)\n", reg, val);
+ sst_write(reg, sst_read(reg) | val);
+}
+
+static inline void sst_unset_bits(u32 reg, u32 val)
+{
+ r_dprintk("sst_unset_bits(%#x, %#x)\n", reg, val);
+ sst_write(reg, sst_read(reg) & ~val);
+}
+
+/* dac access */
+/* dac_read should be remaped to FbiInit2 (via the pci reg init_enable) */
+static u8 sst_dac_read(u8 reg)
+{
+ u8 ret;
+
+#ifdef SST_DEBUG
+ if ((reg & 0x07) != reg) {
+ dprintk("bug line %d: register adress '%d' is to high\n",
+ __LINE__,reg);
+ }
+#endif
+ reg &= 0x07;
+ sst_write(DAC_DATA, ((u32)reg << 8) | DAC_READ_CMD );
+ sst_wait_idle();
+ /*udelay(10);*/
+ ret=(sst_read(DAC_READ) & 0xff);
+ r_dprintk("sst_dac_read(%#x): %#x\n", reg, ret);
+ return (u8)ret;
+}
+
+static void sst_dac_write(u8 reg, u8 val)
+{
+ r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val);
+#ifdef SST_DEBUG
+ if ((reg & 0x07) != reg)
+ dprintk("bug line %d: register adress '%d' is to high\n",
+ __LINE__,reg);
+#endif
+ reg &= 0x07;
+ sst_write(DAC_DATA,(((u32)reg << 8)) | (u32)val);
+}
+
+/* indexed access to ti/att dacs */
+static inline u32 dac_i_read(u8 reg)
+{
+ u32 ret;
+
+ sst_dac_write(DACREG_ADDR_I, reg);
+ ret = sst_dac_read(DACREG_DATA_I);
+ r_dprintk("sst_dac_read_i(%#x): %#x\n", reg, ret);
+ return ret;
+}
+
+static inline void dac_i_write(u8 reg,u8 val)
+{
+ r_dprintk("sst_dac_write_i(%#x, %#x)\n", reg, val);
+ sst_dac_write(DACREG_ADDR_I, reg);
+ sst_dac_write(DACREG_DATA_I, val);
+}
+
+/*
+ *
+ * Internal routines
+ *
+ */
+
+static void sstfb_install_cmap(int con, struct fb_info *info)
+{
+ f_dprintk("sstfb_install_cmap(con: %d)\n",con);
+ f_ddprintk("currcon: %d\n", currcon);
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, 1, sstfb_setcolreg, info);
+ else
+ fb_set_cmap(
+ fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+ 1, sstfb_setcolreg, info);
+}
+
+static int sstfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp, struct fb_info *info)
+{
+ f_ddprintk("sstfb_getcolreg\n");
+ if (regno >= 16) return 1;
+
+ *red = palette[regno].red;
+ *green = palette[regno].green;
+ *blue = palette[regno].blue;
+ *transp = palette[regno].transp;
+ f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
+ regno,*red, *green, *blue, *transp);
+ return 0;
+}
+
+static int sstfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ u32 col;
+
+ f_ddprintk("sstfb_setcolreg\n");
+ f_dddprintk("%-2d rvba: %#x, %#x, %#x, %#x\n",
+ regno, red, green, blue, transp);
+ if (regno >= 16) return 1;
+ palette[regno].red = red;
+ palette[regno].green = green;
+ palette[regno].blue = blue;
+
+ red >>= (16 - disp.var.red.length);
+ green >>= (16 - disp.var.green.length);
+ blue >>= (16 - disp.var.blue.length);
+ transp >>= (16 - disp.var.transp.length);
+ col = (red << disp.var.red.offset)
+ | (green << disp.var.green.offset)
+ | (blue << disp.var.blue.offset)
+ | (transp << disp.var.transp.offset);
+
+ switch(disp.var.bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ fbcon_cmap.cfb16[regno]=(u16)col;
+ break;
+#endif
+#ifdef EN_24_32_BPP
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ fbcon_cmap.cfb32[regno]=col;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ fbcon_cmap.cfb32[regno]=col;
+ break;
+#endif
+#endif
+ default:
+ eprintk("bug line %d: bad depth '%u'\n",__LINE__,
+ disp.var.bits_per_pixel);
+ break;
+ }
+ f_dddprintk("bpp: %d . encoded color: %#x\n",
+ disp.var.bits_per_pixel, col);
+ return 0;
+}
+
+/* set par according to var ( checks var ) */
+static int sstfb_decode_var (const struct fb_var_screeninfo *var,
+ struct sstfb_par *par,
+ const struct sstfb_info *sst_info)
+{
+ int real_length;
+
+ f_dprintk("sstfb_decode_var\n");
+ /* Check var validity */
+ if ((var->xres > 1024) || (!var->xres) || (!var->xres)) {
+ eprintk ("Unsupported resolution %dx%d\n",
+ var->xres, var->yres);
+ return -EINVAL;
+ }
+ if ((var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED) {
+ eprintk("Interlace non supported %#x\n",
+ (var->vmode & FB_VMODE_MASK));
+ return -EINVAL;
+ }
+
+
+ memset(par, 0, sizeof(par));
+ par->xDim = var->xres;
+ par->hSyncOn = var->hsync_len;
+ par->hSyncOff = var->xres + var->right_margin + var->left_margin;
+ par->hBackPorch = var->left_margin;
+ par->yDim = var->yres;
+ par->vSyncOn = var->vsync_len;
+ par->vSyncOff = var->yres + var->lower_margin + var->upper_margin;
+ par->vBackPorch = var->upper_margin;
+
+ switch (var->bits_per_pixel) {
+ case 0 ... 16 :
+ par->bpp = 16;
+ break;
+#ifdef EN_24_32_BPP
+ case 17 ... 24 :
+ par->bpp = 24;
+ break;
+ case 25 ... 32 :
+ par->bpp = 32;
+ break;
+#endif
+ default :
+ eprintk ("Unsupported bpp %d\n", par->bpp);
+ return -EINVAL;
+ break;
+ }
+
+ if (sst_info->is_voodoo2) {
+ /* voodoo2 has 32 pixel wide tiles , BUT stange things
+ happen with odd number of tiles */
+ par->tiles_in_X= (par->xDim + 63 ) / 64 * 2;
+ } else {
+ /* voodoo1 has 64 pixels wide tiles. */
+ par->tiles_in_X= (par->xDim + 63 ) / 64;
+ }
+
+ /*
+ * mem check
+ */
+ /* it seems that the fbi uses tiles of 64x16 pixels to "map" the mem*/
+ /* FIXME: i don't like this... looks wrong*/
+ real_length = par->tiles_in_X * (sst_info->is_voodoo2 ? 32 : 64 )
+ * ((par->bpp == 16) ? 2 : 4);
+/*shoud this function change var ? for instance with yvirt > yres ?*/
+
+ if ((real_length * var->yres) > fb_info.video.len) {
+ eprintk ("Not enough video memory\n");
+ return -ENOMEM;
+ }
+
+ par->freq = PS2KHZ(var->pixclock);
+
+ /* TODO add checks for timings */
+ return 0;
+}
+
+/* sets var according to par (basicaly, sets sane values) */
+static int sstfb_encode_var (struct fb_var_screeninfo *var,
+ const struct sstfb_par *par,
+ const struct sstfb_info *sst_info)
+{
+ memset(var,0,sizeof(struct fb_var_screeninfo));
+
+ var->xres = par->xDim;
+ var->yres = par->yDim;
+ var->xres_virtual = par->xDim;
+ var->yres_virtual = par->yDim;
+ var->bits_per_pixel = par->bpp;
+ /* {x|y}offset = 0 ; sync=0 */
+ var->height = -1;
+ var->width = -1;
+ var->pixclock = KHZ2PS(par->freq);
+ var->left_margin = par->hBackPorch;
+ var->right_margin = par->hSyncOff - par->xDim - par->hBackPorch;
+ var->upper_margin = par->vBackPorch;
+ var->lower_margin = par->vSyncOff - par->yDim - par->vBackPorch;
+ var->hsync_len = par->hSyncOn;
+ var->vsync_len = par->vSyncOn;
+ var->vmode = FB_VMODE_NONINTERLACED;
+
+ /*
+ * correct the color bit fields
+ */
+ /* var->{red|green|blue}.msb_right = 0; */
+
+ switch (par->bpp) {
+ case 16: /* RGB 565 LfbMode 0 */
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ var->transp.length = 0;
+
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->transp.offset = 0;
+ break;
+#ifdef EN_24_32_BPP
+ case 24: /* RGB 888 LfbMode 4 */
+ case 32: /* ARGB 8888 LfbMode 5 */
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ var->transp.length = 0;
+
+ var->red.offset = 16;
+ var->green.offset = 8;
+ var->blue.offset = 0;
+ var->transp.offset = 0; /* in 24bpp we fake a 32 bpp mode */
+ break;
+#endif
+ default:
+ eprintk ("bug line %d: bad depth '%u'\n", __LINE__, par->bpp);
+ break;
+ }
+ return 0;
+}
+
+/*
+ * Frame buffer API
+ */
+
+static int sstfb_open(struct fb_info *info, int user)
+{
+ f_dprintk("sstfb_open(user: %d)\n",user);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int sstfb_release(struct fb_info *info, int user)
+{
+ f_dprintk("sstfb_release(user: %d)\n",user);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static int sstfb_get_fix(struct fb_fix_screeninfo *fix,
+ int con, struct fb_info *info)
+{
+#define sst_info ((struct sstfb_info *) info)
+
+ struct fb_var_screeninfo *var;
+
+ f_dprintk("sstfb_get_fix(con: %d)\n",con);
+ if (con == -1)
+ var = &sstfb_default;
+ else
+ var = &fb_display[con].var;
+
+ strcpy(fix->id, sst_info->info.modename);
+ /* lfb phys address = membase + 4Mb */
+ fix->smem_start = sst_info->video.base;
+ fix->smem_len = sst_info->video.len;
+
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+ /*
+ * According to the specs, the linelength must be of 1024 *pixels*.
+ * and the 24bpp mode is in fact a 32 bpp mode.
+ */
+ fix->line_length = (var->bits_per_pixel == 16) ? 2048 : 4096 ;
+ return 0;
+#undef sst_info
+}
+
+static int sstfb_get_var(struct fb_var_screeninfo *var,
+ int con, struct fb_info *info)
+{
+ f_dprintk("sstfb_get_var(con: %d)\n",con);
+ if (con == -1)
+ *var = sstfb_default;
+ else
+ *var = fb_display[con].var;
+ print_var(var, "var");
+ return 0;
+ }
+
+static int sstfb_set_var(struct fb_var_screeninfo *var,
+ int con, struct fb_info *info)
+{
+#define sst_info ((struct sstfb_info *) info)
+
+ struct sstfb_par par;
+ struct display *display;
+ int err;
+ int old_bpp,old_xres,old_yres;
+
+ f_dprintk("sstfb_set_var(con: %d)\n",con);
+ f_ddprintk("xres yres vxres vyres bpp activate\n");
+ f_ddprintk("%-4d %-4d %-5d %-5d %-3d %#-8x\n",
+ var->xres,var->yres,var->xres_virtual,var->yres_virtual,
+ var->bits_per_pixel,var->activate);
+ if (con < 0)
+ display = &disp;
+ else
+ display = &fb_display[con];
+
+ err = sstfb_decode_var(var, &par, sst_info);
+ if (err)
+ return err;
+ sstfb_encode_var (var, &par, sst_info);
+
+ switch (var->activate & FB_ACTIVATE_MASK) {
+ case FB_ACTIVATE_TEST:
+ return 0;
+ case FB_ACTIVATE_NXTOPEN:
+ case FB_ACTIVATE_NOW:
+ break;
+ default:
+ return -EINVAL;
+ }
+ old_xres = display->var.xres;
+ old_yres = display->var.yres;
+ old_bpp = display->var.bits_per_pixel;
+ display->var = *var;
+
+ if ((old_xres != var->xres) || (old_yres != var->yres)
+ || (old_bpp != var->bits_per_pixel)) {
+ /* 2-3 lignes redondantes avec get_fix */
+ display->screen_base = (char *) sst_info->video.vbase;
+ display->visual = FB_VISUAL_TRUECOLOR;
+ display->type = FB_TYPE_PACKED_PIXELS;
+ display->type_aux = 0;
+ display->ypanstep = 0;
+ display->ywrapstep = 0;
+ display->line_length = (var->bits_per_pixel==16) ? 2048 : 4096;
+ display->inverse = 0;
+ switch (var->bits_per_pixel) {
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ display->dispsw = &fbcon_cfb16;
+ display->dispsw_data = fbcon_cmap.cfb16;
+ break;
+#endif
+#ifdef EN_24_32_BPP
+#if defined (FBCON_HAS_CFB24) || defined (FBCON_HAS_CFB32 )
+ case 24: /*24bpp non packed <=> 32 bpp */
+ case 32:
+ display->dispsw = &fbcon_cfb32;
+ display->dispsw_data = fbcon_cmap.cfb32;
+ break;
+#endif
+#endif
+ default:
+ display->dispsw = &fbcon_dummy;
+ break;
+ }
+ display->scrollmode = SCROLL_YREDRAW;
+ if (sst_info->info.changevar) {
+ v_dprintk("fb_info.changevar(con: %d)\n", con);
+ (*sst_info->info.changevar)(con);
+ v_dprintk("fb_info.changevar: done \n");
+ } else {
+ v_dprintk("fb_info.changevar() == NULL . \n");
+ }
+ }
+
+ if ((con <0) || (con==currcon)) {
+ sstfb_set_par (&par, sst_info);
+ }
+ print_var(var, "var");
+ print_var(&display->var, "&display->var");
+
+ if (old_bpp != var->bits_per_pixel) {
+ if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+ return err;
+ sstfb_install_cmap(con, info);
+ }
+
+ return 0;
+#undef sst_info
+}
+
+
+static int sstfb_set_cmap(struct fb_cmap *cmap, int kspc,
+ int con, struct fb_info *info)
+{
+ struct display *d = (con<0) ? info->disp : fb_display + con;
+
+ f_dprintk("sstfb_set_cmap\n");
+ f_ddprintk("con: %d, currcon: %d, d->cmap.len %d\n",
+ con, currcon, d->cmap.len);
+
+ if (d->cmap.len != 16 ) { /* or test if cmap.len == 0 ? */
+ int err;
+ err = fb_alloc_cmap(&d->cmap, 16, 0); /* cmap size=16 */
+ if (err) return err;
+ }
+ if (con == currcon) {
+ return fb_set_cmap(cmap, kspc, sstfb_setcolreg, info);
+ } else {
+ fb_copy_cmap(cmap, &d->cmap, kspc ? 0 : 1);
+ }
+ return 0;
+}
+
+static int sstfb_get_cmap(struct fb_cmap *cmap, int kspc,
+ int con, struct fb_info *info)
+{
+ f_dprintk("sstfb_get_cmap\n");
+ f_ddprintk("con %d, curcon %d, cmap.len %d\n",
+ con, currcon, fb_display[con].cmap.len);
+
+ /* FIXME: check if con = -1 ? cf sstfb_set_cmap... */
+ if (con == currcon)
+ return fb_get_cmap(cmap, kspc, sstfb_getcolreg, info);
+ else if (fb_display[con].cmap.len)
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap(
+ fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+ cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+/* TODO */
+static int sstfb_pan_display(struct fb_var_screeninfo *var,
+ int con, struct fb_info *info)
+{
+ f_dprintk("sstfb_pan_display\n");
+ return -EINVAL;
+}
+
+static int sstfb_ioctl(struct inode *inode, struct file *file,
+ u_int cmd, u_long arg, int con,
+ struct fb_info *info)
+{
+#define sst_info ((struct sstfb_info *) info)
+#if (SST_DEBUG_IOCTL >0)
+ int i;
+ u_long p;
+ u32 tmp;
+ u32 fbiinit0;
+ struct pci_dev * sst_dev = sst_info->dev;
+#endif
+
+ f_dprintk("sstfb_ioctl(%x)\n", cmd);
+#if (SST_DEBUG_IOCTL >0)
+ switch (cmd) {
+# if (SST_DEBUG_VAR >0)
+/* tmp ioctl : dumps fb_display[0-5] */
+ case _IO('F', 0xdb): /* 0x46db */
+ f_dprintk("dumping fb_display[0-5].var\n");
+ for (i = 0 ; i< 6 ; i++) {
+ print_var(&fb_display[i].var, "var(%d)", i);
+ }
+ return 0;
+# endif /* (SST_DEBUG_VAR >0) */
+/* fills the lfb up to *(u32*)arg */
+ case _IOW('F', 0xdc, u32): /* 0x46dc */
+ if (*(u32*)arg > 0x400000 )
+ *(u32*) arg = 0x400000;
+ f_dprintk("filling %#x \n", *(u32*)arg);
+ for (p = 0 ; p < *(u32*)arg; p+=2)
+ writew( p >> 6 , sst_info->video.vbase + p);
+ return 0;
+/* change VGA pass_through */
+ case _IOW('F', 0xdd, u32): /* 0x46dd */
+ f_dprintk("switch VGA pass-through\n");
+ pci_read_config_dword(sst_dev, PCI_INIT_ENABLE, &tmp);
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ tmp | PCI_EN_INIT_WR );
+ fbiinit0 = sst_read (FBIINIT0);
+ if (* (u32*)arg) {
+ sst_write(FBIINIT0, fbiinit0 & ~EN_VGA_PASSTHROUGH);
+ iprintk ( "Disabling VGA pass-through\n");
+ } else {
+ sst_write(FBIINIT0, fbiinit0 | EN_VGA_PASSTHROUGH);
+ iprintk ( "Enabling VGA pass-through\n");
+ }
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);
+ return 0;
+ case _IO('F', 0xde): /* 0x46de */
+ f_dprintk("test color display\n");
+ f_ddprintk("currcon: %d, bpp %d\n",
+ currcon, fb_display[currcon].var.bits_per_pixel);
+ memset_io(sst_info->video.vbase, 0, sst_info->video.len);
+ switch (fb_display[currcon].var.bits_per_pixel) {
+/* FIXME broken : if we call this ioctl from a tty not bound to the fb, we use its depth and not the current one ... */
+ case 16:
+ sstfb_test16(sst_info);
+ break;
+# ifdef EN_24_32_BPP
+ case 24:
+ case 32:
+ sstfb_test32(sst_info);
+ break;
+# endif
+ default:
+ dprintk("bug line %d: bad depth '%u'\n", __LINE__,
+ fb_display[currcon].var.bits_per_pixel);
+ }
+ return 0;
+ }
+#endif /* (SST_DEBUG_IOCTL >0) */
+ return -EINVAL;
+#undef sst_info
+}
+
+
+/*
+ * Low level routines
+ */
+
+/* get lfb size */
+
+static int sst_get_memsize(u_long *memsize)
+{
+ u32 fbbase_virt = fb_info.video.vbase;
+ f_dprintk("sst_get_memsize\n");
+
+ /* force memsize */
+ if ((mem >= 1 ) && (mem <= 4)) {
+ *memsize = (mem * 0x100000);
+ iprintk("supplied memsize: %#lx\n", *memsize);
+ return 1;
+ }
+
+ writel (0xdeadbeef, fbbase_virt);
+ writel (0xdeadbeef, fbbase_virt+0x100000);
+ writel (0xdeadbeef, fbbase_virt+0x200000);
+ f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",
+ readl(fbbase_virt), readl(fbbase_virt + 0x100000),
+ readl(fbbase_virt + 0x200000));
+
+ writel (0xabcdef01, fbbase_virt);
+
+ f_ddprintk("0Mb: %#x, 1Mb: %#x, 2Mb: %#x\n",
+ readl(fbbase_virt), readl(fbbase_virt + 0x100000),
+ readl(fbbase_virt + 0x200000));
+
+ /* checks for 4mb lfb , then 2, then defaults to 1*/
+ if (readl(fbbase_virt + 0x200000) == 0xdeadbeef) {
+ *memsize = 0x400000;
+ } else if (readl(fbbase_virt + 0x100000) == 0xdeadbeef) {
+ *memsize = 0x200000;
+ } else {
+ *memsize = 0x100000;
+ }
+ f_ddprintk("detected memsize: %#lx\n", *memsize);
+ return 1;
+}
+
+
+/*
+ * wait for the fbi chip. ASK: what happens if the fbi is stuck ?
+ *
+ * the FBI is supposed to be ready if we receive 5 time
+ * in a row a "idle" answer to our requests
+ */
+
+static int sst_wait_idle(void)
+{
+ int count = 0;
+
+ f_ddprintk("sst_wait_idle\n");
+ while(1) {
+ if (sst_read(STATUS) & STATUS_FBI_BUSY) {
+ f_dddprintk("status: busy\n");
+/* FIXME basicaly, this is a busy wait. maybe not that good. oh well; this is a small loop after all ...*/
+ count = 0;
+ } else {
+ count++;
+ f_dddprintk("status: idle(%d)\n", count);
+ }
+ if (count >= 5) return 1;
+ }
+}
+
+/*
+ * detect dac type
+ * prerequisite : write to FbiInitx enabled, video and fbi and pci fifo reset,
+ * dram refresh disabled, FbiInit remaped.
+ * TODO: mmh.. maybe i shoud put the "prerequisite" in the func ...
+ */
+static int __init sst_detect_dactype(void)
+{
+ int ret=0,i;
+ f_dprintk("sst_detect_dactype\n");
+ for (i=0; i< sizeof(dacs)/sizeof(dacs[0]) ; i++) {
+ ret = dacs[i].detect();
+ if (ret) break;
+ }
+ if (!ret)
+ return 0;
+ f_dprintk("found %s\n", dacs[i].name);
+ fb_info.dac_sw=&dacs[i];
+ return 1;
+}
+
+/* fbi should be idle, and fifo emty and mem disabled */
+/* supposed to detect AT&T ATT20C409 and Ti TVP3409 ramdacs */
+
+static int __init (sst_detect_att(void))
+{
+ int i, mir, dir;
+
+ f_dprintk("sst_detect_att\n");
+ for (i = 0; i<3; i++) {
+ sst_dac_write(DACREG_WMA, 0); /* backdoor */
+ sst_dac_read(DACREG_RMR); /* read 4 times RMR */
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ /* the fifth time, CR0 is read */
+ sst_dac_read(DACREG_RMR);
+ /* the 6th, manufacturer id register */
+ mir = sst_dac_read(DACREG_RMR);
+ /*the 7th, device ID register */
+ dir = sst_dac_read(DACREG_RMR);
+ f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
+ if ((mir == DACREG_MIR_ATT ) && (dir == DACREG_DIR_ATT)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int __init (sst_detect_ti(void))
+{
+ int i, mir, dir;
+
+ f_dprintk("sst_detect_ti\n");
+ for (i = 0; i<3; i++) {
+ sst_dac_write(DACREG_WMA, 0); /* backdoor */
+ sst_dac_read(DACREG_RMR); /* read 4 times RMR */
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ /* the fifth time, CR0 is read */
+ sst_dac_read(DACREG_RMR);
+ /* the 6th, manufacturer id register */
+ mir = sst_dac_read(DACREG_RMR);
+ /*the 7th, device ID register */
+ dir = sst_dac_read(DACREG_RMR);
+ f_ddprintk("mir: %#x, dir: %#x\n", mir, dir);
+ if ((mir == DACREG_MIR_TI ) && (dir == DACREG_DIR_TI)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * try to detect ICS5342 ramdac
+ * we get the 1st byte (M value) of preset f1,f7 and fB
+ * why those 3 ? mmmh... for now, i'll do it the glide way...
+ * and ask questions later. anyway, it seems that all the freq registers are
+ * realy at their default state (cf specs) so i ask again, why those 3 regs ?
+ * mmmmh.. it seems that's much more ugly than i thought. we use f0 and fA for
+ * pll programming, so in fact, we *hope* that the f1, f7 & fB won't be
+ * touched...
+ * is it realy safe ? how can i reset this ramdac ? geee...
+ */
+static int __init sst_detect_ics(void)
+{
+ int i;
+ int m_clk0_1, m_clk0_7, m_clk1_b;
+ int n_clk0_1, n_clk0_7, n_clk1_b;
+ f_dprintk("sst_detect_ics\n");
+ for (i = 0; i<5; i++ ) {
+ sst_dac_write(DACREG_ICS_PLLRMA, 0x1); /* f1 */
+ m_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
+ n_clk0_1 = sst_dac_read(DACREG_ICS_PLLDATA);
+ sst_dac_write(DACREG_ICS_PLLRMA, 0x7); /* f7 */
+ m_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
+ n_clk0_7 = sst_dac_read(DACREG_ICS_PLLDATA);
+ sst_dac_write(DACREG_ICS_PLLRMA, 0xb); /* fB */
+ m_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
+ n_clk1_b= sst_dac_read(DACREG_ICS_PLLDATA);
+ f_ddprintk("m_clk0_1: %#x, m_clk0_7: %#x, m_clk1_b: %#x\n",
+ m_clk0_1, m_clk0_7, m_clk1_b);
+ f_ddprintk("n_clk0_1: %#x, n_clk0_7: %#x, n_clk1_b: %#x\n",
+ n_clk0_1, n_clk0_7, n_clk1_b);
+ if (( m_clk0_1 == DACREG_ICS_PLL_CLK0_1_INI)
+ && (m_clk0_7 == DACREG_ICS_PLL_CLK0_7_INI)
+ && (m_clk1_b == DACREG_ICS_PLL_CLK1_B_INI)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* compute the m,n,p , returns the real freq
+ * (ics datasheet : N <-> N1 , P <-> N2)
+ *
+ * Fout= Fref * (M+2)/( 2^P * (N+2))
+ * we try to get close to the asked freq
+ * with P as high, and M as low as possible
+ * range:
+ * ti/att : 0 <= M <= 255; 0 <= P <= 3; 0<= N <= 63
+ * ics : 1 <= M <= 127; 0 <= P <= 3; 1<= N <= 31
+ * we'll use the lowest limitation, should be precise enouth
+ */
+static int sst_calc_pll(const int freq, int *freq_out, struct pll_timing *t)
+{
+ int m, m2, n, p, best_err, fout;
+ int best_n=-1;
+ int best_m=-1;
+
+ f_dprintk("sst_calc_pll(%dKhz)\n", freq);
+ best_err = freq;
+ p=3;
+ /* f * 2^P = vco should be less than VCOmax ~ 250 MHz for ics*/
+ while (((1 << p) * freq > VCO_MAX) && (p >= 0))
+ p--;
+ if (p == -1)
+ return -EINVAL;
+ for (n = 1; n < 32; n++) {
+ /* calc 2 * m so we can round it later*/
+ m2 = (2 * freq * (1 << p) * (n + 2) ) / DAC_FREF - 4 ;
+
+ m = (m2 % 2 ) ? m2/2+1 : m2/2 ;
+ if (m >= 128)
+ break;
+ fout = (DAC_FREF * (m + 2)) / ((1 << p) * (n + 2));
+ if ((ABS(fout - freq) < best_err) && (m > 0)) {
+ best_n = n;
+ best_m = m;
+ best_err = ABS(fout - freq);
+ /* we get the lowest m , allowing 0.5% error in freq*/
+ if (200*best_err < freq) break;
+ }
+ }
+ if (best_n == -1) /* unlikely, but who knows ? */
+ return -EINVAL;
+ t->p=p;
+ t->n=best_n;
+ t->m=best_m;
+ *freq_out=(DAC_FREF * (t->m + 2)) / ((1 << t->p) * (t->n + 2));
+ f_ddprintk ("m: %d, n: %d, p: %d, F: %dKhz\n",
+ t->m, t->n, t->p, *freq_out);
+ return 0;
+}
+
+/*
+ * gfx, video, pci fifo should be reset, dram refresh disabled
+ * see detect_dac
+ */
+
+static int sst_set_pll_att_ti(const struct pll_timing *t, const int clock)
+{
+ u8 cr0, cc;
+ f_dprintk("sst_set_pll_att_ti\n");
+
+ /* enable indexed mode */
+
+ sst_dac_write(DACREG_WMA, 0); /* backdoor */
+ sst_dac_read(DACREG_RMR); /* 1 time: RMR */
+ sst_dac_read(DACREG_RMR); /* 2 RMR */
+ sst_dac_read(DACREG_RMR); /* 3 // */
+ sst_dac_read(DACREG_RMR); /* 4 // */
+ cr0 = sst_dac_read(DACREG_RMR); /* 5 CR0 */
+
+ sst_dac_write(DACREG_WMA, 0);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_write(DACREG_RMR, (cr0 & 0xf0)
+ | DACREG_CR0_EN_INDEXED
+ | DACREG_CR0_8BIT
+ | DACREG_CR0_PWDOWN );
+ /* so, now we are in indexed mode . dunno if its common, but
+ i find this way of doing things a little bit weird :p */
+
+ udelay(300);
+ cc = dac_i_read(DACREG_CC_I);
+ switch (clock) {
+ case VID_CLOCK:
+ dac_i_write(DACREG_AC0_I, t->m);
+ dac_i_write(DACREG_AC1_I, t->p << 6 | t->n);
+ dac_i_write(DACREG_CC_I,
+ (cc & 0x0f) | DACREG_CC_CLKA | DACREG_CC_CLKA_C);
+ break;
+ case GFX_CLOCK:
+ dac_i_write(DACREG_BD0_I, t->m);
+ dac_i_write(DACREG_BD1_I, t->p << 6 | t->n);
+ dac_i_write(DACREG_CC_I,
+ (cc & 0xf0) | DACREG_CC_CLKB | DACREG_CC_CLKB_D);
+ break;
+ default:
+ dprintk("bug line %d: wrong clock code '%d'\n",
+ __LINE__,clock);
+ return 0;
+ }
+ udelay(300);
+
+ /* power up the dac & return to "normal" non-indexed mode */
+ dac_i_write(DACREG_CR0_I,
+ cr0 & ~DACREG_CR0_PWDOWN & ~DACREG_CR0_EN_INDEXED);
+ return 1;
+}
+
+static int sst_set_pll_ics(const struct pll_timing *t, const int clock)
+{
+ u8 pll_ctrl;
+
+ f_dprintk("sst_set_pll_ics\n");
+
+ sst_dac_write(DACREG_ICS_PLLRMA, DACREG_ICS_PLL_CTRL);
+ pll_ctrl = sst_dac_read(DACREG_ICS_PLLDATA);
+ switch(clock) {
+ case VID_CLOCK:
+ sst_dac_write(DACREG_ICS_PLLWMA, 0x0); /* CLK0, f0 */
+ sst_dac_write(DACREG_ICS_PLLDATA, t->m);
+ sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
+ /* selects freq f0 for clock 0 */
+ sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
+ sst_dac_write(DACREG_ICS_PLLDATA,
+ (pll_ctrl & 0xd8)
+ | DACREG_ICS_CLK0
+ | DACREG_ICS_CLK0_0);
+ break;
+ case GFX_CLOCK :
+ sst_dac_write(DACREG_ICS_PLLWMA, 0xa); /* CLK1, fA */
+ sst_dac_write(DACREG_ICS_PLLDATA, t->m);
+ sst_dac_write(DACREG_ICS_PLLDATA, t->p << 5 | t->n);
+ /* selects freq fA for clock 1 */
+ sst_dac_write(DACREG_ICS_PLLWMA, DACREG_ICS_PLL_CTRL);
+ sst_dac_write(DACREG_ICS_PLLDATA,
+ (pll_ctrl & 0xef) | DACREG_ICS_CLK1_A);
+ break;
+ default:
+ dprintk("bug line %d: wrong clock code '%d'\n",
+ __LINE__, clock);
+ return 0;
+ }
+ udelay(300);
+ return 1;
+}
+
+static int sstfb_set_par(const struct sstfb_par * par, struct sstfb_info * sst_info)
+{
+ u32 lfbmode, fbiinit1, fbiinit2, fbiinit3, fbiinit6=0;
+ int ntiles;
+ struct pll_timing pll;
+ int fout;
+ struct pci_dev * sst_dev = sst_info->dev;
+
+ f_dprintk("sst_set_par(%dx%d)\n", par->xDim, par->yDim);
+ f_ddprintk("hSyncOn hSyncOff vSyncOn vSyncOff\n");
+ f_ddprintk("%-7d %-8d %-7d %-8d\n",
+ par->hSyncOn, par->hSyncOff,
+ par->vSyncOn, par->vSyncOff);
+ f_ddprintk("hBackPorch vBackPorch xDim yDim Freq\n");
+ f_ddprintk("%-10d %-10d %-4d %-4d %-8d\n",
+ par->hBackPorch, par->vBackPorch,
+ par->xDim, par->yDim, par->freq);
+
+
+ sst_calc_pll (par->freq, &fout, &pll);
+
+ sst_write(NOPCMD, 0);
+ sst_wait_idle();
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
+ sst_set_bits(FBIINIT1, VIDEO_RESET);
+ sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+ sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
+ sst_wait_idle();
+
+ /*sst_unset_bits (FBIINIT0, FBI_RESET); / reenable FBI ? */
+
+ sst_write(BACKPORCH, par->vBackPorch << 16 | (par->hBackPorch-2));
+ sst_write(VIDEODIMENSIONS, (par->yDim - 1) << 16 | (par->xDim - 1));
+ sst_write(HSYNC, (par->hSyncOff-1) << 16 | (par->hSyncOn-1));
+ sst_write(VSYNC, par->vSyncOff << 16 | par->vSyncOn);
+
+ fbiinit2=sst_read(FBIINIT2);
+ fbiinit3=sst_read(FBIINIT3);
+
+ /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ PCI_EN_INIT_WR | PCI_REMAP_DAC );
+
+ sst_info->dac_sw->set_vidmod(par->bpp);
+ /* set video clock */
+ sst_info->dac_sw->set_pll(&pll, VID_CLOCK);
+ /* disable fbiinit2/3 remap */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ PCI_EN_INIT_WR);
+ /* restore fbiinit2/3 */
+ sst_write(FBIINIT2,fbiinit2);
+ sst_write(FBIINIT3,fbiinit3);
+
+ fbiinit1 = (sst_read(FBIINIT1) & VIDEO_MASK)
+ | EN_DATA_OE
+ | EN_BLANK_OE
+ | EN_HVSYNC_OE
+ | EN_DCLK_OE
+/* | (15 << TILES_IN_X_SHIFT)*/
+ | SEL_INPUT_VCLK_2X
+/* | (2 << VCLK_2X_SEL_DEL_SHIFT)
+ | (2 << VCLK_DEL_SHIFT)*/;
+/* try with vclk_in_delay =0 (bits 29:30) , vclk_out_delay =0 (bits(27:28)
+ in (near) future set them accordingly to revision + resolution (cf glide)
+ first understand what it stands for :)
+ FIXME: there are some artefacts... check for the vclk_in_delay
+ lets try with 6ns delay in both vclk_out & in...
+ doh... they're still there :\
+*/
+
+ ntiles = par->tiles_in_X;
+ if (sst_info->is_voodoo2) {
+ fbiinit1 |= ((ntiles & 0x20) >> 5) << TILES_IN_X_MSB_SHIFT
+ | ((ntiles & 0x1e) >> 1) << TILES_IN_X_SHIFT ;
+/* as the only value of importance for us in fbiinit6 is tiles in X (lsb),
+ and as reading fbinit 6 will return crap (see FBIINIT6_DEFAULT) we just
+ write our value. BTW due to the dac unable to read odd number of tiles, this
+ field is always null ... */
+ fbiinit6 = (ntiles & 0x1) << TILES_IN_X_LSB_SHIFT;
+ }
+ else
+ fbiinit1 |= ntiles << TILES_IN_X_SHIFT;
+
+ switch(par->bpp) {
+ case 16:
+ fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL;
+ break;
+#ifdef EN_24_32_BPP
+ case 24:
+ case 32:
+/* orig sst_set_bits(FBIINIT1, SEL_SOURCE_VCLK_2X_DIV2 | EN_24BPP); */
+ fbiinit1 |= SEL_SOURCE_VCLK_2X_SEL | EN_24BPP;
+ break;
+#endif
+ default:
+ dprintk("bug line %d: bad depth '%u'\n", __LINE__,
+ par->bpp );
+ return 0;
+ break;
+ }
+ sst_write(FBIINIT1, fbiinit1);
+ if (sst_info->is_voodoo2)
+ sst_write(FBIINIT6, fbiinit6);
+ sst_wait_idle();
+ sst_unset_bits(FBIINIT1, VIDEO_RESET);
+ sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+ sst_set_bits(FBIINIT2, EN_DRAM_REFRESH);
+/* disables fbiinit writes */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR);
+
+ /* set lfbmode : set mode + front buffer for reads/writes
+ + disable pipeline + disable byte swapping */
+ switch(par->bpp) {
+ case 16:
+ lfbmode = LFB_565;
+ break;
+#ifdef EN_24_32_BPP
+ case 24:
+ lfbmode = LFB_888;
+ break;
+ case 32:
+ lfbmode = LFB_8888;
+ break;
+#endif
+ default:
+ dprintk("bug line %d: bad depth '%u'\n", __LINE__,
+ par->bpp );
+ return 0;
+ break;
+ }
+
+ if (clipping) {
+ sst_write(LFBMODE, lfbmode | EN_PXL_PIPELINE);
+ /*
+ * Set "clipping" dimensions. If clipping is disabled and
+ * writes to offscreen areas of the framebuffer are performed,
+ * the "behaviour is undefined" (_very_ undefined) - Urs
+ */
+ /* btw, it requires enabling pixel pipeline in LFBMODE .
+ off screen read/writes will just wrap and read/print pixels
+ on screen. Ugly but not that dangerous */
+
+ f_ddprintk("setting clipping dimensions 0..%d, 0..%d\n",
+ par->xDim-1, par->yDim-1);
+
+/* warning the fields are 9bits wide on voodoo1 , 11 (or 10) on voodoo2,
+ make sure we check the values before playing with the registers.. */
+
+ sst_write(CLIP_LEFT_RIGHT, par->xDim );
+ sst_write(CLIP_LOWY_HIGHY, par->yDim );
+ sst_set_bits(FBZMODE, EN_CLIPPING | EN_RGB_WRITE);
+ } else {
+ /* no clipping : direct access, no pipeline */
+ sst_write(LFBMODE, lfbmode );
+ }
+
+ sst_info->current_par = *par ;
+ return 1;
+}
+
+static void sst_set_vidmod_att_ti(const int bpp)
+{
+ u8 cr0;
+
+ f_dprintk("sst_set_vidmod_att_ti(bpp: %d)\n", bpp);
+
+ sst_dac_write(DACREG_WMA, 0); /* backdoor */
+ sst_dac_read(DACREG_RMR); /* read 4 times RMR */
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ /* the fifth time, CR0 is read */
+ cr0 = sst_dac_read(DACREG_RMR);
+
+ sst_dac_write(DACREG_WMA, 0); /* backdoor */
+ sst_dac_read(DACREG_RMR); /* read 4 times RMR */
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ sst_dac_read(DACREG_RMR);
+ /* cr0 */
+ switch(bpp) {
+ case 16:
+ sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_16BPP);
+ break;
+#ifdef EN_24_32_BPP
+ case 24:
+ case 32:
+ sst_dac_write(DACREG_RMR, (cr0 & 0x0f) | DACREG_CR0_24BPP);
+ break;
+#endif
+ default:
+ dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);
+ break;
+ }
+}
+
+static void sst_set_vidmod_ics(const int bpp)
+{
+ f_dprintk("sst_set_vidmod_ics(bpp: %d)\n", bpp);
+ switch(bpp) {
+ case 16:
+ sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_16BPP);
+ break;
+#ifdef EN_24_32_BPP
+ case 24:
+ case 32:
+ sst_dac_write(DACREG_ICS_CMD, DACREG_ICS_CMD_24BPP);
+ break;
+#endif
+ default:
+ dprintk("bug line %d: bad depth '%u'\n", __LINE__, bpp);
+ break;
+ }
+}
+
+static int __init sst_init(void)
+{
+ struct pll_timing gfx_timings;
+ int Fout;
+ int dac_ok;
+ u32 fbiinit0, fbiinit1, fbiinit4;
+ struct pci_dev * sst_dev = fb_info.dev; /* or define a macro ?*/
+
+ f_dprintk("sst_init\n");
+ f_ddprintk(" fbiinit0 fbiinit1 fbiinit2 fbiinit3 fbiinit4 "
+ " fbiinit6\n");
+ f_ddprintk("%0#10x %0#10x %0#10x %0#10x %0#10x %0#10x\n",
+ sst_read(FBIINIT0), sst_read(FBIINIT1), sst_read(FBIINIT2),
+ sst_read(FBIINIT3), sst_read(FBIINIT4), sst_read(FBIINIT6));
+ /* disable video clock */
+ pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);
+
+ /* enable writing to init registers ,disable pci fifo*/
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
+ /* reset video */
+ sst_set_bits(FBIINIT1, VIDEO_RESET);
+ sst_wait_idle();
+ /* reset gfx + pci fifo */
+ sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+ sst_wait_idle();
+
+ /* unreset fifo */
+ /*sst_unset_bits(FBIINIT0, FIFO_RESET);
+ sst_wait_idle();*/
+ /* unreset FBI */
+ /*sst_unset_bits(FBIINIT0, FBI_RESET);
+ sst_wait_idle();*/
+
+ /* disable dram refresh */
+ sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
+ sst_wait_idle();
+ /* remap fbinit2/3 to dac */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ PCI_EN_INIT_WR | PCI_REMAP_DAC );
+ /* detect dac type */
+ dac_ok = sst_detect_dactype();
+ if (!dac_ok) {
+ eprintk("Unknown dac type\n");
+ return 0;
+ }
+
+ /* set graphic clock */
+ if (dac_ok) {
+ fb_info.gfx_clock = fb_info.spec->default_gfx_clock;
+ if ((gfxclk >10 ) && (gfxclk < fb_info.spec->max_gfxclk)) {
+ iprintk ("Using supplied graphic freq : %dMHz\n", gfxclk);
+ fb_info.gfx_clock = gfxclk *1000;
+ } else if (gfxclk) {
+ wprintk ("You fool, %dMhz is way out of spec! Using default\n", gfxclk);
+ }
+
+ sst_calc_pll(fb_info.gfx_clock, &Fout, &gfx_timings);
+ fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+ }
+ /* disable fbiinit remap */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ PCI_EN_INIT_WR| PCI_EN_FIFO_WR );
+ /* defaults init registers */
+ /* FbiInit0: unreset gfx, unreset fifo */
+ fbiinit0 = FBIINIT0_DEFAULT;
+ fbiinit1 = FBIINIT1_DEFAULT;
+ fbiinit4 = FBIINIT4_DEFAULT;
+ if (vgapass)
+ fbiinit0 &= ~EN_VGA_PASSTHROUGH;
+ else
+ fbiinit0 |= EN_VGA_PASSTHROUGH;
+ if (slowpci) {
+ fbiinit1 |= SLOW_PCI_WRITES;
+ fbiinit4 |= SLOW_PCI_READS;
+ } else {
+ fbiinit1 &= ~SLOW_PCI_WRITES;
+ fbiinit4 &= ~SLOW_PCI_READS;
+ }
+ sst_write(FBIINIT0, fbiinit0);
+ sst_wait_idle();
+ sst_write(FBIINIT1, fbiinit1);
+ sst_wait_idle();
+ sst_write(FBIINIT2, FBIINIT2_DEFAULT);
+ sst_wait_idle();
+ sst_write(FBIINIT3, FBIINIT3_DEFAULT);
+ sst_wait_idle();
+ sst_write(FBIINIT4, fbiinit4);
+ sst_wait_idle();
+ if (fb_info.is_voodoo2) {
+ sst_write(FBIINIT6, FBIINIT6_DEFAULT);
+ sst_wait_idle();
+ }
+
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_FIFO_WR );
+ pci_write_config_dword(sst_dev, PCI_VCLK_ENABLE, 0);
+
+ return dac_ok;
+}
+
+#ifdef MODULE
+
+static void __exit sst_shutdown(void)
+{
+ struct pll_timing gfx_timings;
+ int Fout;
+ struct pci_dev * sst_dev = fb_info.dev;
+
+ f_dprintk("sst_shutdown\n");
+ /* reset video, gfx, fifo, disable dram + remap fbiinit2/3 */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR);
+ sst_set_bits(FBIINIT1, VIDEO_RESET | EN_BLANKING);
+ sst_unset_bits(FBIINIT2, EN_DRAM_REFRESH);
+ sst_set_bits(FBIINIT0, FBI_RESET | FIFO_RESET);
+ sst_wait_idle();
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ PCI_EN_INIT_WR | PCI_REMAP_DAC );
+ /*set 20Mhz gfx clock */
+ sst_calc_pll(20000, &Fout, &gfx_timings);
+ fb_info.dac_sw->set_pll(&gfx_timings, GFX_CLOCK);
+ /* TODO maybe shutdown the dac, vrefresh and so on... */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE,
+ PCI_EN_INIT_WR);
+ sst_unset_bits(FBIINIT0, FBI_RESET | FIFO_RESET | EN_VGA_PASSTHROUGH);
+ pci_write_config_dword(sst_dev, PCI_VCLK_DISABLE,0);
+/* maybe keep fbiinit* and PCI_INIT_enable in the fb_info struct at the beginining ? */
+ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, 0);
+
+}
+#endif /* MODULE */
+
+/*
+ * Interface to the world
+ */
+
+int __init sstfb_setup(char *options)
+{
+ char *this_opt;
+
+ f_dprintk("sstfb_setup\n");
+
+ if (!options || !*options)
+ return 0;
+
+ for(this_opt = strtok(options, ","); this_opt;
+ this_opt = strtok(NULL, ",")) {
+ if (!*this_opt) continue;
+
+ f_ddprintk("option %s\n", this_opt);
+
+ if (!strcmp(this_opt, "inverse")) {
+ inverse = 1;
+ fb_invert_cmaps();
+ }
+ else if (!strcmp(this_opt, "vganopass"))
+ vgapass = 0;
+ else if (!strcmp(this_opt, "vgapass"))
+ vgapass = 1;
+ else if (!strcmp(this_opt, "clipping"))
+ clipping = 1;
+ else if (!strcmp(this_opt, "noclipping"))
+ clipping = 0;
+ else if (!strcmp(this_opt, "fastpci"))
+ slowpci = 0;
+ else if (!strcmp(this_opt, "slowpci"))
+ slowpci = 1;
+ else if (!strncmp(this_opt, "mem:",4))
+ mem=simple_strtoul (this_opt+4, NULL, 0);
+ else if (!strncmp(this_opt, "gfxclk:",7))
+ gfxclk=simple_strtoul (this_opt+7, NULL, 0);
+ else if (!strncmp(this_opt, "dev:",4))
+ dev=simple_strtoul (this_opt+4, NULL, 0);
+ else
+ mode_option=this_opt;
+ }
+ return 0;
+}
+
+int __init sstfb_init(void)
+{
+ struct pci_dev * pdev;
+ struct fb_var_screeninfo var;
+#define sst_dev (fb_info.dev)
+ f_dprintk("sstfb_init\n");
+ dprintk("Compile date: "__DATE__" "__TIME__"\n");
+
+ memset (&fb_info, 0, sizeof(fb_info));
+ pci_for_each_dev(pdev) {
+ if (pdev->vendor != PCI_VENDOR_ID_3DFX) continue;
+ if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO) {
+ fb_info.is_voodoo2=0;
+ fb_info.spec=&voodoo1_spec;
+ }
+ else if (pdev->device == PCI_DEVICE_ID_3DFX_VOODOO2) {
+ fb_info.is_voodoo2=1;
+ fb_info.spec=&voodoo2_spec;
+ }
+ else
+ continue;
+ if (dev > 0) {
+ dev--;
+ continue;
+ }
+ f_ddprintk("found device : %s\n", fb_info.spec->name);
+ fb_info.dev = pdev;
+ fb_info.mmio.base = sst_dev->resource[0].start;
+ pci_read_config_byte(sst_dev,
+ PCI_REVISION_ID, &fb_info.revision);
+
+ fb_info.mmio.vbase = (u32) ioremap_nocache(fb_info.mmio.base, 0x400000);
+ if (!fb_info.mmio.vbase) {
+ eprintk("cannot remap register area %#lx\n",
+ fb_info.mmio.base);
+ return -ENXIO;
+ }
+ fb_info.video.base = fb_info.mmio.base+0x400000;
+ fb_info.video.vbase = (u32) ioremap_nocache(fb_info.video.base,
+ 0x400000);
+ if (!fb_info.video.vbase) {
+ eprintk("cannot remap framebuffer %#lx\n",
+ fb_info.video.base);
+ iounmap((void*) fb_info.mmio.vbase);
+ return -ENXIO;
+ }
+ if(!sst_init()) {
+ eprintk("Init failed\n");
+ iounmap((void*)fb_info.mmio.vbase);
+ iounmap((void*)fb_info.video.vbase);
+ return -ENXIO;
+ }
+ sst_get_memsize(&fb_info.video.len);
+ fb_info.configured = 1;
+ strncpy(fb_info.info.modename, fb_info.spec->name, 16);
+
+ iprintk("%s with %s dac\n", fb_info.info.modename, fb_info.dac_sw->name);
+ iprintk("framebuffer at %#lx, mapped to %#lx,"
+ " size %ldMb\n",
+ fb_info.video.base, fb_info.video.vbase,
+ fb_info.video.len >> 20);
+
+ f_ddprintk("revision: %d\n", fb_info.revision);
+ f_ddprintk("regbase_virt: %#lx\n", fb_info.mmio.vbase);
+ f_ddprintk("membase_phys: %#lx\n", fb_info.video.base);
+ f_ddprintk("fbbase_virt: %#lx\n", fb_info.video.vbase);
+
+ fb_info.info.node = -1 ;
+ fb_info.info.flags = FBINFO_FLAG_DEFAULT;
+ fb_info.info.fbops = &sstfb_ops;
+ fb_info.info.disp = &disp;
+ fb_info.info.changevar = NULL;
+ fb_info.info.switch_con = &sstfbcon_switch;
+ fb_info.info.updatevar = &sstfbcon_updatevar;
+ fb_info.info.blank = &sstfbcon_blank;
+ if ( !mode_option &&
+ !fb_find_mode(&var, &fb_info.info, mode_option,
+ NULL, 0, NULL, 16)) {
+ var = sstfb_default;
+ }
+ if (sstfb_set_var(&var, -1, &fb_info.info)) {
+ eprintk("can't set supplied video mode. Using default\n");
+ var = sstfb_default;
+ if (sstfb_set_var(&var, -1, &fb_info.info)) {
+ eprintk("can't set default video mode.\n");
+ return -ENXIO;
+ }
+ }
+ /*clear fb */
+ memset_io(fb_info.video.vbase, 0, fb_info.video.len);
+ /* print some squares ... */
+ sstfb_test16(&fb_info); /* FIXME this is only for 16bpp */
+
+ /* register fb */
+ if (register_framebuffer(&fb_info.info) < 0) {
+ eprintk("can't register framebuffer.\n");
+ return -ENXIO;
+ }
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
+ GET_FB_IDX(fb_info.info.node),fb_info.info.modename);
+
+ num_sst++;
+
+ if (dev <= 0) /* we use the first card only for now (==0) */
+ return 0;
+ }
+ return -ENXIO; /* no voodoo detected */
+#undef sst_dev
+}
+
+/*
+ * console driver
+ */
+static int sstfbcon_switch(int con, struct fb_info *info)
+{
+#define sst_info ((struct sstfb_info *) info)
+ struct sstfb_par par;
+
+ f_dprintk("sstfbcon_switch(con: %d)\n",con);
+ f_ddprintk("currcon: %d\n", currcon);
+ v_dprintk("currcon: %d\n", currcon);
+
+ if (currcon >= 0) {
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap, 1,
+ sstfb_getcolreg, info);
+ }
+ currcon = con;
+ fb_display[con].var.activate = FB_ACTIVATE_NOW;
+
+ print_var(&fb_display[con].var, "&fb_display[con: %d].var",con);
+ sstfb_decode_var(&fb_display[con].var, &par, sst_info);
+ if (memcmp(&par,&(sst_info->current_par),sizeof(par))) {
+ sstfb_set_par(&par, sst_info);
+ }
+ sstfb_install_cmap(con, info);
+ return 0;
+#undef sst_info
+}
+
+static int sstfbcon_updatevar(int con, struct fb_info *info)
+{
+ f_dprintk("sstfbcon_updatevar\n");
+ return -EINVAL;
+}
+
+static void sstfbcon_blank(int blank, struct fb_info *info)
+{
+ f_dprintk("sstfbcon_blank(level %d)\n", blank);
+}
+
+
+/* print some squares on the fb (presuming 16bpp) */
+static void sstfb_test16(struct sstfb_info *sst_info)
+{
+ int i,j;
+ u_long p;
+ u_long fbbase_virt = sst_info->video.vbase;
+
+ f_dprintk("sstfb_test16\n");
+ /* rect blanc 20x100+200+0 */
+ for (i=0 ; i< 100; i++) {
+ p = fbbase_virt + 2048 *i+400;
+ for (j=0 ; j < 10 ; j++) {
+ writel( 0xffffffff, p);
+ p+=4;
+ }
+ }
+ /* rect bleu 180x200+0+0 */
+ for (i=0 ; i< 200; i++) {
+ p = fbbase_virt + 2048 *i;
+ for (j=0 ; j < 90 ; j++) {
+ writel(0x001f001f,p);
+ p+=4;
+ }
+ }
+ /* carre vert 40x40+100+0 */
+ for (i=0 ; i< 40 ; i++) {
+ p = fbbase_virt + 2048 *i + 200;
+ for (j=0; j <20;j++) {
+ writel(0x07e007e0, p);
+ p+=4;
+ }
+ }
+ /*carre rouge 40x40+100+40 */
+ for (i=0; i<40; i++) {
+ p = fbbase_virt + 2048 * (i+40) + 200;
+ for (j=0; j <20;j++) {
+ writel( 0xf800f800, p);
+ p+=4;
+ }
+ }
+}
+
+/* print some squares on the fb (24/32bpp) */
+#ifdef EN_24_32_BPP
+static void sstfb_test32(struct sstfb_info *sst_info)
+{
+ int i,j;
+ u_long p;
+ u32 fbbase_virt = sst_info->video.vbase;
+
+ f_dprintk("sstfb_test32\n");
+ /* rect blanc 20x100+200+0 */
+ for (i=0 ; i< 100; i++) {
+ p = fbbase_virt + 4096*i + 800;
+ for (j=0 ; j < 20 ; j++) {
+ writel( 0x00ffffff, p);
+ p+=4;
+ }
+ }
+ /* rect bleu 180x200+0+0 */
+ for (i=0 ; i< 200; i++) {
+ p = fbbase_virt + 4096 * i;
+ for (j=0 ; j < 180 ; j++) {
+ writel(0x000000ff,p);
+ p+=4;
+ }
+ }
+ /* carre vert 40x40+100+0 */
+ for (i=0 ; i< 40 ; i++) {
+ p = fbbase_virt + 4096 *i + 400;
+ for (j=0; j <40;j++) {
+ writel(0x0000ff00, p);
+ p+=4;
+ }
+ }
+ /*carre rouge 40x40+100+10 */
+ for (i=0; i<40; i++) {
+ p = fbbase_virt + 4096 * (i+40) + 400;
+ for (j=0; j <40;j++) {
+ writel( 0x00ff0000, p);
+ p+=4;
+ }
+ }
+}
+#endif /* EN_24_32_BPP */
+
+#ifdef MODULE
+
+int init_module(void)
+{
+ f_dprintk("init_module\n");
+ sstfb_init();
+ if (num_sst == 0 )
+ return -ENXIO;
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ f_dprintk("cleanup_module\n");
+ f_ddprintk("conf %d\n",fb_info.configured);
+
+ if (fb_info.configured) {
+ sst_shutdown();
+ iounmap((void*)fb_info.mmio.vbase);
+ iounmap((void*)fb_info.video.vbase);
+ unregister_framebuffer(&fb_info.info);
+ }
+}
+
+MODULE_AUTHOR("(c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>");
+MODULE_DESCRIPTION("FBDev driver for 3dfx Voodoo Graphics and Voodoo2 based video boards");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(mem, "i");
+MODULE_PARM_DESC(mem, "Size of frame buffer memory in MiB (1, 2, 4 Mb, default=autodetect)");
+MODULE_PARM(vgapass, "i");
+MODULE_PARM_DESC(vgapass, "Enable VGA PassThrough cable (0 or 1) (default=0)");
+MODULE_PARM(inverse, "i");
+MODULE_PARM_DESC(inverse, "Inverse colormap (0 or 1) (default=0)");
+MODULE_PARM(clipping , "i");
+MODULE_PARM_DESC(clipping, "Enable clipping (slower, safer) (0 or 1) (default=1)");
+MODULE_PARM(gfxclk , "i");
+MODULE_PARM_DESC(gfxclk, "Force graphic chip frequency in Mhz. DANGEROUS. (default=auto)");
+MODULE_PARM(slowpci, "i");
+MODULE_PARM_DESC(slowpci, "Uses slow PCI settings (0 or 1) (default=0)");
+MODULE_PARM(dev,"i");
+MODULE_PARM_DESC(dev , "Attach to device ID (0..n) (default=1st device)");
+#endif /* MODULE */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
+
+#if 0
+void Dump_regs ( void)
+{
+ struct { u32 reg ; char * reg_name;} pci_regs [] = {
+ { PCI_INIT_ENABLE, "initenable"},
+ { PCI_VCLK_ENABLE, "enable vclk"},
+ { PCI_VCLK_DISABLE, "disable vclk"},
+ };
+
+ struct { u32 reg ; char * reg_name;} sst_regs [] = {
+ {FBIINIT0,"fbiinit0"},
+ {FBIINIT1,"fbiinit1"},
+ {FBIINIT2,"fbiinit2"},
+ {FBIINIT3,"fbiinit3"},
+ {FBIINIT4,"fbiinit4"},
+ {FBIINIT5,"fbiinit5"},
+ {FBIINIT6,"fbiinit6"},
+ {FBIINIT7,"fbiinit7"},
+ {LFBMODE,"lfbmode"},
+ {FBZMODE,"fbzmode"},
+ };
+ u32 pci_res[sizeof(pci_regs)/sizeof(pci_regs[0])];
+ u32 sst_res[sizeof(sst_regs)/sizeof(sst_regs[0])];
+
+ struct pci_dev * dev = fb_info.dev;
+
+ int i;
+
+ for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+ pci_read_config_dword ( dev, pci_regs[i].reg , &pci_res[i]) ;
+ }
+ for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+ sst_res[i]=sst_read(sst_regs[i].reg);
+ }
+
+ dprintk ("Dump regs\n");
+ for (i=0; i<(sizeof(pci_regs)/sizeof(pci_regs[0])) ; i++ ) {
+ dprintk("%s = %0#10x\n", pci_regs[i].reg_name , pci_res[i]) ;
+ }
+ for (i=0; i<(sizeof(sst_regs)/sizeof(sst_regs[0])) ; i++ ) {
+ dprintk("%s = %0#10x\n", sst_regs[i].reg_name , sst_res[i]) ;
+ }
+}
+#endif
--- /dev/null
+/*
+ * linux/drivers/video/sstfb.h -- voodoo graphics frame buffer
+ *
+ * Copyright (c) 2000,2001 Ghozlane Toumi <gtoumi@messel.emse.fr>
+ *
+ * Created 28 Aug 2001 by Ghozlane Toumi
+ *
+ * $Id: sstfb.h,v 1.1.4.1 2001/08/29 01:30:38 ghoz Exp $
+ */
+
+
+#ifndef _SSTFB_H_
+#define _SSTFB_H_
+
+/*
+ *
+ * Debug Stuff
+ *
+ */
+
+#ifdef SST_DEBUG
+# define dprintk(X...) printk(KERN_DEBUG "sstfb: " X)
+#else
+# define dprintk(X...)
+# undef SST_DEBUG_REG
+# undef SST_DEBUG_FUNC
+# undef SST_DEBUG_VAR
+# undef SST_DEBUG_IOCTL
+#endif
+
+#if (SST_DEBUG_REG > 0)
+# define r_dprintk(X...) dprintk(X)
+#else
+# define r_dprintk(X...)
+#endif
+#if (SST_DEBUG_REG > 1)
+# define r_ddprintk(X...) dprintk(" " X)
+#else
+# define r_ddprintk(X...)
+#endif
+
+#if (SST_DEBUG_FUNC > 0)
+# define f_dprintk(X...) dprintk(X)
+#else
+# define f_dprintk(X...)
+#endif
+#if (SST_DEBUG_FUNC > 1)
+# define f_ddprintk(X...) dprintk(" " X)
+#else
+# define f_ddprintk(X...)
+#endif
+#if (SST_DEBUG_FUNC > 2)
+# define f_dddprintk(X...) dprintk(" " X)
+#else
+# define f_dddprintk(X...)
+#endif
+
+#if (SST_DEBUG_VAR > 0)
+# define v_dprintk(X...) dprintk(X)
+# define print_var(V, X...) \
+ { \
+ dprintk(X); \
+ printk(" :\n"); \
+ sst_dbg_print_var(V); \
+ }
+#else
+# define v_dprintk(X...)
+# define print_var(X,Y...)
+#endif
+
+#define eprintk(X...) printk(KERN_ERR "sstfb: " X)
+#define iprintk(X...) printk(KERN_INFO "sstfb: " X)
+#define wprintk(X...) printk(KERN_WARNING "sstfb: " X)
+
+#define BIT(x) (1ul << (x))
+#define PS2KHZ(a) (1000000000UL/(a)) /* picoseconds to KHz */
+#define KHZ2PS(a) (1000000000UL/(a))
+
+#ifndef ABS
+# define ABS(x) (((x)<0)?-(x):(x))
+#endif
+
+//void Dump_regs(void);
+
+/*
+ *
+ * Const
+ *
+ */
+
+/* pci stuff */
+#define PCI_INIT_ENABLE 0x40
+# define PCI_EN_INIT_WR BIT(0)
+# define PCI_EN_FIFO_WR BIT(1)
+# define PCI_REMAP_DAC BIT(2)
+#define PCI_VCLK_ENABLE 0xc0 /* enable video */
+#define PCI_VCLK_DISABLE 0xe0
+
+/* register offsets from memBaseAddr */
+#define STATUS 0x0000
+# define STATUS_FBI_BUSY BIT(7)
+#define FBZMODE 0x0110
+# define EN_CLIPPING BIT(0) /* enable clipping */
+# define EN_RGB_WRITE BIT(9) /* enable writes to rgb area */
+# define EN_ALPHA_WRITE BIT(10)
+# define ENGINE_INVERT_Y BIT(17) /* invert Y origin (pipe) */
+#define LFBMODE 0x0114
+# define LFB_565 0 /* bits 3:0 .16 bits RGB */
+# define LFB_888 4 /* 24 bits RGB */
+# define LFB_8888 5 /* 32 bits ARGB */
+# define WR_BUFF_FRONT 0 /* write buf select (front) */
+# define WR_BUFF_BACK (1 << 4) /* back */
+# define RD_BUFF_FRONT 0 /* read buff select (front) */
+# define RD_BUFF_BACK (1 << 6) /* back */
+# define EN_PXL_PIPELINE BIT(8) /* pixel pipeline (clip..)*/
+# define LFB_INVERT_Y BIT(13) /* invert Y origin (LFB) */
+#define CLIP_LEFT_RIGHT 0x0118
+#define CLIP_LOWY_HIGHY 0x011c
+#define NOPCMD 0x0120
+#define FASTFILLCMD 0x0124
+#define SWAPBUFFCMD 0x0128
+#define FBIINIT4 0x0200 /* misc controls */
+# define FAST_PCI_READS 0 /* 1 waitstate */
+# define SLOW_PCI_READS BIT(0) /* 2 ws */
+# define LFB_READ_AHEAD BIT(1)
+#define BACKPORCH 0x0208
+#define VIDEODIMENSIONS 0x020c
+#define FBIINIT0 0x0210 /* misc+fifo controls */
+# define EN_VGA_PASSTHROUGH BIT(0)
+# define FBI_RESET BIT(1)
+# define FIFO_RESET BIT(2)
+#define FBIINIT1 0x0214 /* PCI + video controls */
+# define VIDEO_MASK 0x8080010f /* masks video related bits V1+V2*/
+# define FAST_PCI_WRITES 0 /* 0 ws */
+# define SLOW_PCI_WRITES BIT(1) /* 1 ws */
+# define EN_LFB_READ BIT(3)
+# define TILES_IN_X_SHIFT 4
+# define VIDEO_RESET BIT(8)
+# define EN_BLANKING BIT(12)
+# define EN_DATA_OE BIT(13)
+# define EN_BLANK_OE BIT(14)
+# define EN_HVSYNC_OE BIT(15)
+# define EN_DCLK_OE BIT(16)
+# define SEL_INPUT_VCLK_2X 0 /* bit 17 */
+# define SEL_INPUT_VCLK_SLAVE BIT(17)
+# define SEL_SOURCE_VCLK_SLAVE 0 /* bits 21:20 */
+# define SEL_SOURCE_VCLK_2X_DIV2 (0x01 << 20)
+# define SEL_SOURCE_VCLK_2X_SEL (0x02 << 20)
+# define EN_24BPP BIT(22)
+# define TILES_IN_X_MSB_SHIFT 24 /* v2 */
+# define VCLK_2X_SEL_DEL_SHIFT 27 /* vclk out delay 0,4,6,8ns */
+# define VCLK_DEL_SHIFT 29 /* vclk in delay */
+#define FBIINIT2 0x0218 /* Dram controls */
+# define EN_FAST_RAS_READ BIT(5)
+# define EN_DRAM_OE BIT(6)
+# define EN_FAST_RD_AHEAD_WR BIT(7)
+# define VIDEO_OFFSET_SHIFT 11 /* unit: #rows tile 64x16/2 */
+# define SWAP_DACVSYNC 0
+# define SWAP_DACDATA0 (1 << 9)
+# define SWAP_FIFO_STALL (2 << 9)
+# define EN_RD_AHEAD_FIFO BIT(21)
+# define EN_DRAM_REFRESH BIT(22)
+# define DRAM_REFRESH_16 (0x30 << 23) /* dram 16 ms */
+#define DAC_READ FBIINIT2 /* in remap mode */
+#define FBIINIT3 0x021c /* fbi controls */
+# define DISABLE_TEXTURE BIT(6)
+# define Y_SWAP_ORIGIN_SHIFT 22 /* Y swap substraction value */
+#define HSYNC 0x0220
+#define VSYNC 0x0224
+#define DAC_DATA 0x022c
+# define DAC_READ_CMD BIT(11) /* set read dacreg mode */
+#define FBIINIT5 0x0244 /* v2 specific */
+#define FBIINIT6 0x0248 /* v2 specific */
+#define FBIINIT7 0x024c /* v2 specific */
+# define TILES_IN_X_LSB_SHIFT 30 /* v2 */
+
+/* Dac Registers */
+#define DACREG_WMA 0x0 /* pixel write mode address */
+#define DACREG_LUT 0x01 /* color value */
+#define DACREG_RMR 0x02 /* pixel mask */
+#define DACREG_RMA 0x03 /* pixel read mode address */
+/*Dac registers in indexed mode (TI, ATT dacs) */
+#define DACREG_ADDR_I DACREG_WMA
+#define DACREG_DATA_I DACREG_RMR
+#define DACREG_RMR_I 0x00
+#define DACREG_CR0_I 0x01
+# define DACREG_CR0_EN_INDEXED BIT(0) /* enable indexec mode */
+# define DACREG_CR0_8BIT BIT(1) /* set dac to 8 bits/read */
+# define DACREG_CR0_PWDOWN BIT(3) /* powerdown dac */
+# define DACREG_CR0_16BPP 0x30 /* mode 3 */
+# define DACREG_CR0_24BPP 0x50 /* mode 5 */
+#define DACREG_CR1_I 0x05
+#define DACREG_CC_I 0x06
+# define DACREG_CC_CLKA BIT(7) /* clk A controled by regs */
+# define DACREG_CC_CLKA_C (2<<4) /* clk A uses reg C */
+# define DACREG_CC_CLKB BIT(3) /* clk B controled by regs */
+# define DACREG_CC_CLKB_D 3 /* clkB uses reg D */
+#define DACREG_AC0_I 0x48 /* clock A reg C */
+#define DACREG_AC1_I 0x49
+#define DACREG_BD0_I 0x6c /* clock B reg D */
+#define DACREG_BD1_I 0x6d
+
+/* identification constants */
+#define DACREG_MIR_TI 0x97
+#define DACREG_DIR_TI 0x09
+#define DACREG_MIR_ATT 0x84
+#define DACREG_DIR_ATT 0x09
+/* ics dac specific registers*/
+#define DACREG_ICS_PLLWMA 0x04 /* PLL write mode address */
+#define DACREG_ICS_PLLDATA 0x05 /* PLL data /parameter */
+#define DACREG_ICS_CMD 0x06 /* command */
+# define DACREG_ICS_CMD_16BPP 0x50 /* ics color mode 6 (16bpp bypass)*/
+# define DACREG_ICS_CMD_24BPP 0x70 /* ics color mode 7 (24bpp bypass)*/
+# define DACREG_ICS_CMD_PWDOWN BIT(0) /* powerdown dac */
+#define DACREG_ICS_PLLRMA 0x07 /* PLL read mode address */
+/*
+ * pll parameter register:
+ * indexed : write addr to PLLWMA, write data in PLLDATA.
+ * for reads use PLLRMA .
+ * 8 freq registers (0-7) for video clock (CLK0)
+ * 2 freq registers (a-b) for graphic clock (CLK1)
+ */
+#define DACREG_ICS_PLL_CLK0_1_INI 0x55 /* initial pll M value for freq f1 */
+#define DACREG_ICS_PLL_CLK0_7_INI 0x71 /* f7 */
+#define DACREG_ICS_PLL_CLK1_B_INI 0x79 /* fb */
+#define DACREG_ICS_PLL_CTRL 0x0e
+# define DACREG_ICS_CLK0 BIT(5)
+# define DACREG_ICS_CLK0_0 0
+# define DACREG_ICS_CLK1_A 0 /* bit4 */
+
+/* sst default init registers */
+#define FBIINIT0_DEFAULT EN_VGA_PASSTHROUGH
+
+#define FBIINIT1_DEFAULT \
+ ( \
+ FAST_PCI_WRITES \
+/* SLOW_PCI_WRITES*/ \
+ | VIDEO_RESET \
+ | 10 << TILES_IN_X_SHIFT\
+ | SEL_SOURCE_VCLK_2X_SEL\
+ | EN_LFB_READ \
+ )
+
+#define FBIINIT2_DEFAULT \
+ ( \
+ SWAP_DACVSYNC \
+ | EN_DRAM_OE \
+ | DRAM_REFRESH_16 \
+ | EN_DRAM_REFRESH \
+ | EN_FAST_RAS_READ \
+ | EN_RD_AHEAD_FIFO \
+ | EN_FAST_RD_AHEAD_WR \
+ )
+
+#define FBIINIT3_DEFAULT \
+ ( DISABLE_TEXTURE )
+
+#define FBIINIT4_DEFAULT \
+ ( \
+ FAST_PCI_READS \
+/* SLOW_PCI_READS*/ \
+ | LFB_READ_AHEAD \
+ )
+/* Careful with this one : writing back the data just read will trash the DAC
+ reading some fields give logic value on pins, but setting this field will
+ set the source signal driving the pin. conclusion : just use the default
+ as a base before writing back .
+*/
+#define FBIINIT6_DEFAULT (0x0)
+
+/*
+ *
+ * Misc Const
+ *
+ */
+
+/* used to know witch clock to set */
+#define VID_CLOCK 0
+#define GFX_CLOCK 1
+
+/* freq max */
+#define DAC_FREF 14318 /* DAC reference freq (Khz) */
+#define VCO_MAX 260000
+
+/*
+ *
+ * Declarations
+ *
+ */
+
+struct pll_timing {
+ u8 m;
+ u8 n;
+ u8 p;
+};
+
+struct dac_switch {
+ char * name;
+ int (*detect) (void);
+ int (*set_pll) (const struct pll_timing *t, const int clock);
+ void (*set_vidmod) (const int bpp);
+};
+
+struct sst_spec {
+ char * name;
+ int default_gfx_clock; /* 50000 for voodoo1, 75000 for voodoo2 */
+ int max_gfxclk; /* ! in Mhz ie 60 for voodoo 1 */
+};
+
+struct sstfb_par {
+ unsigned int bpp;
+ unsigned int xDim; /* xres */
+ unsigned int hSyncOn; /* hsync_len */
+ unsigned int hSyncOff; /* left_margin + xres + right_margin */
+ unsigned int hBackPorch;/* left_margin */
+ unsigned int yDim;
+ unsigned int vSyncOn;
+ unsigned int vSyncOff;
+ unsigned int vBackPorch;
+ unsigned int freq; /* freq in picoseconds */
+ unsigned int tiles_in_X; /* num of tiles in X res */
+};
+
+struct sstfb_info {
+ struct fb_info info;
+ struct sstfb_par current_par;
+ struct pci_dev * dev;
+
+ struct {
+ unsigned long base; /* physical */
+ unsigned long vbase; /* virtual (CPU view) */
+ unsigned long len;
+ } video; /* fb memory info */
+ struct {
+ unsigned long base;
+ unsigned long vbase;
+ } mmio; /* registers memory info */
+
+ struct dac_switch * dac_sw; /* dac specific functions */
+ struct sst_spec * spec;
+
+ int is_voodoo2;
+ u8 revision;
+
+ /* status */
+ int configured;
+/* int indexed_mode;
+ int vgapass;
+ int clipping; */
+ int gfx_clock;
+};
+
+#endif /* _SSTFB_H_ */
--- /dev/null
+/*
+ * linux/drivers/video/tx3912fb.c
+ *
+ * Copyright (C) 1999 Harald Koerfgen
+ * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Framebuffer for LCD controller in TMPR3912/05 and PR31700 processors
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/pm.h>
+#include <linux/fb.h>
+#include <asm/bootinfo.h>
+#include <asm/uaccess.h>
+#include <video/fbcon.h>
+#include <video/fbcon-mfb.h>
+#include <video/fbcon-cfb2.h>
+#include <video/fbcon-cfb4.h>
+#include <video/fbcon-cfb8.h>
+#include "tx3912fb.h"
+
+/*
+ * Frame buffer, palette and console structures
+ */
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+static struct display global_disp;
+static int currcon = 0;
+
+/*
+ * Interface used by the world
+ */
+static int tx3912fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int tx3912fb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int tx3912fb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int tx3912fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int tx3912fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int tx3912fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
+
+/*
+ * Interface used by console driver
+ */
+int tx3912fb_init(void);
+static int tx3912fbcon_switch(int con, struct fb_info *info);
+static int tx3912fbcon_updatevar(int con, struct fb_info *info);
+static void tx3912fbcon_blank(int blank, struct fb_info *info);
+
+/*
+ * Macros
+ */
+#define get_line_length(xres_virtual, bpp) \
+ (u_long) (((int) xres_virtual * (int) bpp + 7) >> 3)
+
+/*
+ * Internal routines
+ */
+static int tx3912fb_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info);
+static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static void tx3912fb_install_cmap(int con, struct fb_info *info);
+
+
+/*
+ * Frame buffer operations structure used by console driver
+ */
+static struct fb_ops tx3912fb_ops = {
+ owner: THIS_MODULE,
+ fb_get_fix: tx3912fb_get_fix,
+ fb_get_var: tx3912fb_get_var,
+ fb_set_var: tx3912fb_set_var,
+ fb_get_cmap: tx3912fb_get_cmap,
+ fb_set_cmap: tx3912fb_set_cmap,
+ fb_ioctl: tx3912fb_ioctl,
+};
+
+
+/*
+ * Get fixed display data
+ */
+static int tx3912fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct display *display;
+
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ strcpy(fix->id, TX3912FB_NAME);
+
+ if (con == -1)
+ display = &global_disp;
+ else
+ display = &fb_display[con];
+
+ fix->smem_start = tx3912fb_vaddr;
+ fix->smem_len = tx3912fb_size;
+ fix->type = display->type;
+ fix->type_aux = display->type_aux;
+ fix->xpanstep = 0;
+ fix->ypanstep = display->ypanstep;
+ fix->ywrapstep = display->ywrapstep;
+ fix->visual = display->visual;
+ fix->line_length = display->line_length;
+ fix->accel = FB_ACCEL_NONE;
+
+ return 0;
+}
+
+/*
+ * Get user display data
+ */
+static int tx3912fb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (con == -1)
+ *var = tx3912fb_info;
+ else
+ *var = fb_display[con].var;
+
+ return 0;
+}
+
+/*
+ * Set user display data
+ */
+static int tx3912fb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ int err, activate = var->activate;
+ int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+ u_long line_length;
+ struct display *display;
+
+ if (con == -1)
+ display = &global_disp;
+ else
+ display = &fb_display[con];
+
+ /*
+ * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal
+ * as FB_VMODE_SMOOTH_XPAN is only used internally
+ */
+ if (var->vmode & FB_VMODE_CONUPDATE) {
+ var->xoffset = display->var.xoffset;
+ var->yoffset = display->var.yoffset;
+ var->vmode |= FB_VMODE_YWRAP;
+ }
+
+ /*
+ * Make sure values are in range
+ */
+ if (!var->xres)
+ var->xres = 1;
+ if (!var->yres)
+ var->yres = 1;
+ if (var->xres > var->xres_virtual)
+ var->xres_virtual = var->xres;
+ if (var->yres > var->yres_virtual)
+ var->yres_virtual = var->yres;
+ if (var->bits_per_pixel <= 1)
+ var->bits_per_pixel = 1;
+ else if (var->bits_per_pixel <= 2)
+ var->bits_per_pixel = 2;
+ else if (var->bits_per_pixel <= 4)
+ var->bits_per_pixel = 4;
+ else if (var->bits_per_pixel <= 8)
+ var->bits_per_pixel = 8;
+ else
+ return -EINVAL;
+
+ /*
+ * Memory limit
+ */
+ line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
+ if ((line_length * var->yres_virtual) > tx3912fb_size)
+ return -ENOMEM;
+
+ /*
+ * This is only for color and we only support 8-bit color
+ */
+ if (var->bits_per_pixel) {
+ /* RGB 332 */
+ var->red.offset = 5;
+ var->red.length = 3;
+ var->green.offset = 2;
+ var->green.length = 3;
+ var->blue.offset = 0;
+ var->blue.length = 2;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ }
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
+
+ /*
+ * Make changes if necessary
+ */
+ if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+
+ oldxres = display->var.xres;
+ oldyres = display->var.yres;
+ oldvxres = display->var.xres_virtual;
+ oldvyres = display->var.yres_virtual;
+ oldbpp = display->var.bits_per_pixel;
+ display->var = *var;
+
+ if (oldxres != var->xres || oldyres != var->yres ||
+ oldvxres != var->xres_virtual ||
+ oldvyres != var->yres_virtual ||
+ oldbpp != var->bits_per_pixel) {
+
+ display->screen_base = (u_char *) tx3912fb_vaddr;
+
+ switch (var->bits_per_pixel) {
+ case 1:
+ display->visual = FB_VISUAL_MONO10;
+ break;
+ case 2:
+ display->visual = FB_VISUAL_PSEUDOCOLOR;
+ case 4:
+ case 8:
+ display->visual = FB_VISUAL_TRUECOLOR;
+ break;
+ }
+
+ display->type = FB_TYPE_PACKED_PIXELS;
+ display->type_aux = 0;
+ display->ypanstep = 0;
+ display->ywrapstep = 0;
+ display->next_line =
+ display->line_length =
+ get_line_length(var->xres_virtual,
+ var->bits_per_pixel);
+ display->can_soft_blank = 0;
+ display->inverse = FB_IS_INVERSE;
+
+ switch (var->bits_per_pixel) {
+#ifdef CONFIG_FBCON_MFB
+ case 1:
+ display->dispsw = &fbcon_mfb;
+ break;
+#endif
+#ifdef CONFIG_FBCON_CFB2
+ case 2:
+ display->dispsw = &fbcon_cfb2;
+ break;
+#endif
+#ifdef CONFIG_FBCON_CFB4
+ case 4:
+ display->dispsw = &fbcon_cfb4;
+ break;
+#endif
+#ifdef CONFIG_FBCON_CFB8
+ case 8:
+ display->dispsw = &fbcon_cfb8;
+ display->dispsw_data = fbcon_cmap.cfb8;
+ break;
+#endif
+ default:
+ display->dispsw = &fbcon_dummy;
+ break;
+ }
+
+ if (fb_info.changevar)
+ (*fb_info.changevar)(con);
+ }
+
+ if (oldbpp != var->bits_per_pixel) {
+ if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+ return err;
+ tx3912fb_install_cmap(con, info);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Get the colormap
+ */
+static int tx3912fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ if (con == currcon)
+ return fb_get_cmap(cmap, kspc, tx3912fb_getcolreg, info);
+ else if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2);
+
+ return 0;
+}
+
+/*
+ * Set the Colormap
+ */
+static int tx3912fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ int err;
+
+ if (!fb_display[con].cmap.len)
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+ 1<<fb_display[con].var.bits_per_pixel, 0)))
+ return err;
+
+ if (con == currcon)
+ return fb_set_cmap(cmap, kspc, tx3912fb_setcolreg, info);
+ else
+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+
+ return 0;
+}
+
+/*
+ * Framebuffer ioctl
+ */
+static int tx3912fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+/*
+ * Initialization of the framebuffer
+ */
+int __init tx3912fb_init(void)
+{
+ /* Stop the video logic when frame completes */
+ VidCtrl1 |= ENFREEZEFRAME;
+ IntClear1 |= INT1_LCDINT;
+ while (!(IntStatus1 & INT1_LCDINT));
+
+ /* Disable the video logic */
+ VidCtrl1 &= ~(ENVID | DISPON);
+ udelay(200);
+
+ /* Set start address for DMA transfer */
+ VidCtrl3 = tx3912fb_paddr &
+ (TX3912_VIDCTRL3_VIDBANK_MASK | TX3912_VIDCTRL3_VIDBASEHI_MASK);
+
+ /* Set end address for DMA transfer */
+ VidCtrl4 = (tx3912fb_paddr + tx3912fb_size + 1) &
+ TX3912_VIDCTRL4_VIDBASELO_MASK;
+
+ /* Set the pixel depth */
+ switch (tx3912fb_info.bits_per_pixel) {
+ case 1:
+ /* Monochrome */
+ VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+ break;
+ case 4:
+ /* 4-bit gray */
+ VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+ VidCtrl1 |= TX3912_VIDCTRL1_4BIT_GRAY;
+ break;
+ case 8:
+ /* 8-bit color */
+ VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+ VidCtrl1 |= TX3912_VIDCTRL1_8BIT_COLOR;
+ break;
+ case 2:
+ default:
+ /* 2-bit gray */
+ VidCtrl1 &= ~TX3912_VIDCTRL1_BITSEL_MASK;
+ VidCtrl1 |= TX3912_VIDCTRL1_2BIT_GRAY;
+ break;
+ }
+
+ /* Unfreeze video logic and enable DF toggle */
+ VidCtrl1 &= ~(ENFREEZEFRAME | DFMODE);
+ udelay(200);
+
+ /* Clear the framebuffer */
+ memset((void *) tx3912fb_vaddr, 0xff, tx3912fb_size);
+ udelay(200);
+
+ /* Enable the video logic */
+ VidCtrl1 |= (DISPON | ENVID);
+
+ strcpy(fb_info.modename, TX3912FB_NAME);
+ fb_info.changevar = NULL;
+ fb_info.node = -1;
+ fb_info.fbops = &tx3912fb_ops;
+ fb_info.disp = &global_disp;
+ fb_info.switch_con = &tx3912fbcon_switch;
+ fb_info.updatevar = &tx3912fbcon_updatevar;
+ fb_info.blank = &tx3912fbcon_blank;
+ fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+ tx3912fb_set_var(&tx3912fb_info, -1, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0)
+ return -1;
+
+ printk (KERN_INFO "fb%d: TX3912 frame buffer using %uKB.\n",
+ GET_FB_IDX(fb_info.node), (u_int) (tx3912fb_size >> 10));
+
+ return 0;
+}
+
+/*
+ * Switch the console to be the framebuffer
+ */
+static int tx3912fbcon_switch(int con, struct fb_info *info)
+{
+ /* Save off the color map if needed */
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap, 1,
+ tx3912fb_getcolreg, info);
+
+ /* Make the switch */
+ currcon = con;
+
+ /* Install new colormap */
+ tx3912fb_install_cmap(con, info);
+
+ return 0;
+}
+
+/*
+ * Update variable structure
+ */
+static int tx3912fbcon_updatevar(int con, struct fb_info *info)
+{
+ /* Nothing */
+ return 0;
+}
+
+/*
+ * Blank the display
+ */
+static void tx3912fbcon_blank(int blank, struct fb_info *info)
+{
+ /* FIXME */
+ printk("tx3912fbcon_blank\n");
+}
+
+/*
+ * Read a single color register
+ */
+static int tx3912fb_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info)
+{
+ if (regno > 255)
+ return 1;
+
+#if FB_IS_GREY
+ {
+ u_int grey;
+
+ grey = regno * 255 / 15;
+
+#if FB_IS_INVERSE
+ grey ^= 255;
+#endif
+ grey |= grey << 8;
+ *red = grey;
+ *green = grey;
+ *blue = grey;
+ }
+#else
+ *red = (palette[regno].red<<8) | palette[regno].red;
+ *green = (palette[regno].green<<8) | palette[regno].green;
+ *blue = (palette[regno].blue<<8) | palette[regno].blue;
+#endif
+ *transp = 0;
+
+ return 0;
+}
+
+/*
+ * Set a single color register
+ */
+static int tx3912fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ if (regno > 255)
+ return 1;
+
+#ifdef FBCON_HAS_CFB8
+ if( regno < 16 )
+ fbcon_cmap.cfb8[regno] = ((red & 0xe000) >> 8)
+ | ((green & 0xe000) >> 11)
+ | ((blue & 0xc000) >> 14);
+#endif
+
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ palette[regno].red = red;
+ palette[regno].green = green;
+ palette[regno].blue = blue;
+
+ return 0;
+}
+
+/*
+ * Install the color map
+ */
+static void tx3912fb_install_cmap(int con, struct fb_info *info)
+{
+ if (con != currcon)
+ return;
+
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, 1, tx3912fb_setcolreg, info);
+ else
+ fb_set_cmap(fb_default_cmap(1 << fb_display[con].var.bits_per_pixel), 1, tx3912fb_setcolreg, info);
+}
+
+MODULE_LICENSE("GPL");
--- /dev/null
+/*
+ * linux/drivers/video/tx3912fb.h
+ *
+ * Copyright (C) 2001 Steven Hill (sjhill@realitydiluted.com)
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ * Includes for TMPR3912/05 and PR31700 LCD controller registers
+ */
+#include <asm/tx3912.h>
+
+#define VidCtrl1 REG_AT(0x028)
+#define VidCtrl2 REG_AT(0x02C)
+#define VidCtrl3 REG_AT(0x030)
+#define VidCtrl4 REG_AT(0x034)
+#define VidCtrl5 REG_AT(0x038)
+#define VidCtrl6 REG_AT(0x03C)
+#define VidCtrl7 REG_AT(0x040)
+#define VidCtrl8 REG_AT(0x044)
+#define VidCtrl9 REG_AT(0x048)
+#define VidCtrl10 REG_AT(0x04C)
+#define VidCtrl11 REG_AT(0x050)
+#define VidCtrl12 REG_AT(0x054)
+#define VidCtrl13 REG_AT(0x058)
+#define VidCtrl14 REG_AT(0x05C)
+
+/* Video Control 1 Register */
+#define LINECNT 0xffc00000
+#define LINECNT_SHIFT 22
+#define LOADDLY BIT(21)
+#define BAUDVAL (BIT(20) | BIT(19) | BIT(18) | BIT(17) | BIT(16))
+#define BAUDVAL_SHIFT 16
+#define VIDDONEVAL (BIT(15) | BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9))
+#define VIDDONEVAL_SHIFT 9
+#define ENFREEZEFRAME BIT(8)
+#define TX3912_VIDCTRL1_BITSEL_MASK 0x000000c0
+#define TX3912_VIDCTRL1_2BIT_GRAY 0x00000040
+#define TX3912_VIDCTRL1_4BIT_GRAY 0x00000080
+#define TX3912_VIDCTRL1_8BIT_COLOR 0x000000c0
+#define BITSEL_SHIFT 6
+#define DISPSPLIT BIT(5)
+#define DISP8 BIT(4)
+#define DFMODE BIT(3)
+#define INVVID BIT(2)
+#define DISPON BIT(1)
+#define ENVID BIT(0)
+
+/* Video Control 2 Register */
+#define VIDRATE_MASK 0xffc00000
+#define VIDRATE_SHIFT 22
+#define HORZVAL_MASK 0x001ff000
+#define HORZVAL_SHIFT 12
+#define LINEVAL_MASK 0x000001ff
+
+/* Video Control 3 Register */
+#define TX3912_VIDCTRL3_VIDBANK_MASK 0xfff00000
+#define TX3912_VIDCTRL3_VIDBASEHI_MASK 0x000ffff0
+
+/* Video Control 4 Register */
+#define TX3912_VIDCTRL4_VIDBASELO_MASK 0x000ffff0
+
+
+/*
+ * Begin platform specific configurations
+ */
+#if defined(CONFIG_NINO_4MB) || defined(CONFIG_NINO_8MB)
+#define FB_X_RES 240
+#define FB_Y_RES 320
+#if defined(CONFIG_FBCON_CFB4)
+#define FB_BPP 4
+#else
+#if defined(CONFIG_FBCON_CFB2)
+#define FB_BPP 2
+#else
+#define FB_BPP 1
+#endif
+#endif
+#define FB_IS_GREY 1
+#define FB_IS_INVERSE 0
+#endif
+
+#ifdef CONFIG_NINO_16MB
+#define FB_X_RES 240
+#define FB_Y_RES 320
+#define FB_BPP 8
+#define FB_IS_GREY 0
+#define FB_IS_INVERSE 0
+#endif
+
+/*
+ * Define virtual resolutions if necessary
+ */
+#ifndef FB_X_VIRTUAL_RES
+#define FB_X_VIRTUAL_RES FB_X_RES
+#endif
+#ifndef FB_Y_VIRTUAL_RES
+#define FB_Y_VIRTUAL_RES FB_Y_RES
+#endif
+
+/*
+ * Framebuffer address and size
+ */
+u_long tx3912fb_paddr = 0;
+u_long tx3912fb_vaddr = 0;
+u_long tx3912fb_size = (FB_X_RES * FB_Y_RES * FB_BPP / 8);
+
+/*
+ * Framebuffer info structure
+ */
+static struct fb_var_screeninfo tx3912fb_info = {
+ FB_X_RES, FB_Y_RES,
+ FB_X_VIRTUAL_RES, FB_Y_VIRTUAL_RES,
+ 0, 0,
+ FB_BPP, FB_IS_GREY,
+ {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0},
+ 0, FB_ACTIVATE_NOW,
+ -1, -1, 0, 20000,
+ 64, 64, 32, 32, 64, 2,
+ 0, FB_VMODE_NONINTERLACED,
+ {0,0,0,0,0,0}
+};
+
+/*
+ * Framebuffer name
+ */
+static char TX3912FB_NAME[16] = "tx3912fb";
* real memory.. Parse the same file multiple times
* to get all the info.
*/
-#define MANUF( manuf, name ) static const char __manufstr_##manuf[] __initdata = name;
+#define MANUF( manuf, name ) static char __manufstr_##manuf[] __initdata = name;
#define ENDMANUF()
-#define PRODUCT( manuf, prod, name ) static const char __prodstr_##manuf##prod[] __initdata = name;
+#define PRODUCT( manuf, prod, name ) static char __prodstr_##manuf##prod[] __initdata = name;
#include "devlist.h"
#define PRODUCT( manuf, prod, name ) { 0x##prod, 0, __prodstr_##manuf##prod },
#include "devlist.h"
-static const struct zorro_manuf_info __initdata zorro_manuf_list[] = {
+static struct zorro_manuf_info __initdata zorro_manuf_list[] = {
#define MANUF( manuf, name ) { 0x##manuf, sizeof(__prods_##manuf) / sizeof(struct zorro_prod_info), __manufstr_##manuf, __prods_##manuf },
#define ENDMANUF()
#define PRODUCT( manuf, prod, name )
EXPORT_SYMBOL(zorro_find_device);
EXPORT_SYMBOL(zorro_unused_z2ram);
+
+MODULE_LICENSE("GPL");
if (inode->u.adfs_i.stamped) {
/* convert 32-bit seconds to 40-bit centi-seconds */
low = (secs & 255) * 100;
- high = (secs / 256) * 100 + (low << 8) + 0x336e996a;
+ high = (secs / 256) * 100 + (low >> 8) + 0x336e996a;
inode->u.adfs_i.loadaddr = (high >> 24) |
(inode->u.adfs_i.loadaddr & ~0xff);
static void add_dquot_ref(struct super_block *sb, short type)
{
struct list_head *p;
- struct inode *inode;
if (!sb->dq_op)
return; /* nothing to do */
file_list_lock();
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file *filp = list_entry(p, struct file, f_list);
- if (!filp->f_dentry)
- continue;
- inode = filp->f_dentry->d_inode;
+ struct inode *inode = filp->f_dentry->d_inode;
if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
+ struct vfsmount *mnt = mntget(file->f_vfsmnt);
+ struct dentry *dentry = dget(file->f_dentry);
file_list_unlock();
sb->dq_op->initialize(inode, type);
inode->i_flags |= S_QUOTA;
+ dput(dentry);
+ mntput(mnt);
/* As we may have blocked we had better restart... */
goto restart;
}
#include <linux/kmod.h>
#endif
+int core_uses_pid;
+
static struct linux_binfmt *formats;
static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
if (argv != NULL) {
for (;;) {
char * p;
- int error;
- error = get_user(p,argv);
- if (error)
- return error;
+ if (get_user(p, argv))
+ return -EFAULT;
if (!p)
break;
argv++;
pte_t * pte;
if (page_count(page) != 1)
- printk("mem_map disagrees with %p at %08lx\n", page, address);
+ printk(KERN_ERR "mem_map disagrees with %p at %08lx\n", page, address);
pgd = pgd_offset(tsk->mm, address);
spin_lock(&tsk->mm->page_table_lock);
mmap_failed:
flush_failed:
spin_lock_irq(¤t->sigmask_lock);
- if (current->sig != oldsig)
+ if (current->sig != oldsig) {
kfree(current->sig);
- current->sig = oldsig;
+ current->sig = oldsig;
+ }
spin_unlock_irq(¤t->sigmask_lock);
return retval;
}
int do_coredump(long signr, struct pt_regs * regs)
{
struct linux_binfmt * binfmt;
- char corename[6+sizeof(current->comm)];
+ char corename[6+sizeof(current->comm)+10];
struct file * file;
struct inode * inode;
int retval = 0;
goto fail;
memcpy(corename,"core.", 5);
-#if 0
- memcpy(corename+5,current->comm,sizeof(current->comm));
-#else
corename[4] = '\0';
-#endif
+ if (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)
+ sprintf(&corename[4], ".%d", current->pid);
file = filp_open(corename, O_CREAT | 2 | O_NOFOLLOW, 0600);
if (IS_ERR(file))
goto fail;
if (file->f_op && file->f_op->release)
file->f_op->release(inode, file);
fops_put(file->f_op);
- file->f_dentry = NULL;
- file->f_vfsmnt = NULL;
if (file->f_mode & FMODE_WRITE)
put_write_access(inode);
- dput(dentry);
- if (mnt)
- mntput(mnt);
file_list_lock();
+ file->f_dentry = NULL;
+ file->f_vfsmnt = NULL;
list_del(&file->f_list);
list_add(&file->f_list, &free_list);
files_stat.nr_free_files++;
file_list_unlock();
+ dput(dentry);
+ mntput(mnt);
}
}
file_list_unlock();
}
-void file_moveto(struct file *new, struct file *old)
-{
- file_list_lock();
- list_del(&new->f_list);
- list_add(&new->f_list, &old->f_list);
- file_list_unlock();
-}
-
int fs_may_remount_ro(struct super_block *sb)
{
struct list_head *p;
file_list_lock();
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file *file = list_entry(p, struct file, f_list);
- struct inode *inode;
-
- if (!file->f_dentry)
- continue;
-
- inode = file->f_dentry->d_inode;
+ struct inode *inode = file->f_dentry->d_inode;
/* File with pending delete? */
if (inode->i_nlink == 0)
struct nlm_wait *block;
struct list_head *tmp;
+ reparent_to_init();
+ snprintf(current->comm, sizeof(current->comm),
+ "%s-reclaim",
+ host->h_name);
+
/* This one ensures that our parent doesn't terminate while the
* reclaim is in progress */
lock_kernel();
/* bitmap.c contains the code that handles the inode and block bitmaps */
-#include <linux/sched.h>
+#include <linux/fs.h>
#include <linux/minix_fs.h>
-#include <linux/stat.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
#include <linux/locks.h>
-#include <linux/quotaops.h>
#include <asm/bitops.h>
printk("trying to free block not in datazone\n");
return;
}
- bh = get_hash_table(sb->s_dev,block,BLOCK_SIZE);
- if (bh)
- clear_bit(BH_Dirty, &bh->b_state);
- brelse(bh);
zone = block - sb->u.minix_sb.s_firstdatazone + 1;
bit = zone & 8191;
zone >>= 13;
<< sb->u.minix_sb.s_log_zone_size);
}
-static struct buffer_head *V1_minix_clear_inode(struct inode *inode)
+struct minix_inode *
+minix_V1_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
{
- struct buffer_head *bh;
- struct minix_inode *raw_inode;
- int ino, block;
+ int block;
+ struct minix_sb_info *sbi = &sb->u.minix_sb;
+ struct minix_inode *p;
- ino = inode->i_ino;
- if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
- printk("Bad inode number on dev %s: %d is out of range\n",
- kdevname(inode->i_dev), ino);
+ if (!ino || ino > sbi->s_ninodes) {
+ printk("Bad inode number on dev %s: %ld is out of range\n",
+ bdevname(sb->s_dev), ino);
return NULL;
}
- block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
- inode->i_sb->u.minix_sb.s_zmap_blocks +
- (ino - 1) / MINIX_INODES_PER_BLOCK);
- bh = bread(inode->i_dev, block, BLOCK_SIZE);
- if (!bh) {
+ ino--;
+ block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
+ ino / MINIX_INODES_PER_BLOCK;
+ *bh = bread(sb->s_dev, block, BLOCK_SIZE);
+ if (!*bh) {
printk("unable to read i-node block\n");
return NULL;
}
- raw_inode = ((struct minix_inode *)bh->b_data +
- (ino - 1) % MINIX_INODES_PER_BLOCK);
- raw_inode->i_nlinks = 0;
- raw_inode->i_mode = 0;
- mark_buffer_dirty(bh);
- return bh;
+ p = (void *)(*bh)->b_data;
+ return p + ino % MINIX_INODES_PER_BLOCK;
}
-static struct buffer_head *V2_minix_clear_inode(struct inode *inode)
+struct minix2_inode *
+minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
{
- struct buffer_head *bh;
- struct minix2_inode *raw_inode;
- int ino, block;
+ int block;
+ struct minix_sb_info *sbi = &sb->u.minix_sb;
+ struct minix2_inode *p;
- ino = inode->i_ino;
- if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
- printk("Bad inode number on dev %s: %d is out of range\n",
- kdevname(inode->i_dev), ino);
+ *bh = NULL;
+ if (!ino || ino > sbi->s_ninodes) {
+ printk("Bad inode number on dev %s: %ld is out of range\n",
+ bdevname(sb->s_dev), ino);
return NULL;
}
- block = (2 + inode->i_sb->u.minix_sb.s_imap_blocks +
- inode->i_sb->u.minix_sb.s_zmap_blocks +
- (ino - 1) / MINIX2_INODES_PER_BLOCK);
- bh = bread(inode->i_dev, block, BLOCK_SIZE);
- if (!bh) {
+ ino--;
+ block = 2 + sbi->s_imap_blocks + sbi->s_zmap_blocks +
+ ino / MINIX2_INODES_PER_BLOCK;
+ *bh = bread(sb->s_dev, block, BLOCK_SIZE);
+ if (!*bh) {
printk("unable to read i-node block\n");
return NULL;
}
- raw_inode = ((struct minix2_inode *) bh->b_data +
- (ino - 1) % MINIX2_INODES_PER_BLOCK);
- raw_inode->i_nlinks = 0;
- raw_inode->i_mode = 0;
- mark_buffer_dirty(bh);
- return bh;
+ p = (void *)(*bh)->b_data;
+ return p + ino % MINIX2_INODES_PER_BLOCK;
}
/* Clear the link count and mode of a deleted inode on disk. */
static void minix_clear_inode(struct inode *inode)
{
struct buffer_head *bh;
- if (INODE_VERSION(inode) == MINIX_V1)
- bh = V1_minix_clear_inode(inode);
- else
- bh = V2_minix_clear_inode(inode);
- brelse (bh);
+ if (INODE_VERSION(inode) == MINIX_V1) {
+ struct minix_inode *raw_inode;
+ raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
+ if (raw_inode) {
+ raw_inode->i_nlinks = 0;
+ raw_inode->i_mode = 0;
+ }
+ } else {
+ struct minix2_inode *raw_inode;
+ raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
+ if (raw_inode) {
+ raw_inode->i_nlinks = 0;
+ raw_inode->i_mode = 0;
+ }
+ }
+ if (bh) {
+ mark_buffer_dirty(bh);
+ brelse (bh);
+ }
}
void minix_free_inode(struct inode * inode)
* minix directory handling functions
*/
-#include <linux/string.h>
-#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/minix_fs.h>
-#include <linux/stat.h>
+#include <linux/pagemap.h>
+
+typedef struct minix_dir_entry minix_dirent;
static int minix_readdir(struct file *, void *, filldir_t);
struct file_operations minix_dir_operations = {
read: generic_read_dir,
readdir: minix_readdir,
- fsync: file_fsync,
+ fsync: minix_sync_file,
};
-static int minix_readdir(struct file * filp,
- void * dirent, filldir_t filldir)
+static inline void dir_put_page(struct page *page)
{
- unsigned int offset;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
- struct minix_sb_info * info;
+ kunmap(page);
+ page_cache_release(page);
+}
+
+static inline unsigned long dir_pages(struct inode *inode)
+{
+ return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
+}
+
+static int dir_commit_chunk(struct page *page, unsigned from, unsigned to)
+{
+ struct inode *dir = (struct inode *)page->mapping->host;
+ int err = 0;
+ page->mapping->a_ops->commit_write(NULL, page, from, to);
+ if (IS_SYNC(dir))
+ err = waitfor_one_page(page);
+ return err;
+}
+
+static struct page * dir_get_page(struct inode *dir, unsigned long n)
+{
+ struct address_space *mapping = dir->i_mapping;
+ struct page *page = read_cache_page(mapping, n,
+ (filler_t*)mapping->a_ops->readpage, NULL);
+ if (!IS_ERR(page)) {
+ wait_on_page(page);
+ kmap(page);
+ if (!Page_Uptodate(page))
+ goto fail;
+ }
+ return page;
+
+fail:
+ dir_put_page(page);
+ return ERR_PTR(-EIO);
+}
+
+static inline void *minix_next_entry(void *de, struct minix_sb_info *sbi)
+{
+ return (void*)((char*)de + sbi->s_dirsize);
+}
+
+static int minix_readdir(struct file * filp, void * dirent, filldir_t filldir)
+{
+ unsigned long pos = filp->f_pos;
struct inode *inode = filp->f_dentry->d_inode;
+ struct super_block *sb = inode->i_sb;
+ unsigned offset = pos & ~PAGE_CACHE_MASK;
+ unsigned long n = pos >> PAGE_CACHE_SHIFT;
+ unsigned long npages = dir_pages(inode);
+ struct minix_sb_info *sbi = &sb->u.minix_sb;
+ unsigned chunk_size = sbi->s_dirsize;
+
+ pos = (pos + chunk_size-1) & ~(chunk_size-1);
+ if (pos >= inode->i_size)
+ goto done;
+
+ for ( ; n < npages; n++, offset = 0) {
+ char *p, *kaddr, *limit;
+ struct page *page = dir_get_page(inode, n);
- info = &inode->i_sb->u.minix_sb;
- if (filp->f_pos & (info->s_dirsize - 1))
- return -EBADF;
- while (filp->f_pos < inode->i_size) {
- offset = filp->f_pos & 1023;
- bh = minix_bread(inode,(filp->f_pos)>>BLOCK_SIZE_BITS,0);
- if (!bh) {
- filp->f_pos += 1024-offset;
+ if (IS_ERR(page))
continue;
- }
- do {
- de = (struct minix_dir_entry *) (offset + bh->b_data);
+ kaddr = (char *)page_address(page);
+ p = kaddr+offset;
+ limit = kaddr + PAGE_CACHE_SIZE - chunk_size;
+ for ( ; p <= limit ; p = minix_next_entry(p, sbi)) {
+ minix_dirent *de = (minix_dirent *)p;
if (de->inode) {
- int size = strnlen(de->name, info->s_namelen);
- if (filldir(dirent, de->name, size, filp->f_pos, de->inode, DT_UNKNOWN) < 0) {
- brelse(bh);
- return 0;
+ int over;
+ unsigned l = strnlen(de->name,sbi->s_namelen);
+
+ offset = p - kaddr;
+ over = filldir(dirent, de->name, l,
+ (n<<PAGE_CACHE_SHIFT) | offset,
+ de->inode, DT_UNKNOWN);
+ if (over) {
+ dir_put_page(page);
+ goto done;
}
}
- offset += info->s_dirsize;
- filp->f_pos += info->s_dirsize;
- } while (offset < 1024 && filp->f_pos < inode->i_size);
- brelse(bh);
+ }
+ dir_put_page(page);
}
+
+done:
+ filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset;
UPDATE_ATIME(inode);
return 0;
}
+
+static inline int namecompare(int len, int maxlen,
+ const char * name, const char * buffer)
+{
+ if (len < maxlen && buffer[len])
+ return 0;
+ return !memcmp(name, buffer, len);
+}
+
+/*
+ * minix_find_entry()
+ *
+ * finds an entry in the specified directory with the wanted name. It
+ * returns the cache buffer in which the entry was found, and the entry
+ * itself (as a parameter - res_dir). It does NOT read the inode of the
+ * entry - you'll have to do that yourself if you want to.
+ */
+minix_dirent *minix_find_entry(struct dentry *dentry, struct page **res_page)
+{
+ const char * name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ struct inode * dir = dentry->d_parent->d_inode;
+ struct super_block * sb = dir->i_sb;
+ struct minix_sb_info * sbi = &sb->u.minix_sb;
+ unsigned long n;
+ unsigned long npages = dir_pages(dir);
+ struct page *page = NULL;
+ struct minix_dir_entry *de;
+
+ *res_page = NULL;
+
+ for (n = 0; n < npages; n++) {
+ char *kaddr;
+ page = dir_get_page(dir, n);
+ if (IS_ERR(page))
+ continue;
+
+ kaddr = (char*)page_address(page);
+ de = (struct minix_dir_entry *) kaddr;
+ kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
+ for ( ; (char *) de <= kaddr ; de = minix_next_entry(de,sbi)) {
+ if (!de->inode)
+ continue;
+ if (namecompare(namelen,sbi->s_namelen,name,de->name))
+ goto found;
+ }
+ dir_put_page(page);
+ }
+ return NULL;
+
+found:
+ *res_page = page;
+ return de;
+}
+
+int minix_add_link(struct dentry *dentry, struct inode *inode)
+{
+ struct inode *dir = dentry->d_parent->d_inode;
+ const char * name = dentry->d_name.name;
+ int namelen = dentry->d_name.len;
+ struct super_block * sb = dir->i_sb;
+ struct minix_sb_info * sbi = &sb->u.minix_sb;
+ struct page *page = NULL;
+ struct minix_dir_entry * de;
+ unsigned long npages = dir_pages(dir);
+ unsigned long n;
+ char *kaddr;
+ unsigned from, to;
+ int err;
+
+ /* We take care of directory expansion in the same loop */
+ for (n = 0; n <= npages; n++) {
+ page = dir_get_page(dir, n);
+ err = PTR_ERR(page);
+ if (IS_ERR(page))
+ goto out;
+ kaddr = (char*)page_address(page);
+ de = (minix_dirent *)kaddr;
+ kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
+ while ((char *)de <= kaddr) {
+ if (!de->inode)
+ goto got_it;
+ err = -EEXIST;
+ if (namecompare(namelen,sbi->s_namelen,name,de->name))
+ goto out_page;
+ de = minix_next_entry(de, sbi);
+ }
+ dir_put_page(page);
+ }
+ BUG();
+ return -EINVAL;
+
+got_it:
+ from = (char*)de - (char*)page_address(page);
+ to = from + sbi->s_dirsize;
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ goto out_unlock;
+ memcpy (de->name, name, namelen);
+ memset (de->name + namelen, 0, sbi->s_dirsize - namelen - 2);
+ de->inode = inode->i_ino;
+ err = dir_commit_chunk(page, from, to);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(dir);
+out_unlock:
+ UnlockPage(page);
+out_page:
+ dir_put_page(page);
+out:
+ return err;
+}
+
+int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
+{
+ struct address_space *mapping = page->mapping;
+ struct inode *inode = (struct inode*)mapping->host;
+ char *kaddr = (char*)page_address(page);
+ unsigned from = (char*)de - kaddr;
+ unsigned to = from + inode->i_sb->u.minix_sb.s_dirsize;
+ int err;
+
+ lock_page(page);
+ err = mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ BUG();
+ de->inode = 0;
+ err = dir_commit_chunk(page, from, to);
+ UnlockPage(page);
+ dir_put_page(page);
+ inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+ mark_inode_dirty(inode);
+ return err;
+}
+
+int minix_make_empty(struct inode *inode, struct inode *dir)
+{
+ struct address_space *mapping = inode->i_mapping;
+ struct page *page = grab_cache_page(mapping, 0);
+ struct minix_sb_info * sbi = &inode->i_sb->u.minix_sb;
+ struct minix_dir_entry * de;
+ char *base;
+ int err;
+
+ if (!page)
+ return -ENOMEM;
+ err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * sbi->s_dirsize);
+ if (err)
+ goto fail;
+
+ base = (char*)page_address(page);
+ memset(base, 0, PAGE_CACHE_SIZE);
+
+ de = (struct minix_dir_entry *) base;
+ de->inode = inode->i_ino;
+ strcpy(de->name,".");
+ de = minix_next_entry(de, sbi);
+ de->inode = dir->i_ino;
+ strcpy(de->name,"..");
+
+ err = dir_commit_chunk(page, 0, 2 * sbi->s_dirsize);
+fail:
+ UnlockPage(page);
+ page_cache_release(page);
+ return err;
+}
+
+/*
+ * routine to check that the specified directory is empty (for rmdir)
+ */
+int minix_empty_dir(struct inode * inode)
+{
+ struct page *page = NULL;
+ unsigned long i, npages = dir_pages(inode);
+ struct minix_sb_info *sbi = &inode->i_sb->u.minix_sb;
+
+ for (i = 0; i < npages; i++) {
+ char *kaddr;
+ minix_dirent * de;
+ page = dir_get_page(inode, i);
+
+ if (IS_ERR(page))
+ continue;
+
+ kaddr = (char *)page_address(page);
+ de = (minix_dirent *)kaddr;
+ kaddr += PAGE_CACHE_SIZE - sbi->s_dirsize;
+
+ while ((char *)de <= kaddr) {
+ if (de->inode != 0) {
+ /* check for . and .. */
+ if (de->name[0] != '.')
+ goto not_empty;
+ if (!de->name[1]) {
+ if (de->inode != inode->i_ino)
+ goto not_empty;
+ } else if (de->name[1] != '.')
+ goto not_empty;
+ else if (de->name[2])
+ goto not_empty;
+ }
+ de = minix_next_entry(de, sbi);
+ }
+ dir_put_page(page);
+ }
+ return 1;
+
+not_empty:
+ dir_put_page(page);
+ return 0;
+}
+
+/* Releases the page */
+void minix_set_link(struct minix_dir_entry *de, struct page *page,
+ struct inode *inode)
+{
+ struct inode *dir = (struct inode*)page->mapping->host;
+ struct minix_sb_info *sbi = &dir->i_sb->u.minix_sb;
+ unsigned from = (char *)de-(char*)page_address(page);
+ unsigned to = from + sbi->s_dirsize;
+ int err;
+
+ lock_page(page);
+ err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
+ if (err)
+ BUG();
+ de->inode = inode->i_ino;
+ err = dir_commit_chunk(page, from, to);
+ UnlockPage(page);
+ dir_put_page(page);
+ dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+ mark_inode_dirty(dir);
+}
+
+struct minix_dir_entry * minix_dotdot (struct inode *dir, struct page **p)
+{
+ struct page *page = dir_get_page(dir, 0);
+ struct minix_sb_info *sbi = &dir->i_sb->u.minix_sb;
+ struct minix_dir_entry *de = NULL;
+
+ if (!IS_ERR(page)) {
+ de = minix_next_entry(page_address(page), sbi);
+ *p = page;
+ }
+ return de;
+}
+
+ino_t minix_inode_by_name(struct dentry *dentry)
+{
+ struct page *page;
+ struct minix_dir_entry *de = minix_find_entry(dentry, &page);
+ ino_t res = 0;
+
+ if (de) {
+ res = de->inode;
+ dir_put_page(page);
+ }
+ return res;
+}
* We have mostly NULLs here: the current defaults are OK for
* the minix filesystem.
*/
-static int minix_sync_file(struct file *, struct dentry *, int);
+int minix_sync_file(struct file *, struct dentry *, int);
struct file_operations minix_file_operations = {
read: generic_file_read,
truncate: minix_truncate,
};
-static int minix_sync_file(struct file * file,
- struct dentry *dentry,
- int datasync)
+int minix_sync_file(struct file * file, struct dentry *dentry, int datasync)
{
struct inode *inode = dentry->d_inode;
+ int err = fsync_inode_buffers(inode);
- if (INODE_VERSION(inode) == MINIX_V1)
- return V1_minix_sync_file(inode);
- else
- return V2_minix_sync_file(inode);
+ if (!(inode->i_state & I_DIRTY))
+ return err;
+ if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
+ return err;
+
+ err |= minix_sync_inode(inode);
+ return err ? -EIO : 0;
}
#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/minix_fs.h>
#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/stat.h>
#include <linux/locks.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/blkdev.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-
-#include <linux/minix_fs.h>
-
static void minix_read_inode(struct inode * inode);
static void minix_write_inode(struct inode * inode, int wait);
static int minix_statfs(struct super_block *sb, struct statfs *buf);
return 0;
}
-/*
- * Check the root directory of the filesystem to make sure
- * it really _is_ a Minix filesystem, and to check the size
- * of the directory entry.
- */
-static const char * minix_checkroot(struct super_block *s, struct inode *dir)
-{
- struct buffer_head *bh;
- struct minix_dir_entry *de;
- const char * errmsg;
- int dirsize;
-
- if (!S_ISDIR(dir->i_mode))
- return "root directory is not a directory";
-
- bh = minix_bread(dir, 0, 0);
- if (!bh)
- return "unable to read root directory";
-
- de = (struct minix_dir_entry *) bh->b_data;
- errmsg = "bad root directory '.' entry";
- dirsize = BLOCK_SIZE;
- if (de->inode == MINIX_ROOT_INO && strcmp(de->name, ".") == 0) {
- errmsg = "bad root directory '..' entry";
- dirsize = 8;
- }
-
- while ((dirsize <<= 1) < BLOCK_SIZE) {
- de = (struct minix_dir_entry *) (bh->b_data + dirsize);
- if (de->inode != MINIX_ROOT_INO)
- continue;
- if (strcmp(de->name, ".."))
- continue;
- s->u.minix_sb.s_dirsize = dirsize;
- s->u.minix_sb.s_namelen = dirsize - 2;
- errmsg = NULL;
- break;
- }
- brelse(bh);
- return errmsg;
-}
-
static struct super_block *minix_read_super(struct super_block *s, void *data,
int silent)
{
struct minix_super_block *ms;
int i, block;
kdev_t dev = s->s_dev;
- const char * errmsg;
struct inode *root_inode;
unsigned int hblock;
+ struct minix_sb_info *sbi = &s->u.minix_sb;
/* N.B. These should be compile-time tests.
Unfortunately that is impossible. */
goto out_bad_sb;
ms = (struct minix_super_block *) bh->b_data;
- s->u.minix_sb.s_ms = ms;
- s->u.minix_sb.s_sbh = bh;
- s->u.minix_sb.s_mount_state = ms->s_state;
+ sbi->s_ms = ms;
+ sbi->s_sbh = bh;
+ sbi->s_mount_state = ms->s_state;
s->s_blocksize = BLOCK_SIZE;
s->s_blocksize_bits = BLOCK_SIZE_BITS;
- s->u.minix_sb.s_ninodes = ms->s_ninodes;
- s->u.minix_sb.s_nzones = ms->s_nzones;
- s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
- s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
- s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
- s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
- s->u.minix_sb.s_max_size = ms->s_max_size;
+ sbi->s_ninodes = ms->s_ninodes;
+ sbi->s_nzones = ms->s_nzones;
+ sbi->s_imap_blocks = ms->s_imap_blocks;
+ sbi->s_zmap_blocks = ms->s_zmap_blocks;
+ sbi->s_firstdatazone = ms->s_firstdatazone;
+ sbi->s_log_zone_size = ms->s_log_zone_size;
+ sbi->s_max_size = ms->s_max_size;
s->s_magic = ms->s_magic;
if (s->s_magic == MINIX_SUPER_MAGIC) {
- s->u.minix_sb.s_version = MINIX_V1;
- s->u.minix_sb.s_dirsize = 16;
- s->u.minix_sb.s_namelen = 14;
- s->u.minix_sb.s_link_max = MINIX_LINK_MAX;
+ sbi->s_version = MINIX_V1;
+ sbi->s_dirsize = 16;
+ sbi->s_namelen = 14;
+ sbi->s_link_max = MINIX_LINK_MAX;
} else if (s->s_magic == MINIX_SUPER_MAGIC2) {
- s->u.minix_sb.s_version = MINIX_V1;
- s->u.minix_sb.s_dirsize = 32;
- s->u.minix_sb.s_namelen = 30;
- s->u.minix_sb.s_link_max = MINIX_LINK_MAX;
+ sbi->s_version = MINIX_V1;
+ sbi->s_dirsize = 32;
+ sbi->s_namelen = 30;
+ sbi->s_link_max = MINIX_LINK_MAX;
} else if (s->s_magic == MINIX2_SUPER_MAGIC) {
- s->u.minix_sb.s_version = MINIX_V2;
- s->u.minix_sb.s_nzones = ms->s_zones;
- s->u.minix_sb.s_dirsize = 16;
- s->u.minix_sb.s_namelen = 14;
- s->u.minix_sb.s_link_max = MINIX2_LINK_MAX;
+ sbi->s_version = MINIX_V2;
+ sbi->s_nzones = ms->s_zones;
+ sbi->s_dirsize = 16;
+ sbi->s_namelen = 14;
+ sbi->s_link_max = MINIX2_LINK_MAX;
} else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
- s->u.minix_sb.s_version = MINIX_V2;
- s->u.minix_sb.s_nzones = ms->s_zones;
- s->u.minix_sb.s_dirsize = 32;
- s->u.minix_sb.s_namelen = 30;
- s->u.minix_sb.s_link_max = MINIX2_LINK_MAX;
+ sbi->s_version = MINIX_V2;
+ sbi->s_nzones = ms->s_zones;
+ sbi->s_dirsize = 32;
+ sbi->s_namelen = 30;
+ sbi->s_link_max = MINIX2_LINK_MAX;
} else
goto out_no_fs;
/*
* Allocate the buffer map to keep the superblock small.
*/
- i = (s->u.minix_sb.s_imap_blocks + s->u.minix_sb.s_zmap_blocks) * sizeof(bh);
+ i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh);
map = kmalloc(i, GFP_KERNEL);
if (!map)
goto out_no_map;
memset(map, 0, i);
- s->u.minix_sb.s_imap = &map[0];
- s->u.minix_sb.s_zmap = &map[s->u.minix_sb.s_imap_blocks];
+ sbi->s_imap = &map[0];
+ sbi->s_zmap = &map[sbi->s_imap_blocks];
block=2;
- for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++) {
- if (!(s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)))
+ for (i=0 ; i < sbi->s_imap_blocks ; i++) {
+ if (!(sbi->s_imap[i]=bread(dev,block,BLOCK_SIZE)))
goto out_no_bitmap;
block++;
}
- for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++) {
- if (!(s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)))
+ for (i=0 ; i < sbi->s_zmap_blocks ; i++) {
+ if (!(sbi->s_zmap[i]=bread(dev,block,BLOCK_SIZE)))
goto out_no_bitmap;
block++;
}
- minix_set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
- minix_set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
+ minix_set_bit(0,sbi->s_imap[0]->b_data);
+ minix_set_bit(0,sbi->s_zmap[0]->b_data);
/* set up enough so that it can read an inode */
s->s_op = &minix_sops;
root_inode = iget(s, MINIX_ROOT_INO);
if (!root_inode)
goto out_no_root;
- /*
- * Check the fs before we get the root dentry ...
- */
- errmsg = minix_checkroot(s, root_inode);
- if (errmsg)
- goto out_bad_root;
s->s_root = d_alloc_root(root_inode);
if (!s->s_root)
goto out_iput;
- s->s_root->d_op = &minix_dentry_operations;
+ if (!NO_TRUNCATE)
+ s->s_root->d_op = &minix_dentry_operations;
if (!(s->s_flags & MS_RDONLY)) {
ms->s_state &= ~MINIX_VALID_FS;
mark_buffer_dirty(bh);
s->s_dirt = 1;
}
- if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
+ if (!(sbi->s_mount_state & MINIX_VALID_FS))
printk ("MINIX-fs: mounting unchecked file system, "
"running fsck is recommended.\n");
- else if (s->u.minix_sb.s_mount_state & MINIX_ERROR_FS)
+ else if (sbi->s_mount_state & MINIX_ERROR_FS)
printk ("MINIX-fs: mounting file system with errors, "
"running fsck is recommended.\n");
return s;
-out_bad_root:
- if (!silent)
- printk("MINIX-fs: %s\n", errmsg);
out_iput:
iput(root_inode);
goto out_freemap;
out_no_bitmap:
printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
out_freemap:
- for (i = 0; i < s->u.minix_sb.s_imap_blocks; i++)
- brelse(s->u.minix_sb.s_imap[i]);
- for (i = 0; i < s->u.minix_sb.s_zmap_blocks; i++)
- brelse(s->u.minix_sb.s_zmap[i]);
- kfree(s->u.minix_sb.s_imap);
+ for (i = 0; i < sbi->s_imap_blocks; i++)
+ brelse(sbi->s_imap[i]);
+ for (i = 0; i < sbi->s_zmap_blocks; i++)
+ brelse(sbi->s_zmap[i]);
+ kfree(sbi->s_imap);
goto out_release;
out_no_map:
return V2_minix_get_block(inode, block, bh_result, create);
}
-/*
- * the global minix fs getblk function.
- */
-struct buffer_head *minix_getblk(struct inode *inode, int block, int create)
-{
- struct buffer_head dummy;
- int error;
-
- dummy.b_state = 0;
- dummy.b_blocknr = -1000;
- error = minix_get_block(inode, block, &dummy, create);
- if (!error && buffer_mapped(&dummy)) {
- struct buffer_head *bh;
- bh = getblk(dummy.b_dev, dummy.b_blocknr, BLOCK_SIZE);
- if (buffer_new(&dummy)) {
- memset(bh->b_data, 0, BLOCK_SIZE);
- mark_buffer_uptodate(bh, 1);
- mark_buffer_dirty(bh);
- }
- return bh;
- }
- return NULL;
-}
-
-struct buffer_head * minix_bread(struct inode * inode, int block, int create)
-{
- struct buffer_head * bh;
-
- bh = minix_getblk(inode, block, create);
- if (!bh || buffer_uptodate(bh))
- return bh;
- ll_rw_block(READ, 1, &bh);
- wait_on_buffer(bh);
- if (buffer_uptodate(bh))
- return bh;
- brelse(bh);
- return NULL;
-}
-
static int minix_writepage(struct page *page)
{
return block_write_full_page(page,minix_get_block);
{
return generic_block_bmap(mapping,block,minix_get_block);
}
-struct address_space_operations minix_aops = {
+static struct address_space_operations minix_aops = {
readpage: minix_readpage,
writepage: minix_writepage,
sync_page: block_sync_page,
bmap: minix_bmap
};
+void minix_set_inode(struct inode *inode, dev_t rdev)
+{
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_op = &minix_file_inode_operations;
+ inode->i_fop = &minix_file_operations;
+ inode->i_mapping->a_ops = &minix_aops;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = &minix_dir_inode_operations;
+ inode->i_fop = &minix_dir_operations;
+ inode->i_mapping->a_ops = &minix_aops;
+ } else if (S_ISLNK(inode->i_mode)) {
+ inode->i_op = &page_symlink_inode_operations;
+ inode->i_mapping->a_ops = &minix_aops;
+ } else
+ init_special_inode(inode, inode->i_mode, rdev);
+}
+
/*
* The minix V1 function to read an inode.
*/
{
struct buffer_head * bh;
struct minix_inode * raw_inode;
- int block, ino;
-
- ino = inode->i_ino;
- inode->i_mode = 0;
- if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
- printk("Bad inode number on dev %s"
- ": %d is out of range\n",
- kdevname(inode->i_dev), ino);
- return;
- }
- block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
- inode->i_sb->u.minix_sb.s_zmap_blocks +
- (ino-1)/MINIX_INODES_PER_BLOCK;
- if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
- printk("Major problem: unable to read inode from dev "
- "%s\n", kdevname(inode->i_dev));
+ int i;
+
+ raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
+ if (!raw_inode)
return;
- }
- raw_inode = ((struct minix_inode *) bh->b_data) +
- (ino-1)%MINIX_INODES_PER_BLOCK;
inode->i_mode = raw_inode->i_mode;
inode->i_uid = (uid_t)raw_inode->i_uid;
inode->i_gid = (gid_t)raw_inode->i_gid;
inode->i_size = raw_inode->i_size;
inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
inode->i_blocks = inode->i_blksize = 0;
- for (block = 0; block < 9; block++)
- inode->u.minix_i.u.i1_data[block] = raw_inode->i_zone[block];
- if (S_ISREG(inode->i_mode)) {
- inode->i_op = &minix_file_inode_operations;
- inode->i_fop = &minix_file_operations;
- inode->i_mapping->a_ops = &minix_aops;
- } else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &minix_dir_inode_operations;
- inode->i_fop = &minix_dir_operations;
- } else if (S_ISLNK(inode->i_mode)) {
- inode->i_op = &page_symlink_inode_operations;
- inode->i_mapping->a_ops = &minix_aops;
- } else
- init_special_inode(inode, inode->i_mode, raw_inode->i_zone[0]);
+ for (i = 0; i < 9; i++)
+ inode->u.minix_i.u.i1_data[i] = raw_inode->i_zone[i];
+ minix_set_inode(inode, raw_inode->i_zone[0]);
brelse(bh);
}
{
struct buffer_head * bh;
struct minix2_inode * raw_inode;
- int block, ino;
-
- ino = inode->i_ino;
- inode->i_mode = 0;
- if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
- printk("Bad inode number on dev %s"
- ": %d is out of range\n",
- kdevname(inode->i_dev), ino);
- return;
- }
- block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
- inode->i_sb->u.minix_sb.s_zmap_blocks +
- (ino-1)/MINIX2_INODES_PER_BLOCK;
- if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
- printk("Major problem: unable to read inode from dev "
- "%s\n", kdevname(inode->i_dev));
+ int i;
+
+ raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
+ if (!raw_inode)
return;
- }
- raw_inode = ((struct minix2_inode *) bh->b_data) +
- (ino-1)%MINIX2_INODES_PER_BLOCK;
inode->i_mode = raw_inode->i_mode;
inode->i_uid = (uid_t)raw_inode->i_uid;
inode->i_gid = (gid_t)raw_inode->i_gid;
inode->i_atime = raw_inode->i_atime;
inode->i_ctime = raw_inode->i_ctime;
inode->i_blocks = inode->i_blksize = 0;
- for (block = 0; block < 10; block++)
- inode->u.minix_i.u.i2_data[block] = raw_inode->i_zone[block];
- if (S_ISREG(inode->i_mode)) {
- inode->i_op = &minix_file_inode_operations;
- inode->i_fop = &minix_file_operations;
- inode->i_mapping->a_ops = &minix_aops;
- } else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &minix_dir_inode_operations;
- inode->i_fop = &minix_dir_operations;
- } else if (S_ISLNK(inode->i_mode)) {
- inode->i_op = &page_symlink_inode_operations;
- inode->i_mapping->a_ops = &minix_aops;
- } else
- init_special_inode(inode, inode->i_mode, raw_inode->i_zone[0]);
+ for (i = 0; i < 10; i++)
+ inode->u.minix_i.u.i2_data[i] = raw_inode->i_zone[i];
+ minix_set_inode(inode, raw_inode->i_zone[0]);
brelse(bh);
}
{
struct buffer_head * bh;
struct minix_inode * raw_inode;
- int ino, block;
+ int i;
- ino = inode->i_ino;
- if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
- printk("Bad inode number on dev %s"
- ": %d is out of range\n",
- kdevname(inode->i_dev), ino);
- return 0;
- }
- block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
- (ino-1)/MINIX_INODES_PER_BLOCK;
- if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
- printk("unable to read i-node block\n");
+ raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
+ if (!raw_inode)
return 0;
- }
- raw_inode = ((struct minix_inode *)bh->b_data) +
- (ino-1)%MINIX_INODES_PER_BLOCK;
raw_inode->i_mode = inode->i_mode;
raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
raw_inode->i_time = inode->i_mtime;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
- else for (block = 0; block < 9; block++)
- raw_inode->i_zone[block] = inode->u.minix_i.u.i1_data[block];
+ else for (i = 0; i < 9; i++)
+ raw_inode->i_zone[i] = inode->u.minix_i.u.i1_data[i];
mark_buffer_dirty(bh);
return bh;
}
{
struct buffer_head * bh;
struct minix2_inode * raw_inode;
- int ino, block;
+ int i;
- ino = inode->i_ino;
- if (!ino || ino > inode->i_sb->u.minix_sb.s_ninodes) {
- printk("Bad inode number on dev %s"
- ": %d is out of range\n",
- kdevname(inode->i_dev), ino);
+ raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
+ if (!raw_inode)
return 0;
- }
- block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
- (ino-1)/MINIX2_INODES_PER_BLOCK;
- if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
- printk("unable to read i-node block\n");
- return 0;
- }
- raw_inode = ((struct minix2_inode *)bh->b_data) +
- (ino-1)%MINIX2_INODES_PER_BLOCK;
raw_inode->i_mode = inode->i_mode;
raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
raw_inode->i_ctime = inode->i_ctime;
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
- else for (block = 0; block < 10; block++)
- raw_inode->i_zone[block] = inode->u.minix_i.u.i2_data[block];
+ else for (i = 0; i < 10; i++)
+ raw_inode->i_zone[i] = inode->u.minix_i.u.i2_data[i];
mark_buffer_dirty(bh);
return bh;
}
*branch[n].p = branch[n].key;
mark_buffer_uptodate(bh, 1);
unlock_buffer(bh);
- mark_buffer_dirty(bh);
+ mark_buffer_dirty_inode(bh, inode);
parent = nr;
}
if (n == num)
/* had we spliced it onto indirect block? */
if (where->bh)
- mark_buffer_dirty(where->bh);
+ mark_buffer_dirty_inode(where->bh, inode);
mark_inode_dirty(inode);
return 0;
if (partial == chain)
mark_inode_dirty(inode);
else
- mark_buffer_dirty(partial->bh);
+ mark_buffer_dirty_inode(partial->bh, inode);
free_branches(inode, &nr, &nr+1, (chain+n-1) - partial);
}
/* Clear the ends of indirect blocks on the shared branch */
while (partial > chain) {
free_branches(inode, partial->p + 1, block_end(partial->bh),
(chain+n-1) - partial);
- mark_buffer_dirty(partial->bh);
+ mark_buffer_dirty_inode(partial->bh, inode);
brelse (partial->bh);
partial--;
}
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
mark_inode_dirty(inode);
}
-
-static int sync_block (struct inode * inode, block_t block, int wait)
-{
- struct buffer_head * bh;
-
- if (!block)
- return 0;
- bh = get_hash_table(inode->i_dev, block_to_cpu(block), BLOCK_SIZE);
- if (!bh)
- return 0;
- if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
- brelse(bh);
- return -1;
- }
- if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
- {
- brelse(bh);
- return 0;
- }
- ll_rw_block(WRITE, 1, &bh);
- atomic_dec(&bh->b_count);
- return 0;
-}
-
-static int sync_indirect(struct inode *inode, block_t iblock, int depth,
- int wait)
-{
- struct buffer_head * ind_bh = NULL;
- int rc, err = 0;
-
- if (!iblock)
- return 0;
-
- rc = sync_block (inode, iblock, wait);
- if (rc)
- return rc;
-
- ind_bh = bread(inode->i_dev, block_to_cpu(iblock), BLOCK_SIZE);
- if (!ind_bh)
- return -1;
-
- if (--depth) {
- block_t *p = (block_t*)ind_bh->b_data;
- block_t *end = block_end(ind_bh);
- while (p < end) {
- rc = sync_indirect (inode, *p++, depth, wait);
- if (rc > 0)
- break;
- if (rc)
- err = rc;
- }
- }
- brelse(ind_bh);
- return err;
-}
-
-static inline int sync_file(struct inode * inode)
-{
- int wait, err = 0, i;
- block_t *idata = i_data(inode);
-
- lock_kernel();
- err = generic_buffer_fdatasync(inode, 0, ~0UL);
- for (wait=0; wait<=1; wait++)
- for (i=1; i<DEPTH; i++)
- err |= sync_indirect(inode, idata[DIRECT+i-1], i, wait);
- err |= minix_sync_inode (inode);
- unlock_kernel();
- return (err < 0) ? -EIO : 0;
-}
-#include <linux/sched.h>
-#include <linux/locks.h>
+#include <linux/fs.h>
#include <linux/minix_fs.h>
+#include <linux/locks.h>
#include <linux/smp_lock.h>
enum {DEPTH = 3, DIRECT = 7}; /* Only double indirect */
{
truncate(inode);
}
-
-int V1_minix_sync_file(struct inode * inode)
-{
- return sync_file(inode);
-}
-#include <linux/sched.h>
-#include <linux/locks.h>
+#include <linux/fs.h>
#include <linux/minix_fs.h>
+#include <linux/locks.h>
#include <linux/smp_lock.h>
enum {DIRECT = 7, DEPTH = 4}; /* Have triple indirect */
{
truncate(inode);
}
-
-int V2_minix_sync_file(struct inode * inode)
-{
- return sync_file(inode);
-}
* Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/sched.h>
+#include <linux/fs.h>
#include <linux/minix_fs.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
-#include <linux/quotaops.h>
+#include <linux/pagemap.h>
-#include <asm/uaccess.h>
-
-/*
- * comment out this line if you want names > info->s_namelen chars to be
- * truncated. Else they will be disallowed (ENAMETOOLONG).
- */
-/* #define NO_TRUNCATE */
+static inline void inc_count(struct inode *inode)
+{
+ inode->i_nlink++;
+ mark_inode_dirty(inode);
+}
-static inline int namecompare(int len, int maxlen,
- const char * name, const char * buffer)
+static inline void dec_count(struct inode *inode)
{
- if (len < maxlen && buffer[len])
- return 0;
- return !memcmp(name, buffer, len);
+ inode->i_nlink--;
+ mark_inode_dirty(inode);
}
-/*
- * minix_find_entry()
- *
- * finds an entry in the specified directory with the wanted name. It
- * returns the cache buffer in which the entry was found, and the entry
- * itself (as a parameter - res_dir). It does NOT read the inode of the
- * entry - you'll have to do that yourself if you want to.
- */
-static struct buffer_head * minix_find_entry(struct inode * dir,
- const char * name, int namelen, struct minix_dir_entry ** res_dir)
+static int add_nondir(struct dentry *dentry, struct inode *inode)
{
- unsigned long block, offset;
- struct buffer_head * bh;
- struct minix_sb_info * info;
- struct minix_dir_entry *de;
-
- *res_dir = NULL;
- info = &dir->i_sb->u.minix_sb;
- if (namelen > info->s_namelen) {
-#ifdef NO_TRUNCATE
- return NULL;
-#else
- namelen = info->s_namelen;
-#endif
- }
- bh = NULL;
- block = offset = 0;
- while (block*BLOCK_SIZE+offset < dir->i_size) {
- if (!bh) {
- bh = minix_bread(dir,block,0);
- if (!bh) {
- block++;
- continue;
- }
- }
- de = (struct minix_dir_entry *) (bh->b_data + offset);
- offset += info->s_dirsize;
- if (de->inode && namecompare(namelen,info->s_namelen,name,de->name)) {
- *res_dir = de;
- return bh;
- }
- if (offset < bh->b_size)
- continue;
- brelse(bh);
- bh = NULL;
- offset = 0;
- block++;
+ int err = minix_add_link(dentry, inode);
+ if (!err) {
+ d_instantiate(dentry, inode);
+ return 0;
}
- brelse(bh);
- return NULL;
+ dec_count(inode);
+ iput(inode);
+ return err;
}
-#ifndef NO_TRUNCATE
-
static int minix_hash(struct dentry *dentry, struct qstr *qstr)
{
unsigned long hash;
return 0;
}
-#endif
-
struct dentry_operations minix_dentry_operations = {
-#ifndef NO_TRUNCATE
d_hash: minix_hash,
-#endif
};
static struct dentry *minix_lookup(struct inode * dir, struct dentry *dentry)
{
struct inode * inode = NULL;
- struct minix_dir_entry * de;
- struct buffer_head * bh;
-
-#ifndef NO_TRUNCATE
- dentry->d_op = &minix_dentry_operations;
-#endif
- bh = minix_find_entry(dir, dentry->d_name.name, dentry->d_name.len, &de);
- if (bh) {
- int ino = de->inode;
- brelse (bh);
+ ino_t ino;
+
+ dentry->d_op = dir->i_sb->s_root->d_op;
+
+ if (dentry->d_name.len > dir->i_sb->u.minix_sb.s_namelen)
+ return ERR_PTR(-ENAMETOOLONG);
+
+ ino = minix_inode_by_name(dentry);
+ if (ino) {
inode = iget(dir->i_sb, ino);
if (!inode)
return NULL;
}
-/*
- * minix_add_entry()
- *
- * adds a file entry to the specified directory, returning a possible
- * error value if it fails.
- *
- * NOTE!! The inode part of 'de' is left at 0 - which means you
- * may not sleep between calling this and putting something into
- * the entry, as someone else might have used it while you slept.
- */
-static int minix_add_entry(struct inode * dir,
- const char * name, int namelen,
- struct buffer_head ** res_buf,
- struct minix_dir_entry ** res_dir)
-{
- int i;
- unsigned long block, offset;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
- struct minix_sb_info * info;
-
- *res_buf = NULL;
- *res_dir = NULL;
- info = &dir->i_sb->u.minix_sb;
- if (namelen > info->s_namelen) {
-#ifdef NO_TRUNCATE
- return -ENAMETOOLONG;
-#else
- namelen = info->s_namelen;
-#endif
- }
- if (!namelen)
- return -ENOENT;
- bh = NULL;
- block = offset = 0;
- while (1) {
- if (!bh) {
- bh = minix_bread(dir,block,1);
- if (!bh)
- return -ENOSPC;
- }
- de = (struct minix_dir_entry *) (bh->b_data + offset);
- offset += info->s_dirsize;
- if (block*bh->b_size + offset > dir->i_size) {
- de->inode = 0;
- dir->i_size = block*bh->b_size + offset;
- mark_inode_dirty(dir);
- }
- if (!de->inode) {
- dir->i_mtime = dir->i_ctime = CURRENT_TIME;
- mark_inode_dirty(dir);
- for (i = 0; i < info->s_namelen ; i++)
- de->name[i] = (i < namelen) ? name[i] : 0;
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- *res_dir = de;
- break;
- }
- if (offset < bh->b_size)
- continue;
- brelse(bh);
- bh = NULL;
- offset = 0;
- block++;
- }
- *res_buf = bh;
- return 0;
-}
-
-static int minix_create(struct inode * dir, struct dentry *dentry, int mode)
+static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
{
int error;
- struct inode * inode;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
+ struct inode * inode = minix_new_inode(dir, &error);
- inode = minix_new_inode(dir, &error);
- if (!inode)
- return error;
- inode->i_op = &minix_file_inode_operations;
- inode->i_fop = &minix_file_operations;
- inode->i_mapping->a_ops = &minix_aops;
- inode->i_mode = mode;
- mark_inode_dirty(inode);
- error = minix_add_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &bh ,&de);
- if (error) {
- inode->i_nlink--;
+ if (inode) {
+ inode->i_mode = mode;
+ minix_set_inode(inode, rdev);
mark_inode_dirty(inode);
- iput(inode);
- return error;
+ error = add_nondir(dentry, inode);
}
- de->inode = inode->i_ino;
- mark_buffer_dirty(bh);
- brelse(bh);
- d_instantiate(dentry, inode);
- return 0;
+ return error;
}
-static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
+static int minix_create(struct inode * dir, struct dentry *dentry, int mode)
{
- int error;
- struct inode * inode;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
-
- inode = minix_new_inode(dir, &error);
- if (!inode)
- return error;
- inode->i_uid = current->fsuid;
- init_special_inode(inode, mode, rdev);
- mark_inode_dirty(inode);
- error = minix_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de);
- if (error) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput(inode);
- return error;
- }
- de->inode = inode->i_ino;
- mark_buffer_dirty(bh);
- brelse(bh);
- d_instantiate(dentry, inode);
- return 0;
+ return minix_mknod(dir, dentry, mode, 0);
}
-static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
+static int minix_symlink(struct inode * dir, struct dentry *dentry,
+ const char * symname)
{
- int error;
+ int err = -ENAMETOOLONG;
+ int i = strlen(symname)+1;
struct inode * inode;
- struct buffer_head * bh, *dir_block;
- struct minix_dir_entry * de;
- struct minix_sb_info * info;
- info = &dir->i_sb->u.minix_sb;
- if (dir->i_nlink >= info->s_link_max)
- return -EMLINK;
- inode = minix_new_inode(dir, &error);
+ if (i > dir->i_sb->s_blocksize)
+ goto out;
+
+ inode = minix_new_inode(dir, &err);
if (!inode)
- return error;
- inode->i_op = &minix_dir_inode_operations;
- inode->i_fop = &minix_dir_operations;
- inode->i_size = 2 * info->s_dirsize;
- dir_block = minix_bread(inode,0,1);
- if (!dir_block) {
- inode->i_nlink--;
- mark_inode_dirty(inode);
- iput(inode);
- return -ENOSPC;
- }
- de = (struct minix_dir_entry *) dir_block->b_data;
- de->inode=inode->i_ino;
- strcpy(de->name,".");
- de = (struct minix_dir_entry *) (dir_block->b_data + info->s_dirsize);
- de->inode = dir->i_ino;
- strcpy(de->name,"..");
- inode->i_nlink = 2;
- mark_buffer_dirty(dir_block);
- brelse(dir_block);
- inode->i_mode = S_IFDIR | mode;
- if (dir->i_mode & S_ISGID)
- inode->i_mode |= S_ISGID;
- mark_inode_dirty(inode);
- error = minix_add_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &bh, &de);
- if (error) {
- inode->i_nlink=0;
- iput(inode);
- return error;
- }
- de->inode = inode->i_ino;
- mark_buffer_dirty(bh);
- dir->i_nlink++;
- mark_inode_dirty(dir);
- brelse(bh);
- d_instantiate(dentry, inode);
- return 0;
-}
+ goto out;
-/*
- * routine to check that the specified directory is empty (for rmdir)
- */
-static int empty_dir(struct inode * inode)
-{
- unsigned int block, offset;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
- struct minix_sb_info * info;
-
- info = &inode->i_sb->u.minix_sb;
- block = 0;
- bh = NULL;
- offset = 2*info->s_dirsize;
- if (inode->i_size & (info->s_dirsize-1))
- goto bad_dir;
- if (inode->i_size < offset)
- goto bad_dir;
- bh = minix_bread(inode,0,0);
- if (!bh)
- goto bad_dir;
- de = (struct minix_dir_entry *) bh->b_data;
- if (!de->inode || strcmp(de->name,"."))
- goto bad_dir;
- de = (struct minix_dir_entry *) (bh->b_data + info->s_dirsize);
- if (!de->inode || strcmp(de->name,".."))
- goto bad_dir;
- while (block*BLOCK_SIZE+offset < inode->i_size) {
- if (!bh) {
- bh = minix_bread(inode,block,0);
- if (!bh) {
- block++;
- continue;
- }
- }
- de = (struct minix_dir_entry *) (bh->b_data + offset);
- offset += info->s_dirsize;
- if (de->inode) {
- brelse(bh);
- return 0;
- }
- if (offset < bh->b_size)
- continue;
- brelse(bh);
- bh = NULL;
- offset = 0;
- block++;
- }
- brelse(bh);
- return 1;
-bad_dir:
- brelse(bh);
- printk("Bad directory on device %s\n",
- kdevname(inode->i_dev));
- return 1;
-}
+ inode->i_mode = S_IFLNK | 0777;
+ minix_set_inode(inode, 0);
+ err = block_symlink(inode, symname, i);
+ if (err)
+ goto out_fail;
-static int minix_rmdir(struct inode * dir, struct dentry *dentry)
-{
- int retval;
- struct inode * inode;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
+ err = add_nondir(dentry, inode);
+out:
+ return err;
- inode = NULL;
- bh = minix_find_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &de);
- retval = -ENOENT;
- if (!bh)
- goto end_rmdir;
- inode = dentry->d_inode;
-
- if (!empty_dir(inode)) {
- retval = -ENOTEMPTY;
- goto end_rmdir;
- }
- if (de->inode != inode->i_ino) {
- retval = -ENOENT;
- goto end_rmdir;
- }
- if (inode->i_nlink != 2)
- printk("empty directory has nlink!=2 (%d)\n",inode->i_nlink);
- de->inode = 0;
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- inode->i_nlink=0;
- mark_inode_dirty(inode);
- inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- dir->i_nlink--;
- mark_inode_dirty(dir);
- retval = 0;
-end_rmdir:
- brelse(bh);
- return retval;
+out_fail:
+ dec_count(inode);
+ iput(inode);
+ goto out;
}
-static int minix_unlink(struct inode * dir, struct dentry *dentry)
+static int minix_link(struct dentry * old_dentry, struct inode * dir,
+ struct dentry *dentry)
{
- int retval;
- struct inode * inode;
- struct buffer_head * bh;
- struct minix_dir_entry * de;
+ struct inode *inode = old_dentry->d_inode;
- retval = -ENOENT;
- inode = dentry->d_inode;
- bh = minix_find_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &de);
- if (!bh || de->inode != inode->i_ino)
- goto end_unlink;
- if (!inode->i_nlink) {
- printk("Deleting nonexistent file (%s:%lu), %d\n",
- kdevname(inode->i_dev),
- inode->i_ino, inode->i_nlink);
- inode->i_nlink=1;
- }
- de->inode = 0;
- dir->i_version = ++event;
- mark_buffer_dirty(bh);
- dir->i_ctime = dir->i_mtime = CURRENT_TIME;
- mark_inode_dirty(dir);
- inode->i_nlink--;
- inode->i_ctime = dir->i_ctime;
- mark_inode_dirty(inode);
- retval = 0;
-end_unlink:
- brelse(bh);
- return retval;
+ if (S_ISDIR(inode->i_mode))
+ return -EPERM;
+
+ if (inode->i_nlink >= inode->i_sb->u.minix_sb.s_link_max)
+ return -EMLINK;
+
+ inode->i_ctime = CURRENT_TIME;
+ inc_count(inode);
+ atomic_inc(&inode->i_count);
+ return add_nondir(dentry, inode);
}
-static int minix_symlink(struct inode * dir, struct dentry *dentry,
- const char * symname)
+static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
{
- struct minix_dir_entry * de;
- struct inode * inode = NULL;
- struct buffer_head * bh = NULL;
- int i;
- int err;
+ struct inode * inode;
+ int err = -EMLINK;
- err = -ENAMETOOLONG;
- i = strlen(symname)+1;
- if (i>1024)
+ if (dir->i_nlink >= dir->i_sb->u.minix_sb.s_link_max)
goto out;
+
+ inc_count(dir);
+
inode = minix_new_inode(dir, &err);
if (!inode)
- goto out;
+ goto out_dir;
- inode->i_mode = S_IFLNK | 0777;
- inode->i_op = &page_symlink_inode_operations;
- inode->i_mapping->a_ops = &minix_aops;
- err = block_symlink(inode, symname, i);
+ inode->i_mode = S_IFDIR | mode;
+ if (dir->i_mode & S_ISGID)
+ inode->i_mode |= S_ISGID;
+ minix_set_inode(inode, 0);
+
+ inc_count(inode);
+
+ err = minix_make_empty(inode, dir);
if (err)
- goto fail;
+ goto out_fail;
- err = minix_add_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &bh, &de);
+ err = minix_add_link(dentry, inode);
if (err)
- goto fail;
+ goto out_fail;
- de->inode = inode->i_ino;
- mark_buffer_dirty(bh);
- brelse(bh);
d_instantiate(dentry, inode);
out:
return err;
-fail:
- inode->i_nlink--;
- mark_inode_dirty(inode);
+
+out_fail:
+ dec_count(inode);
+ dec_count(inode);
iput(inode);
+out_dir:
+ dec_count(dir);
goto out;
}
-static int minix_link(struct dentry * old_dentry, struct inode * dir,
- struct dentry *dentry)
+static int minix_unlink(struct inode * dir, struct dentry *dentry)
{
- int error;
- struct inode *inode = old_dentry->d_inode;
+ int err = -ENOENT;
+ struct inode * inode = dentry->d_inode;
+ struct page * page;
struct minix_dir_entry * de;
- struct buffer_head * bh;
- if (S_ISDIR(inode->i_mode))
- return -EPERM;
+ de = minix_find_entry(dentry, &page);
+ if (!de)
+ goto end_unlink;
- if (inode->i_nlink >= inode->i_sb->u.minix_sb.s_link_max)
- return -EMLINK;
+ err = minix_delete_entry(de, page);
+ if (err)
+ goto end_unlink;
- error = minix_add_entry(dir, dentry->d_name.name,
- dentry->d_name.len, &bh, &de);
- if (error) {
- brelse(bh);
- return error;
- }
- de->inode = inode->i_ino;
- mark_buffer_dirty(bh);
- brelse(bh);
- inode->i_nlink++;
- inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(inode);
- atomic_inc(&inode->i_count);
- d_instantiate(dentry, inode);
- return 0;
+ inode->i_ctime = dir->i_ctime;
+ dec_count(inode);
+end_unlink:
+ return err;
}
-#define PARENT_INO(buffer) \
-(((struct minix_dir_entry *) ((buffer)+info->s_dirsize))->inode)
+static int minix_rmdir(struct inode * dir, struct dentry *dentry)
+{
+ struct inode * inode = dentry->d_inode;
+ int err = -ENOTEMPTY;
+
+ if (minix_empty_dir(inode)) {
+ err = minix_unlink(dir, dentry);
+ if (!err) {
+ dec_count(dir);
+ dec_count(inode);
+ }
+ }
+ return err;
+}
-/*
- * Anybody can rename anything with this: the permission checks are left to the
- * higher-level routines.
- */
static int minix_rename(struct inode * old_dir, struct dentry *old_dentry,
struct inode * new_dir, struct dentry *new_dentry)
{
- struct inode * old_inode, * new_inode;
- struct buffer_head * old_bh, * new_bh, * dir_bh;
- struct minix_dir_entry * old_de, * new_de;
- struct minix_sb_info * info;
- int retval;
-
- info = &old_dir->i_sb->u.minix_sb;
- new_bh = dir_bh = NULL;
- old_inode = old_dentry->d_inode;
- new_inode = new_dentry->d_inode;
- old_bh = minix_find_entry(old_dir, old_dentry->d_name.name,
- old_dentry->d_name.len, &old_de);
- retval = -ENOENT;
- if (!old_bh || old_de->inode != old_inode->i_ino)
- goto end_rename;
- retval = -EPERM;
- new_bh = minix_find_entry(new_dir, new_dentry->d_name.name,
- new_dentry->d_name.len, &new_de);
- if (new_bh) {
- if (!new_inode) {
- brelse(new_bh);
- new_bh = NULL;
- }
- }
+ struct minix_sb_info * info = &old_dir->i_sb->u.minix_sb;
+ struct inode * old_inode = old_dentry->d_inode;
+ struct inode * new_inode = new_dentry->d_inode;
+ struct page * dir_page = NULL;
+ struct minix_dir_entry * dir_de = NULL;
+ struct page * old_page;
+ struct minix_dir_entry * old_de;
+ int err = -ENOENT;
+
+ old_de = minix_find_entry(old_dentry, &old_page);
+ if (!old_de)
+ goto out;
+
if (S_ISDIR(old_inode->i_mode)) {
- if (new_inode) {
- retval = -ENOTEMPTY;
- if (!empty_dir(new_inode))
- goto end_rename;
- }
- retval = -EIO;
- dir_bh = minix_bread(old_inode,0,0);
- if (!dir_bh)
- goto end_rename;
- if (PARENT_INO(dir_bh->b_data) != old_dir->i_ino)
- goto end_rename;
- retval = -EMLINK;
- if (!new_inode && new_dir != old_dir &&
- new_dir->i_nlink >= info->s_link_max)
- goto end_rename;
- }
- if (!new_bh) {
- retval = minix_add_entry(new_dir,
- new_dentry->d_name.name,
- new_dentry->d_name.len,
- &new_bh, &new_de);
- if (retval)
- goto end_rename;
+ err = -EIO;
+ dir_de = minix_dotdot(old_inode, &dir_page);
+ if (!dir_de)
+ goto out_old;
}
-/* ok, that's it */
- new_de->inode = old_inode->i_ino;
- old_de->inode = 0;
- old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
- old_dir->i_version = ++event;
- mark_inode_dirty(old_dir);
- new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
- new_dir->i_version = ++event;
- mark_inode_dirty(new_dir);
+
if (new_inode) {
- new_inode->i_nlink--;
+ struct page * new_page;
+ struct minix_dir_entry * new_de;
+
+ err = -ENOTEMPTY;
+ if (dir_de && !minix_empty_dir(new_inode))
+ goto out_dir;
+
+ err = -ENOENT;
+ new_de = minix_find_entry(new_dentry, &new_page);
+ if (!new_de)
+ goto out_dir;
+ inc_count(old_inode);
+ minix_set_link(new_de, new_page, old_inode);
new_inode->i_ctime = CURRENT_TIME;
- mark_inode_dirty(new_inode);
- }
- mark_buffer_dirty(old_bh);
- mark_buffer_dirty(new_bh);
- if (dir_bh) {
- PARENT_INO(dir_bh->b_data) = new_dir->i_ino;
- mark_buffer_dirty(dir_bh);
- old_dir->i_nlink--;
- mark_inode_dirty(old_dir);
- if (new_inode) {
+ if (dir_de)
new_inode->i_nlink--;
- mark_inode_dirty(new_inode);
- } else {
- new_dir->i_nlink++;
- mark_inode_dirty(new_dir);
+ dec_count(new_inode);
+ } else {
+ if (dir_de) {
+ err = -EMLINK;
+ if (new_dir->i_nlink >= info->s_link_max)
+ goto out_dir;
+ }
+ inc_count(old_inode);
+ err = minix_add_link(new_dentry, old_inode);
+ if (err) {
+ dec_count(old_inode);
+ goto out_dir;
}
+ if (dir_de)
+ inc_count(new_dir);
+ }
+
+ minix_delete_entry(old_de, old_page);
+ dec_count(old_inode);
+
+ if (dir_de) {
+ minix_set_link(dir_de, dir_page, new_dir);
+ dec_count(old_dir);
}
- retval = 0;
-end_rename:
- brelse(dir_bh);
- brelse(old_bh);
- brelse(new_bh);
- return retval;
+ return 0;
+
+out_dir:
+ if (dir_de) {
+ kunmap(dir_page);
+ page_cache_release(dir_page);
+ }
+out_old:
+ kunmap(old_page);
+ page_cache_release(old_page);
+out:
+ return err;
}
/*
*/
static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{
- kmap(page);
return nfs_flush_incompatible(file, page);
}
+
static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
{
long status;
loff_t pos = ((loff_t)page->index<<PAGE_CACHE_SHIFT) + to;
struct inode *inode = page->mapping->host;
- kunmap(page);
lock_kernel();
status = nfs_updatepage(file, page, offset, to-offset);
unlock_kernel();
if ((fattr->mode & S_IFMT) != (inode->i_mode & S_IFMT))
return 1;
- if (is_bad_inode(inode))
+ if (is_bad_inode(inode) || NFS_STALE(inode))
return 1;
/* Has the filehandle changed? If so is the old one stale? */
int
__nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
{
- int status = 0;
+ int status = -ESTALE;
struct nfs_fattr fattr;
dfprintk(PAGECACHE, "NFS: revalidating (%x/%Ld)\n",
inode->i_dev, (long long)NFS_FILEID(inode));
lock_kernel();
- if (!inode || is_bad_inode(inode) || NFS_STALE(inode)) {
- unlock_kernel();
- return -ESTALE;
- }
+ if (!inode || is_bad_inode(inode))
+ goto out_nowait;
+ if (NFS_STALE(inode) && inode != inode->i_sb->s_root->d_inode)
+ goto out_nowait;
while (NFS_REVALIDATING(inode)) {
status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING);
- if (status < 0) {
- unlock_kernel();
- return status;
- }
+ if (status < 0)
+ goto out_nowait;
if (time_before(jiffies,NFS_READTIME(inode)+NFS_ATTRTIMEO(inode))) {
status = NFS_STALE(inode) ? -ESTALE : 0;
goto out_nowait;
inode->i_dev, (long long)NFS_FILEID(inode), status);
if (status == -ESTALE) {
NFS_FLAGS(inode) |= NFS_INO_STALE;
- remove_inode_hash(inode);
+ if (inode != inode->i_sb->s_root->d_inode)
+ remove_inode_hash(inode);
}
goto out;
}
}
dfprintk(PAGECACHE, "NFS: (%x/%Ld) revalidation complete\n",
inode->i_dev, (long long)NFS_FILEID(inode));
+
+ NFS_FLAGS(inode) &= ~NFS_INO_STALE;
out:
NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING;
wake_up(&inode->i_wait);
return len;
}
+
+
+/* mangling borrowed from fs/super.c */
+/* Use octal escapes, like mount does, for embedded spaces etc. */
+static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
+
+static int
+mangle(const unsigned char *s, char *buf, int len) {
+ char *sp;
+ int n;
+
+ sp = buf;
+ while(*s && sp-buf < len-3) {
+ for (n = 0; n < sizeof(need_escaping); n++) {
+ if (*s == need_escaping[n]) {
+ *sp++ = '\\';
+ *sp++ = '0' + ((*s & 0300) >> 6);
+ *sp++ = '0' + ((*s & 070) >> 3);
+ *sp++ = '0' + (*s & 07);
+ goto next;
+ }
+ }
+ *sp++ = *s;
+ next:
+ s++;
+ }
+ return sp - buf; /* no trailing NUL */
+}
+
+#define FREEROOM ((int)PAGE_SIZE-200-len)
+#define MANGLE(s) len += mangle((s), buffer+len, FREEROOM);
+
int
exp_procfs_exports(char *buffer, char **start, off_t offset,
int length, int *eof, void *data)
int len = 0;
int i,j;
- len += sprintf(buffer, "# Version 1.0\n");
+ len += sprintf(buffer, "# Version 1.1\n");
len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n");
for (clp = clients; clp; clp = clp->cl_next) {
exp = clp->cl_export[i];
while (exp) {
int first = 0;
- len += sprintf(buffer+len, "%s\t", exp->ex_path);
- len += sprintf(buffer+len, "%s", clp->cl_ident);
- len += sprintf(buffer+len, "(");
+ MANGLE(exp->ex_path);
+ buffer[len++]='\t';
+ MANGLE(clp->cl_ident);
+ buffer[len++]='(';
len += exp_flags(buffer+len, exp->ex_flags);
len += sprintf(buffer+len, ") # ");
d_drop(tdentry); /* we never want ".." hashed */
if (!pdentry && tdentry->d_inode == NULL) {
/* File system cannot find ".." ... sad but possible */
- dput(tdentry);
pdentry = ERR_PTR(-EINVAL);
}
if (!pdentry) {
* before the fh goes out on the wire ...
*/
inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
- __u32 **datapp, int maxsize)
+ __u32 *datap, int *maxsize)
{
- __u32 *datap= *datapp;
struct super_block *sb = dentry->d_inode->i_sb;
if (dentry == exp->ex_dentry)
int need_parent = !S_ISDIR(dentry->d_inode->i_mode) &&
!(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
- int type = sb->s_op->dentry_to_fh(dentry, datap, &maxsize, need_parent);
- datap += maxsize;
- *datapp = datap;
+ int type = sb->s_op->dentry_to_fh(dentry, datap, maxsize, need_parent);
return type;
}
-
+
+ if (*maxsize < 2)
+ return 255;
*datap++ = ino_t_to_u32(dentry->d_inode->i_ino);
*datap++ = dentry->d_inode->i_generation;
- if (S_ISDIR(dentry->d_inode->i_mode) || (exp->ex_flags & NFSEXP_NOSUBTREECHECK)){
- *datapp = datap;
+ if (*maxsize ==2 ||
+ S_ISDIR(dentry->d_inode->i_mode) ||
+ (exp->ex_flags & NFSEXP_NOSUBTREECHECK)) {
+ *maxsize = 2;
return 1;
}
*datap++ = ino_t_to_u32(dentry->d_parent->d_inode->i_ino);
- *datapp = datap;
+ *maxsize = 3;
return 2;
}
/* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
*datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev));
*datap++ = ino_t_to_u32(exp->ex_ino);
- if (inode)
+ fhp->fh_handle.fh_size = 3*4;
+ if (inode) {
+ int size = fhp->fh_maxsize/4 - 3;
fhp->fh_handle.fh_fileid_type =
- _fh_update(dentry, exp, &datap, fhp->fh_maxsize-3);
- fhp->fh_handle.fh_size = (datap-fhp->fh_handle.fh_auth+1)*4;
+ _fh_update(dentry, exp, datap, &size);
+ fhp->fh_handle.fh_size += size*4;
+ }
}
nfsd_nr_verified++;
if (fhp->fh_handle.fh_version != 1) {
_fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
} else {
+ int size;
if (fhp->fh_handle.fh_fileid_type != 0)
goto out_uptodate;
datap = fhp->fh_handle.fh_auth+
fhp->fh_handle.fh_size/4 -1;
+ size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
fhp->fh_handle.fh_fileid_type =
- _fh_update(dentry, fhp->fh_export, &datap, fhp->fh_maxsize-fhp->fh_handle.fh_size);
- fhp->fh_handle.fh_size = (datap-fhp->fh_handle.fh_auth+1)*4;
+ _fh_update(dentry, fhp->fh_export, datap, &size);
+ fhp->fh_handle.fh_size += size*4;
}
out:
return 0;
{
struct file * f;
struct inode *inode;
+ static LIST_HEAD(kill_list);
int error;
error = -ENFILE;
f->f_pos = 0;
f->f_reada = 0;
f->f_op = fops_get(inode->i_fop);
- if (inode->i_sb)
- file_move(f, &inode->i_sb->s_files);
+ file_move(f, &inode->i_sb->s_files);
if (f->f_op && f->f_op->open) {
error = f->f_op->open(inode,f);
if (error)
fops_put(f->f_op);
if (f->f_mode & FMODE_WRITE)
put_write_access(inode);
+ file_move(f, &kill_list); /* out of the way.. */
f->f_dentry = NULL;
f->f_vfsmnt = NULL;
cleanup_file:
char *disk_name (struct gendisk *hd, int minor, char *buf)
{
- unsigned int part;
const char *maj = hd->major_name;
- int unit = (minor >> hd->minor_shift) + 'a';
+ unsigned int unit = (minor >> hd->minor_shift);
+ unsigned int part = (minor & ((1 << hd->minor_shift) -1 ));
- part = minor & ((1 << hd->minor_shift) - 1);
- if (hd->part[minor].de) {
+ if ((unit < hd->nr_real) && hd->part[minor].de) {
int pos;
pos = devfs_generate_path (hd->part[minor].de, buf, 64);
#ifdef CONFIG_ARCH_S390
if (genhd_dasd_name
- && genhd_dasd_name (buf, unit - 'a', part, hd) == 0)
+ && genhd_dasd_name (buf, unit, part, hd) == 0)
return buf;
#endif
/*
maj = "hd";
break;
case MD_MAJOR:
- sprintf(buf, "%s%d", maj, unit - 'a');
+ sprintf(buf, "%s%d", maj, unit);
return buf;
}
if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
- if (unit > 'z') {
- unit -= 'z' + 1;
+ if (unit+'a' > 'z') {
+ unit -= 26;
sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
if (part)
sprintf(buf + 4, "%d", part);
}
if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) {
int ctlr = hd->major - COMPAQ_SMART2_MAJOR;
- int disk = minor >> hd->minor_shift;
- int part = minor & (( 1 << hd->minor_shift) - 1);
if (part == 0)
- sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+ sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
else
- sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+ sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
return buf;
}
if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) {
int ctlr = hd->major - COMPAQ_CISS_MAJOR;
- int disk = minor >> hd->minor_shift;
- int part = minor & (( 1 << hd->minor_shift) - 1);
if (part == 0)
- sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+ sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
else
- sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+ sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
return buf;
}
if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
int ctlr = hd->major - DAC960_MAJOR;
- int disk = minor >> hd->minor_shift;
- int part = minor & (( 1 << hd->minor_shift) - 1);
if (part == 0)
- sprintf(buf, "%s/c%dd%d", maj, ctlr, disk);
+ sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
else
- sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, disk, part);
+ sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
return buf;
}
if (part)
- sprintf(buf, "%s%c%d", maj, unit, part);
+ sprintf(buf, "%s%c%d", maj, unit+'a', part);
else
- sprintf(buf, "%s%c", maj, unit);
+ sprintf(buf, "%s%c", maj, unit+'a');
return buf;
}
* in the file COPYING); if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <asm/types.h>
+#include <linux/types.h>
#include <asm/unaligned.h>
#include <asm/byteorder.h>
#include <linux/genhd.h>
printk(LDM_CRIT "Cannot find VBLK, database may be corrupt.\n");
return -1;
}
- if (BE16(buffer + 0x0E) == 0) /* Record is not in use. */
+ if ((BE16(buffer + 0x0E) == 0) || /* Record is not in use. */
+ (BE16(buffer + 0x0C) != 0)) /* Part 2 of an ext. record */
return 0;
/* FIXME: What about extended VBLKs? */
switch (buffer[0x13]) {
file_list_lock();
for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
struct file * filp = list_entry(p, struct file, f_list);
- struct dentry * dentry;
+ struct dentry * dentry = filp->f_dentry;
struct inode * inode;
+ struct file_operations *fops;
- dentry = filp->f_dentry;
- if (!dentry)
- continue;
if (dentry->d_op != &proc_dentry_operations)
continue;
inode = dentry->d_inode;
if (inode->u.generic_ip != de)
continue;
- fops_put(filp->f_op);
+ fops = filp->f_op;
filp->f_op = NULL;
+ fops_put(fops);
}
file_list_unlock();
}
goto outi;
brelse(bh);
- s->s_dirt = 1;
return s;
struct list_head *lp;
struct dentry *result;
+ /* fhtype happens to reflect the number of u32s encoded.
+ * due to a bug in earlier code, fhtype might indicate there
+ * are more u32s then actually fitted.
+ * so if fhtype seems to be more than len, reduce fhtype.
+ * Valid types are:
+ * 2 - objectid + dir_id - legacy support
+ * 3 - objectid + dir_id + generation
+ * 4 - objectid + dir_id + objectid and dirid of parent - legacy
+ * 5 - objectid + dir_id + generation + objectid and dirid of parent
+ * 6 - as above plus generation of directory
+ * 6 does not fit in NFSv2 handles
+ */
+ if (fhtype > len) {
+ if (fhtype != 6 || len != 5)
+ printk(KERN_WARNING "nfsd/reiserfs, fhtype=%d, len=%d - odd\n",
+ fhtype, len);
+ fhtype = 5;
+ }
if (fhtype < 2 || (parent && fhtype < 4))
goto out ;
key.on_disk_key.k_objectid = data[0] ;
key.on_disk_key.k_dir_id = data[1] ;
inode = reiserfs_iget(sb, &key) ;
- if (inode && (fhtype == 3 || fhtype == 6) &&
+ if (inode && (fhtype == 3 || fhtype >= 5) &&
data[2] != inode->i_generation) {
iput(inode) ;
inode = NULL ;
}
} else {
- key.on_disk_key.k_objectid = data[fhtype==6?3:2] ;
- key.on_disk_key.k_dir_id = data[fhtype==6?4:3] ;
+ key.on_disk_key.k_objectid = data[fhtype>=5?3:2] ;
+ key.on_disk_key.k_dir_id = data[fhtype>=5?4:3] ;
inode = reiserfs_iget(sb, &key) ;
if (inode && fhtype == 6 &&
data[5] != inode->i_generation) {
data[0] = inode->i_ino ;
data[1] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
data[2] = inode->i_generation ;
- *lenp = 3;
+ *lenp = 3 ;
/* no room for directory info? return what we've stored so far */
- if (maxlen < 6 || ! need_parent)
- return 3;
+ if (maxlen < 5 || ! need_parent)
+ return 3 ;
inode = dentry->d_parent->d_inode ;
data[3] = inode->i_ino ;
data[4] = le32_to_cpu(INODE_PKEY (inode)->k_dir_id) ;
+ *lenp = 5 ;
+ if (maxlen < 6)
+ return 5 ;
data[5] = inode->i_generation ;
- *lenp = 6;
- return 6;
+ *lenp = 6 ;
+ return 6 ;
}
static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
{
+ if (mnt->mnt_sb->s_flags & MS_NOUSER)
+ return -EINVAL;
+
if (S_ISDIR(nd->dentry->d_inode->i_mode) !=
S_ISDIR(mnt->mnt_root->d_inode->i_mode))
return -ENOTDIR;
bdops = devfs_get_ops ( devfs_get_handle_from_inode (inode) );
if (bdops) bdev->bd_op = bdops;
/* Done with lookups, semaphore down */
- down(&mount_sem);
dev = to_kdev_t(bdev->bd_dev);
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
blkdev_put(bdev, BDEV_FS);
out:
path_release(&nd);
- up(&mount_sem);
return ERR_PTR(error);
}
{
kdev_t dev;
int error = -EMFILE;
- down(&mount_sem);
dev = get_unnamed_dev();
if (dev) {
struct super_block * sb;
}
put_unnamed_dev(dev);
}
- up(&mount_sem);
return ERR_PTR(error);
}
* Get the superblock of kernel-wide instance, but
* keep the reference to fs_type.
*/
- down(&mount_sem);
retry:
spin_lock(&sb_lock);
if (!list_empty(&fs_type->fs_supers)) {
kdev_t dev = get_unnamed_dev();
if (!dev) {
put_super(s);
- up(&mount_sem);
return ERR_PTR(-EMFILE);
}
s->s_dev = dev;
spin_unlock(&sb_lock);
put_super(s);
put_unnamed_dev(dev);
- up(&mount_sem);
return ERR_PTR(-EINVAL);
}
}
return 0;
}
-struct vfsmount *kern_mount(struct file_system_type *type)
-{
- struct super_block *sb;
- struct vfsmount *mnt = alloc_vfsmnt();
-
- if (!mnt)
- return ERR_PTR(-ENOMEM);
-
- if (type->fs_flags & FS_SINGLE)
- sb = get_sb_single(type, 0, NULL);
- else
- sb = get_sb_nodev(type, 0, NULL);
- if (IS_ERR(sb)) {
- kmem_cache_free(mnt_cache, mnt);
- return (struct vfsmount *)sb;
- }
- mnt->mnt_sb = sb;
- mnt->mnt_root = dget(sb->s_root);
- mnt->mnt_mountpoint = mnt->mnt_root;
- mnt->mnt_parent = mnt;
- up_write(&sb->s_umount);
- up(&mount_sem);
- return mnt;
-}
-
/*
* Doesn't take quota and stuff into account. IOW, in some cases it will
* give false negatives. The main reason why it's here is that we need
return err;
}
-static int do_add_mount(struct nameidata *nd, char *type, int flags,
- char *name, void *data)
+struct vfsmount *do_kern_mount(char *type, int flags, char *name, void *data)
{
struct file_system_type * fstype;
struct vfsmount *mnt = NULL;
struct super_block *sb;
- int retval = 0;
if (!type || !memchr(type, 0, PAGE_SIZE))
- return -EINVAL;
+ return ERR_PTR(-EINVAL);
/* we need capabilities... */
if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ return ERR_PTR(-EPERM);
/* ... filesystem driver... */
fstype = get_fs_type(type);
if (!fstype)
- return -ENODEV;
+ return ERR_PTR(-ENODEV);
/* ... allocated vfsmount... */
- retval = -ENOMEM;
mnt = alloc_vfsmnt();
- if (!mnt)
+ if (!mnt) {
+ mnt = ERR_PTR(-ENOMEM);
goto fs_out;
+ }
if (name) {
mnt->mnt_devname = kmalloc(strlen(name)+1, GFP_KERNEL);
if (mnt->mnt_devname)
strcpy(mnt->mnt_devname, name);
}
- /* get superblock, locks mount_sem on success */
- if (fstype->fs_flags & FS_NOMOUNT)
- sb = ERR_PTR(-EINVAL);
- else if (fstype->fs_flags & FS_REQUIRES_DEV)
+ /* get locked superblock */
+ if (fstype->fs_flags & FS_REQUIRES_DEV)
sb = get_sb_bdev(fstype, name, flags, data);
else if (fstype->fs_flags & FS_SINGLE)
sb = get_sb_single(fstype, flags, data);
else
sb = get_sb_nodev(fstype, flags, data);
- retval = PTR_ERR(sb);
if (IS_ERR(sb)) {
if (mnt->mnt_devname)
kfree(mnt->mnt_devname);
kmem_cache_free(mnt_cache, mnt);
+ mnt = (struct vfsmount *)sb;
goto fs_out;
}
+ if (fstype->fs_flags & FS_NOMOUNT)
+ sb->s_flags |= MS_NOUSER;
mnt->mnt_sb = sb;
mnt->mnt_root = dget(sb->s_root);
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
up_write(&sb->s_umount);
+fs_out:
+ put_filesystem(fstype);
+ return mnt;
+}
+struct vfsmount *kern_mount(struct file_system_type *type)
+{
+ return do_kern_mount((char *)type->name, 0, (char *)type->name, NULL);
+}
+
+static int do_add_mount(struct nameidata *nd, char *type, int flags,
+ char *name, void *data)
+{
+ struct vfsmount *mnt = do_kern_mount(type, flags, name, data);
+ int retval = PTR_ERR(mnt);
+
+ if (IS_ERR(mnt))
+ goto out;
+
+ down(&mount_sem);
/* Something was mounted here while we slept */
while(d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry))
;
/* Refuse the same filesystem on the same mount point */
- if (nd->mnt->mnt_sb == sb && nd->mnt->mnt_root == nd->dentry)
+ if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
retval = -EBUSY;
else
retval = graft_tree(mnt, nd);
- mntput(mnt);
up(&mount_sem);
-fs_out:
- put_filesystem(fstype);
+ mntput(mnt);
+out:
return retval;
}
-/* $Id: elf.h,v 1.29 2001/03/30 07:10:48 davem Exp $ */
+/* $Id: elf.h,v 1.30 2001/08/30 23:35:38 kanoj Exp $ */
#ifndef __ASM_SPARC64_ELF_H
#define __ASM_SPARC64_ELF_H
#endif
#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE 8192
+#define ELF_EXEC_PAGESIZE PAGE_SIZE
/* This is the location that an ET_DYN program is loaded if exec'ed. Typical
use of this is to invoke "./ld.so someprog" to test out a new version of
-/* $Id: pgtable.h,v 1.143 2001/08/22 22:16:56 kanoj Exp $
+/* $Id: pgtable.h,v 1.145 2001/08/30 03:22:00 kanoj Exp $
* pgtable.h: SpitFire page table operations.
*
* Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu)
#define _PAGE_WRITE 0x0000000000000100 /* Writable SW Bit */
#define _PAGE_PRESENT 0x0000000000000080 /* Present Page (ie. not swapped out) */
+#if PAGE_SHIFT == 13
+#define _PAGE_SZBITS _PAGE_SZ8K
+#elif PAGE_SHIFT == 16
+#define _PAGE_SZBITS _PAGE_SZ64K
+#elif PAGE_SHIFT == 19
+#define _PAGE_SZBITS _PAGE_SZ512K
+#elif PAGE_SHIFT == 22
+#define _PAGE_SZBITS _PAGE_SZ4M
+#else
+#error Wrong PAGE_SHIFT specified
+#endif
+
#define _PAGE_CACHE (_PAGE_CP | _PAGE_CV)
#define __DIRTY_BITS (_PAGE_MODIFIED | _PAGE_WRITE | _PAGE_W)
#define _PFN_MASK _PAGE_PADDR
-#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED | _PAGE_PRESENT)
+#define _PAGE_CHG_MASK (_PFN_MASK | _PAGE_MODIFIED | _PAGE_ACCESSED | _PAGE_PRESENT | _PAGE_SZBITS)
#define pg_iobits (_PAGE_VALID | _PAGE_PRESENT | __DIRTY_BITS | __ACCESS_BITS | _PAGE_E)
#ifndef __ASSEMBLY__
-extern pte_t __bad_page(void);
-
-#define BAD_PAGE __bad_page()
-
extern unsigned long phys_base;
-#define ZERO_PAGE(vaddr) (mem_map)
+extern struct page *mem_map_zero;
+#define ZERO_PAGE(vaddr) (mem_map_zero)
/* Warning: These take pointers to page structs now... */
#define mk_pte(page, pgprot) \
- __pte((((page - mem_map) << PAGE_SHIFT)+phys_base) | pgprot_val(pgprot))
+ __pte((((page - mem_map) << PAGE_SHIFT)+phys_base) | pgprot_val(pgprot) | _PAGE_SZBITS)
#define page_pte_prot(page, prot) mk_pte(page, prot)
#define page_pte(page) page_pte_prot(page, __pgprot(0))
-#define mk_pte_phys(physpage, pgprot) (__pte((physpage) | pgprot_val(pgprot)))
+#define mk_pte_phys(physpage, pgprot) (__pte((physpage) | pgprot_val(pgprot) | _PAGE_SZBITS))
extern inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot)
{
-/* $Id: system.h,v 1.63 2001/04/24 01:09:12 davem Exp $ */
+/* $Id: system.h,v 1.64 2001/08/30 03:22:00 kanoj Exp $ */
#ifndef __SPARC64_SYSTEM_H
#define __SPARC64_SYSTEM_H
#define ARCH_SUN4C_SUN4 0
#define ARCH_SUN4 0
-extern unsigned long empty_bad_page;
-extern unsigned long empty_zero_page;
#endif
#define setipl(__new_ipl) \
#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
-#define AC97_PCM_LR_DAC_RATE 0x0032 /* PCM LR DAC Rate */
+#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR DAC Rate */
#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
extern int ac97_read_proc (char *page_out, char **start, off_t off,
int count, int *eof, void *data);
extern int ac97_probe_codec(struct ac97_codec *);
+extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate);
+extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate);
+
#endif /* _AC97_CODEC_H_ */
#define MS_NOATIME 1024 /* Do not update access times. */
#define MS_NODIRATIME 2048 /* Do not update directory access times */
#define MS_BIND 4096
+#define MS_NOUSER (1<<31)
/*
* Flags that can be altered by MS_REMOUNT
extern void remove_inode_hash(struct inode *);
extern struct file * get_empty_filp(void);
extern void file_move(struct file *f, struct list_head *list);
-extern void file_moveto(struct file *new, struct file *old);
extern struct buffer_head * get_hash_table(kdev_t, int, int);
extern struct buffer_head * getblk(kdev_t, int, int);
extern void ll_rw_block(int, int, struct buffer_head * bh[]);
int gs_init_port(struct gs_port *port);
int gs_setserial(struct gs_port *port, struct serial_struct *sp);
void gs_getserial(struct gs_port *port, struct serial_struct *sp);
+void gs_got_break(struct gs_port *port);
extern int gs_debug;
#define I2C_ALGO_ISA 0x050000 /* lm_sensors ISA pseudo-adapter */
#define I2C_ALGO_SAA7146 0x060000 /* SAA 7146 video decoder bus */
#define I2C_ALGO_ACB 0x070000 /* ACCESS.bus algorithm */
+#define I2C_ALGO_IIC 0x080000 /* ITE IIC bus */
#define I2C_ALGO_EC 0x100000 /* ACPI embedded controller */
/* --- MPC8xx PowerPC adapters */
#define I2C_HW_MPC8XX_EPON 0x00 /* Eponymous MPC8xx I2C adapter */
+/* --- ITE based algorithms */
+#define I2C_HW_I_IIC 0x00 /* controller on the ITE */
+
/* --- SMBus only adapters */
#define I2C_HW_SMBUS_PIIX4 0x00
#define I2C_HW_SMBUS_ALI15X3 0x01
*/
typedef enum { ide_unknown, ide_generic, ide_pci,
ide_cmd640, ide_dtc2278, ide_ali14xx,
- ide_qd6580, ide_umc8672, ide_ht6560b,
+ ide_qd65xx, ide_umc8672, ide_ht6560b,
ide_pdc4030, ide_rz1000, ide_trm290,
ide_cmd646, ide_cy82c693, ide_4drives,
ide_pmac, ide_etrax100
*/
#define NLMSVC_XDRSIZE sizeof(struct nlm_args)
-void nlmxdr_init(void);
int nlmsvc_decode_testargs(struct svc_rqst *, u32 *, struct nlm_args *);
int nlmsvc_encode_testres(struct svc_rqst *, u32 *, struct nlm_res *);
int nlmsvc_decode_lockargs(struct svc_rqst *, u32 *, struct nlm_args *);
#ifdef __KERNEL__
+/*
+ * change the define below to 0 if you want names > info->s_namelen chars to be
+ * truncated. Else they will be disallowed (ENAMETOOLONG).
+ */
+#define NO_TRUNCATE 1
+
+extern struct minix_inode * minix_V1_raw_inode(struct super_block *, ino_t, struct buffer_head **);
+extern struct minix2_inode * minix_V2_raw_inode(struct super_block *, ino_t, struct buffer_head **);
extern struct inode * minix_new_inode(const struct inode * dir, int * error);
extern void minix_free_inode(struct inode * inode);
extern unsigned long minix_count_free_inodes(struct super_block *sb);
extern void minix_free_block(struct inode * inode, int block);
extern unsigned long minix_count_free_blocks(struct super_block *sb);
-extern struct buffer_head * minix_getblk(struct inode *, int, int);
-extern struct buffer_head * minix_bread(struct inode *, int, int);
-
extern void V1_minix_truncate(struct inode *);
extern void V2_minix_truncate(struct inode *);
extern void minix_truncate(struct inode *);
extern int minix_sync_inode(struct inode *);
-extern int V1_minix_sync_file(struct inode *);
-extern int V2_minix_sync_file(struct inode *);
+extern void minix_set_inode(struct inode *, dev_t);
extern int V1_minix_get_block(struct inode *, long, struct buffer_head *, int);
extern int V2_minix_get_block(struct inode *, long, struct buffer_head *, int);
-extern struct address_space_operations minix_aops;
+extern struct minix_dir_entry *minix_find_entry(struct dentry*, struct page**);
+extern int minix_add_link(struct dentry*, struct inode*);
+extern int minix_delete_entry(struct minix_dir_entry*, struct page*);
+extern int minix_make_empty(struct inode*, struct inode*);
+extern int minix_empty_dir(struct inode*);
+extern void minix_set_link(struct minix_dir_entry*, struct page*, struct inode*);
+extern struct minix_dir_entry *minix_dotdot(struct inode*, struct page**);
+extern ino_t minix_inode_by_name(struct dentry*);
+
+extern int minix_sync_file(struct file *, struct dentry *, int);
+
extern struct inode_operations minix_file_inode_operations;
extern struct inode_operations minix_dir_inode_operations;
extern struct file_operations minix_file_operations;
* Free memory management - zoned buddy allocator.
*/
+#ifndef CONFIG_FORCE_MAX_ZONEORDER
#define MAX_ORDER 10
+#else
+#define MAX_ORDER CONFIG_FORCE_MAX_ZONEORDER
+#endif
typedef struct free_area_struct {
struct list_head free_list;
#define MODULE_DEVICE_TABLE(type,name) \
MODULE_GENERIC_TABLE(type##_device,name)
+/*
+ * The following license idents are currently accepted as indicating free
+ * software modules
+ *
+ * "GPL" [GNU Public License v2 or later]
+ * "GPL and additional rights" [GNU Public License v2 rights and more]
+ * "Dual BSD/GPL" [GNU Public License v2 or BSD license choice]
+ *
+ * The following other idents are available
+ *
+ * "Proprietary" [Non free products]
+ *
+ * There are dual licensed components, but when running with Linux it is the
+ * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
+ * is a GPL combined work.
+ *
+ * This exists for several reasons
+ * 1. So modinfo can show license info for users wanting to vet their setup
+ * is free
+ * 2. So the community can ignore bug reports including proprietary modules
+ * 3. So vendors can do likewise based on their own policies
+ */
+
+#define MODULE_LICENSE(license) \
+static const char __module_license[] __attribute__((section(".modinfo"))) = \
+"license=" license
+
/* Define the module variable, and usage macros. */
extern struct module __this_module;
#else /* MODULE */
#define MODULE_AUTHOR(name)
+#define MODULE_LICENSE(license)
#define MODULE_DESCRIPTION(desc)
#define MODULE_SUPPORTED_DEVICE(name)
#define MODULE_PARM(var,type)
--- /dev/null
+/*
+ * Generic cache management functions. Everything is arch-specific,
+ * but this header exists to make sure the defines/functions can be
+ * used in a generic way.
+ *
+ * 2000-11-13 Arjan van de Ven <arjan@fenrus.demon.nl>
+ *
+ */
+
+#ifndef _LINUX_PREFETCH_H
+#define _LINUX_PREFETCH_H
+
+#include <asm/processor.h>
+#include <asm/cache.h>
+
+/*
+ prefetch(x) attempts to pre-emptively get the memory pointed to
+ by address "x" into the CPU L1 cache.
+ prefetch(x) should not cause any kind of exception, prefetch(0) is
+ specifically ok.
+
+ prefetch() should be defined by the architecture, if not, the
+ #define below provides a no-op define.
+
+ There are 3 prefetch() macros:
+
+ prefetch(x) - prefetches the cacheline at "x" for read
+ prefetchw(x) - prefetches the cacheline at "x" for write
+ spin_lock_prefetch(x) - prefectches the spinlock *x for taking
+
+ there is also PREFETCH_STRIDE which is the architecure-prefered
+ "lookahead" size for prefetching streamed operations.
+
+*/
+
+/*
+ * These cannot be do{}while(0) macros. See the mental gymnastics in
+ * the loop macro.
+ */
+
+#ifndef ARCH_HAS_PREFETCH
+#define ARCH_HAS_PREFETCH
+static inline void prefetch(const void *x) {;}
+#endif
+
+#ifndef ARCH_HAS_PREFETCHW
+#define ARCH_HAS_PREFETCHW
+static inline void prefetchw(const void *x) {;}
+#endif
+
+#ifndef ARCH_HAS_SPINLOCK_PREFETCH
+#define ARCH_HAS_SPINLOCK_PREFETCH
+#define spin_lock_prefetch(x) prefetchw(x)
+#endif
+
+#ifndef PREFETCH_STRIDE
+#define PREFETCH_STRIDE (4*L1_CACHE_BYTE)
+#endif
+
+#endif
typedef int (*kxdrproc_t)(void *rqstp, u32 *data, void *obj);
/*
- * These variables contain pre-xdr'ed values for faster operation.
- * FIXME: should be replaced by macros for big-endian machines.
+ * pre-xdr'ed macros.
*/
-extern u32 xdr_zero, xdr_one, xdr_two;
-
-extern u32 rpc_success,
- rpc_prog_unavail,
- rpc_prog_mismatch,
- rpc_proc_unavail,
- rpc_garbage_args,
- rpc_system_err;
-
-extern u32 rpc_auth_ok,
- rpc_autherr_badcred,
- rpc_autherr_rejectedcred,
- rpc_autherr_badverf,
- rpc_autherr_rejectedverf,
- rpc_autherr_tooweak,
- rpc_autherr_dropit;
-
-void xdr_init(void);
+
+#define xdr_zero __constant_htonl(0)
+#define xdr_one __constant_htonl(1)
+#define xdr_two __constant_htonl(2)
+
+#define rpc_success __constant_htonl(RPC_SUCCESS)
+#define rpc_prog_unavail __constant_htonl(RPC_PROG_UNAVAIL)
+#define rpc_prog_mismatch __constant_htonl(RPC_PROG_MISMATCH)
+#define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL)
+#define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS)
+#define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR)
+
+#define rpc_auth_ok __constant_htonl(RPC_AUTH_OK)
+#define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED)
+#define rpc_autherr_rejectedcred __constant_htonl(RPC_AUTH_REJECTEDCRED)
+#define rpc_autherr_badverf __constant_htonl(RPC_AUTH_BADVERF)
+#define rpc_autherr_rejectedverf __constant_htonl(RPC_AUTH_REJECTEDVERF)
+#define rpc_autherr_tooweak __constant_htonl(RPC_AUTH_TOOWEAK)
+
/*
* Miscellaneous XDR helper functions
*
* Basic Linux Telephony Interface
*
- * (c) Copyright 1999 Quicknet Technologies, Inc.
+ * (c) Copyright 1999-2001 Quicknet Technologies, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Contributors: Alan Cox, <alan@redhat.com>
* David W. Erhart, <derhart@quicknet.net>
*
- * Version: 0.1.0 - December 19, 1999
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Version: $Revision: 4.2 $
+ *
+ * $Id: telephony.h,v 4.2 2001/08/06 07:09:43 craigs Exp $
*
- * Fixes:
- *
*****************************************************************************/
#ifndef TELEPHONY_H
#define TELEPHONY_H
+#define TELEPHONY_VERSION 3013
+
#define PHONE_VENDOR_IXJ 1
#define PHONE_VENDOR_QUICKNET PHONE_VENDOR_IXJ
#define PHONE_VENDOR_VOICETRONIX 2
#define PHONE_HOOKSTATE _IO ('q', 0x84)
#define PHONE_MAXRINGS _IOW ('q', 0x85, char)
#define PHONE_RING_CADENCE _IOW ('q', 0x86, short)
-#define OLD_PHONE_RING_START _IO ('q', 0x87)
+#define OLD_PHONE_RING_START _IO ('q', 0x87)
#define PHONE_RING_START _IOW ('q', 0x87, PHONE_CID *)
#define PHONE_RING_STOP _IO ('q', 0x88)
#define PHONE_REC_DEPTH _IOW ('q', 0x8C, int)
#define PHONE_FRAME _IOW ('q', 0x8D, int)
#define PHONE_REC_VOLUME _IOW ('q', 0x8E, int)
+#define PHONE_REC_VOLUME_LINEAR _IOW ('q', 0xDB, int)
#define PHONE_REC_LEVEL _IO ('q', 0x8F)
#define PHONE_PLAY_CODEC _IOW ('q', 0x90, int)
#define PHONE_PLAY_STOP _IO ('q', 0x92)
#define PHONE_PLAY_DEPTH _IOW ('q', 0x93, int)
#define PHONE_PLAY_VOLUME _IOW ('q', 0x94, int)
+#define PHONE_PLAY_VOLUME_LINEAR _IOW ('q', 0xDC, int)
#define PHONE_PLAY_LEVEL _IO ('q', 0x95)
#define PHONE_DTMF_READY _IOR ('q', 0x96, int)
#define PHONE_GET_DTMF _IOR ('q', 0x97, int)
*
******************************************************************************/
#define PHONE_WINK_DURATION _IOW ('q', 0xA6, int)
-
+#define PHONE_WINK _IOW ('q', 0xAA, int)
/******************************************************************************
*
ALAW = 9,
LINEAR16 = 10,
LINEAR8 = 11,
- WSS = 12
+ WSS = 12,
+ G729B = 13
} phone_codec;
struct phone_codec_data
{
- phone_codec type;
- unsigned short buf_min, buf_opt, buf_max;
+ phone_codec type;
+ unsigned short buf_min, buf_opt, buf_max;
};
-#define PHONE_QUERY_CODEC _IOWR ('q', 0xA7, struct phone_codec_data *)
-#define PHONE_PSTN_LINETEST _IO ('q', 0xA8)
+#define PHONE_QUERY_CODEC _IOWR ('q', 0xA7, struct phone_codec_data *)
+#define PHONE_PSTN_LINETEST _IO ('q', 0xA8)
/******************************************************************************
*
* indicate the current state of the hookswitch. The pstn_ring bit
* indicates that the DAA on a LineJACK card has detected ring voltage on
* the PSTN port. The caller_id bit indicates that caller_id data has been
-* received and is available. The pstn_wink bit indicates that the DAA on
-* the LineJACK has received a wink from the telco switch. The f0, f1, f2
+* recieved and is available. The pstn_wink bit indicates that the DAA on
+* the LineJACK has recieved a wink from the telco switch. The f0, f1, f2
* and f3 bits indicate that the filter has been triggered by detecting the
* frequency programmed into that filter.
*
};
-#endif /* TELEPHONY_H */
+#endif /* TELEPHONY_H */
+
atomic_t refcnt;
};
-#define USB_MAXCHILDREN (16) /* This is arbitrary */
+/* This is arbitrary.
+ * From USB 2.0 spec Table 11-13, offset 7, a hub can
+ * have up to 255 ports. The most yet reported is 10.
+ */
+#define USB_MAXCHILDREN (16)
struct usb_device {
int devnum; /* Device number on USB bus */
- int slow; /* Slow device? */
+
+ enum {
+ USB_SPEED_UNKNOWN = 0, /* enumerating */
+ USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
+ USB_SPEED_HIGH /* usb 2.0 */
+ } speed;
+
+ struct usb_device *tt; /* usb1.1 device on usb2.0 bus */
+ int ttport; /* device/hub port on that tt */
atomic_t refcnt; /* Reference count */
struct semaphore serialize;
* up to us. This one happens to share a lot of bit positions with the UHCI
* specification, so that much of the uhci driver can just mask the bits
* appropriately.
+ *
+ * NOTE: there's no encoding (yet?) for a "high speed" endpoint; treat them
+ * like full speed devices.
*/
#define PIPE_ISOCHRONOUS 0
static inline unsigned int __create_pipe(struct usb_device *dev, unsigned int endpoint)
{
- return (dev->devnum << 8) | (endpoint << 15) | (dev->slow << 26);
+ return (dev->devnum << 8) | (endpoint << 15) |
+ ((dev->speed == USB_SPEED_LOW) << 26);
}
static inline unsigned int __default_pipe(struct usb_device *dev)
{
- return (dev->slow << 26);
+ return ((dev->speed == USB_SPEED_LOW) << 26);
}
/* Create various pipes... */
*/
/*
- * $Id: bluetooth.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: bluetooth.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
*/
-#ifndef __IF_BLUETOOTH_H
-#define __IF_BLUETOOTH_H
+#ifndef __BLUETOOTH_H
+#define __BLUETOOTH_H
#include <asm/types.h>
#include <asm/byteorder.h>
+#ifndef AF_BLUETOOTH
+#define AF_BLUETOOTH 31
+#define PF_BLUETOOTH AF_BLUETOOTH
+#endif
+
#define BTPROTO_L2CAP 0
#define BTPROTO_HCI 1
#define SOL_HCI 0
#define SOL_L2CAP 6
-typedef struct {
- __u8 b0, b1, b2, b3, b4, b5;
-} bdaddr_t;
-
-#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
-
/* Connection and socket states */
enum {
BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */
BT_CLOSED
};
+/* Endianness conversions */
+#define htobs(a) __cpu_to_le16(a)
+#define htobl(a) __cpu_to_le32(a)
+#define btohs(a) __le16_to_cpu(a)
+#define btohl(a) __le32_to_cpu(a)
+
+/* BD Address */
+typedef struct {
+ __u8 b[6];
+} __attribute__((packed)) bdaddr_t;
+
+#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
+
/* Copy, swap, convert BD Address */
-static __inline__ int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
+static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
{
return memcmp(ba1, ba2, sizeof(bdaddr_t));
}
-static __inline__ void bacpy(bdaddr_t *dst, bdaddr_t *src)
+static inline void bacpy(bdaddr_t *dst, bdaddr_t *src)
{
memcpy(dst, src, sizeof(bdaddr_t));
}
-extern void baswap(bdaddr_t *dst, bdaddr_t *src);
-
-extern char *batostr(bdaddr_t *ba);
-extern bdaddr_t *strtoba(char *str);
-
-/* Endianness conversions */
-#define htobs(a) __cpu_to_le16(a)
-#define htobl(a) __cpu_to_le32(a)
-#define btohs(a) __le16_to_cpu(a)
-#define btohl(a) __le32_to_cpu(a)
+void baswap(bdaddr_t *dst, bdaddr_t *src);
+char *batostr(bdaddr_t *ba);
+bdaddr_t *strtoba(char *str);
int bterr(__u16 code);
-#endif /* __IF_BLUETOOTH_H */
+#endif /* __BLUETOOTH_H */
*/
/*
- * $Id: bluez.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: bluez.h,v 1.4 2001/08/03 04:19:49 maxk Exp $
*/
#ifndef __IF_BLUEZ_H
#include <net/sock.h>
-#define BLUEZ_VER "1.0"
-
#define BLUEZ_MAX_PROTO 2
/* Reserv for core and drivers use */
/* ----- SKB helpers ----- */
struct bluez_skb_cb {
- int incomming, fragmented;
- struct sk_buff_head frags;
+ int incomming;
};
#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
-static __inline__ struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
{
struct sk_buff *skb;
if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
- bluez_cb(skb)->incomming = 0;
- bluez_cb(skb)->fragmented = 0;
skb_reserve(skb, BLUEZ_SKB_RESERVE);
+ bluez_cb(skb)->incomming = 0;
}
return skb;
}
-static __inline__ struct sk_buff *bluez_skb_clone(struct sk_buff *skb, int how)
-{
- struct sk_buff *new;
-
- if ((new = skb_clone(skb, how)))
- bluez_cb(new)->fragmented = 0;
- return new;
-}
-
-static __inline__ struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
int nb, int *err)
{
struct sk_buff *skb;
if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
- bluez_cb(skb)->incomming = 0;
- bluez_cb(skb)->fragmented = 0;
skb_reserve(skb, BLUEZ_SKB_RESERVE);
+ bluez_cb(skb)->incomming = 0;
}
return skb;
}
-static __inline__ int bluez_skb_frags(struct sk_buff *skb)
-{
- if (bluez_cb(skb)->fragmented)
- return skb_queue_len(&bluez_cb(skb)->frags);
- return 0;
-}
-
-static __inline__ void bluez_skb_add_frag(struct sk_buff *skb, struct sk_buff *frag)
-{
- if (!bluez_cb(skb)->fragmented) {
- skb_queue_head_init(&bluez_cb(skb)->frags);
- bluez_cb(skb)->fragmented = 1;
- }
- __skb_queue_tail(&bluez_cb(skb)->frags, frag);
-}
-
-static __inline__ struct sk_buff *bluez_skb_next_frag(struct sk_buff *skb)
+static inline int skb_frags_no(struct sk_buff *skb)
{
- if (bluez_cb(skb)->fragmented)
- return skb_peek(&bluez_cb(skb)->frags);
- if (skb->next == (void *) skb->list)
- return NULL;
- return skb->next;
-}
-
-static __inline__ struct sk_buff *bluez_skb_get_frag(struct sk_buff *skb)
-{
- if (bluez_cb(skb)->fragmented)
- return __skb_dequeue(&bluez_cb(skb)->frags);
- return NULL;
-}
-
-static __inline__ void bluez_skb_free(struct sk_buff *skb)
-{
- if (bluez_cb(skb)->fragmented)
- __skb_queue_purge(&bluez_cb(skb)->frags);
- kfree_skb(skb);
-}
-
-static __inline__ void bluez_skb_queue_purge(struct sk_buff_head *q)
-{
- struct sk_buff *skb;
+ register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
+ register int n = 1;
- while((skb = skb_dequeue(q)))
- bluez_skb_free(skb);
+ for (; frag; frag=frag->next, n++);
+ return n;
}
extern int hci_core_init(void);
*/
/*
- * $Id: hci.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci.h,v 1.15 2001/08/05 06:02:15 maxk Exp $
*/
-#ifndef __IF_HCI_H
-#define __IF_HCI_H
+#ifndef __HCI_H
+#define __HCI_H
#include <asm/byteorder.h>
+#define HCI_MAX_DEV 8
+#define HCI_MAX_FRAME_SIZE 2048
+
+/* HCI dev events */
+#define HCI_DEV_REG 1
+#define HCI_DEV_UNREG 2
+#define HCI_DEV_UP 3
+#define HCI_DEV_DOWN 4
+
+/* HCI device types */
+#define HCI_UART 0
+#define HCI_USB 1
+#define HCI_VHCI 2
+
+/* HCI device modes */
+#define HCI_NORMAL 0x0001
+#define HCI_RAW 0x0002
+#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
+#define HCI_SOCK 0x1000
+
+/* HCI device states */
+#define HCI_INIT 0x0010
+#define HCI_UP 0x0020
+#define HCI_RUNNING 0x0040
+
+/* HCI device flags */
+#define HCI_PSCAN 0x0100
+#define HCI_ISCAN 0x0200
+#define HCI_AUTH 0x0400
+
+/* HCI Ioctl defines */
+#define HCIDEVUP _IOW('H', 201, int)
+#define HCIDEVDOWN _IOW('H', 202, int)
+#define HCIDEVRESET _IOW('H', 203, int)
+#define HCIRESETSTAT _IOW('H', 204, int)
+#define HCIGETINFO _IOR('H', 205, int)
+#define HCIGETDEVLIST _IOR('H', 206, int)
+#define HCISETRAW _IOW('H', 207, int)
+#define HCISETSCAN _IOW('H', 208, int)
+#define HCISETAUTH _IOW('H', 209, int)
+#define HCIINQUIRY _IOR('H', 210, int)
+#define HCISETPTYPE _IOW('H', 211, int)
+#define HCIGETCONNLIST _IOR('H', 212, int)
+
+#ifndef __NO_HCI_DEFS
+
/* HCI Packet types */
#define HCI_COMMAND_PKT 0x01
#define HCI_ACLDATA_PKT 0x02
#define HCI_EVENT_PKT 0x04
#define HCI_UNKNOWN_PKT 0xff
+/* HCI Packet types */
+#define HCI_DM1 0x0008
+#define HCI_DM3 0x0400
+#define HCI_DM5 0x4000
+#define HCI_DH1 0x0010
+#define HCI_DH3 0x0800
+#define HCI_DH5 0x8000
+
+/* ACL flags */
+#define ACL_CONT 0x0001
+#define ACL_START 0x0002
+#define ACL_ACTIVE_BCAST 0x0010
+#define ACL_PICO_BCAST 0x0020
+
+/* Baseband links */
+#define SCO_LINK 0x00
+#define ACL_LINK 0x01
+
+/* LMP features */
+#define LMP_3SLOT 0x01
+#define LMP_5SLOT 0x02
+#define LMP_ENCRYPT 0x04
+#define LMP_SOFFSET 0x08
+#define LMP_TACCURACY 0x10
+#define LMP_RSWITCH 0x20
+#define LMP_HOLD 0x40
+#define LMP_SNIF 0x80
+
+#define LMP_PARK 0x01
+#define LMP_RSSI 0x02
+#define LMP_QUALITY 0x04
+#define LMP_SCO 0x08
+#define LMP_HV2 0x10
+#define LMP_HV3 0x20
+#define LMP_ULAW 0x40
+#define LMP_ALAW 0x80
+
+#define LMP_CVSD 0x01
+#define LMP_PSCHEME 0x02
+#define LMP_PCONTROL 0x04
+
/* ----- HCI Commands ----- */
/* OGF & OCF values */
/* Informational Parameters */
#define OGF_INFO_PARAM 0x04
-#define OCF_NOP 0x0000
-#define OCF_READ_BUFFER_SIZE 0x0005
+#define OCF_READ_LOCAL_VERSION 0x0001
+typedef struct {
+ __u8 status;
+ __u8 hci_ver;
+ __u16 hci_rev;
+ __u8 lmp_ver;
+ __u16 man_name;
+ __u16 lmp_sub;
+} __attribute__ ((packed)) read_local_version_rp;
+
+#define OCF_READ_LOCAL_FEATURES 0x0003
+typedef struct {
+ __u8 status;
+ __u8 features[8];
+} __attribute__ ((packed)) read_local_features_rp;
+
+#define OCF_READ_BUFFER_SIZE 0x0005
typedef struct {
__u8 status;
__u16 acl_mtu;
__u8 sco_mtu;
__u16 acl_max_pkt;
__u16 sco_max_pkt;
-} __attribute__ ((packed)) read_buffer_size_rp;
+} __attribute__ ((packed)) read_buffer_size_rp;
-#define OCF_READ_BD_ADDR 0x0009
+#define OCF_READ_BD_ADDR 0x0009
typedef struct {
__u8 status;
bdaddr_t bdaddr;
-} __attribute__ ((packed)) read_bd_addr_rp;
+} __attribute__ ((packed)) read_bd_addr_rp;
/* Host Controller and Baseband */
-#define OGF_HOST_CTL 0x03
-#define OCF_RESET 0x0003
+#define OGF_HOST_CTL 0x03
+#define OCF_RESET 0x0003
#define OCF_WRITE_AUTH_ENABLE 0x0020
#define AUTH_DISABLED 0x00
#define AUTH_ENABLED 0x01
-#define OCF_WRITE_CA_TIMEOUT 0x0016 /* Write_Connection_Accept_Timeout */
-#define OCF_WRITE_PG_TIMEOUT 0x0018 /* Write_Page_Timeout */
+#define OCF_WRITE_CA_TIMEOUT 0x0016
+#define OCF_WRITE_PG_TIMEOUT 0x0018
#define OCF_WRITE_SCAN_ENABLE 0x001A
#define SCANS_DISABLED 0x00
- #define IS_ENA_PS_DIS 0x01 /* Inquiry scan enabled Page Scan disabled */
- #define IS_DIS_PS_ENA 0x02 /* Inquiry scan disabled Page Scan enabled */
- #define IS_ENA_PS_ENA 0x03 /* Inquiry scan enabled Page Scan enabled */
+ #define IS_ENA_PS_DIS 0x01
+ #define IS_DIS_PS_ENA 0x02
+ #define IS_ENA_PS_ENA 0x03
#define OCF_SET_EVENT_FLT 0x0005
typedef struct {
__u8 flt_type;
__u8 cond_type;
- __u8 condition;
-} __attribute__ ((packed)) set_event_flt_cp;
-#define SET_EVENT_FLT_CP_SIZE 3
+ __u8 condition[0];
+} __attribute__ ((packed)) set_event_flt_cp;
+#define SET_EVENT_FLT_CP_SIZE 2
/* Filter types */
#define FLT_CLEAR_ALL 0x00
/* CONN_SETUP Conditions */
#define CONN_SETUP_AUTO_OFF 0x01
-#define CONN_SETUP_AUTO_ON 0x02
+#define CONN_SETUP_AUTO_ON 0x02
+
+#define OCF_CHANGE_LOCAL_NAME 0x0013
+typedef struct {
+ __u8 name[248];
+} __attribute__ ((packed)) change_local_name_cp;
+#define CHANGE_LOCAL_NAME_CP_SIZE 248
+
+#define OCF_READ_LOCAL_NAME 0x0014
+typedef struct {
+ __u8 status;
+ __u8 name[248];
+} __attribute__ ((packed)) read_local_name_rp;
+#define READ_LOCAL_NAME_RP_SIZE 249
+
+#define OCF_READ_CLASS_OF_DEV 0x0023
+typedef struct {
+ __u8 status;
+ __u8 dev_class[3];
+} __attribute__ ((packed)) read_class_of_dev_rp;
+#define READ_CLASS_OF_DEV_RP_SIZE 4
+
+#define OCF_WRITE_CLASS_OF_DEV 0x0024
+typedef struct {
+ __u8 dev_class[3];
+} __attribute__ ((packed)) write_class_of_dev_cp;
+#define WRITE_CLASS_OF_DEV_CP_SIZE 3
/* Link Control */
#define OGF_LINK_CTL 0x01
__u8 pscan_mode;
__u16 clock_offset;
__u8 role_switch;
-} __attribute__ ((packed)) create_conn_cp;
-#define CREATE_CONN_CP_SIZE 13
+} __attribute__ ((packed)) create_conn_cp;
+#define CREATE_CONN_CP_SIZE 13
#define OCF_ACCEPT_CONN_REQ 0x0009
typedef struct {
bdaddr_t bdaddr;
__u8 role;
-} __attribute__ ((packed)) accept_conn_req_cp;
-#define ACCEPT_CONN_REQ_CP_SIZE 7
+} __attribute__ ((packed)) accept_conn_req_cp;
+#define ACCEPT_CONN_REQ_CP_SIZE 7
#define OCF_DISCONNECT 0x0006
typedef struct {
__u16 handle;
__u8 reason;
-} __attribute__ ((packed)) disconnect_cp;
-#define DISCONNECT_CP_SIZE 3
+} __attribute__ ((packed)) disconnect_cp;
+#define DISCONNECT_CP_SIZE 3
#define OCF_INQUIRY 0x0001
typedef struct {
__u8 lap[3];
__u8 lenght;
__u8 num_rsp;
-} __attribute__ ((packed)) inquiry_cp;
-#define INQUIRY_CP_SIZE 5
+} __attribute__ ((packed)) inquiry_cp;
+#define INQUIRY_CP_SIZE 5
#define OGF_LINK_POLICY 0x02 /* Link Policy */
__u8 pscan_mode;
__u8 class[3];
__u16 clock_offset;
-} __attribute__ ((packed)) inquiry_info;
-#define INQUIRY_INFO_SIZE 14
+} __attribute__ ((packed)) inquiry_info;
+#define INQUIRY_INFO_SIZE 14
#define EVT_CONN_COMPLETE 0x03
typedef struct {
bdaddr_t bdaddr;
__u8 link_type;
__u8 encr_mode;
-} __attribute__ ((packed)) evt_conn_complete;
-#define EVT_CONN_COMPLETE_SIZE 13
+} __attribute__ ((packed)) evt_conn_complete;
+#define EVT_CONN_COMPLETE_SIZE 13
#define EVT_CONN_REQUEST 0x04
typedef struct {
bdaddr_t bdaddr;
-#if defined (__LITTLE_ENDIAN_BITFIELD)
- __u32 class :24;
- __u32 type :8;
-#else /* (__BIG_ENDIAN_BITFIELD) */
- __u32 type :8;
- __u32 class :24;
-#endif
-} __attribute__ ((packed)) evt_conn_request;
-#define EVT_CONN_REQUEST_SIZE 10
+ __u8 dev_class[3];
+ __u8 link_type;
+} __attribute__ ((packed)) evt_conn_request;
+#define EVT_CONN_REQUEST_SIZE 10
#define EVT_DISCONN_COMPLETE 0x05
typedef struct {
__u8 status;
__u16 handle;
__u8 reason;
-} __attribute__ ((packed)) evt_disconn_complete;
-#define EVT_DISCONN_COMPLETE_SIZE 4
+} __attribute__ ((packed)) evt_disconn_complete;
+#define EVT_DISCONN_COMPLETE_SIZE 4
#define EVT_CMD_COMPLETE 0x0e
typedef struct {
__u8 ncmd;
__u16 opcode;
-} __attribute__ ((packed)) evt_cmd_complete;
-#define EVT_CMD_COMPLETE_SIZE 3
+} __attribute__ ((packed)) evt_cmd_complete;
+#define EVT_CMD_COMPLETE_SIZE 3
#define EVT_CMD_STATUS 0x0f
typedef struct {
__u8 status;
__u8 ncmd;
__u16 opcode;
-} __attribute__ ((packed)) evt_cmd_status;
-#define EVT_CMD_STATUS_SIZE 4
+} __attribute__ ((packed)) evt_cmd_status;
+#define EVT_CMD_STATUS_SIZE 4
#define EVT_NUM_COMP_PKTS 0x13
typedef struct {
__u8 num_hndl;
/* variable lenght part */
-} __attribute__ ((packed)) evt_num_comp_pkts;
-#define EVT_NUM_COMP_PKTS_SIZE 1
+} __attribute__ ((packed)) evt_num_comp_pkts;
+#define EVT_NUM_COMP_PKTS_SIZE 1
#define EVT_HCI_DEV_EVENT 0xfd
typedef struct {
__u16 event;
__u16 param;
-} __attribute__ ((packed)) evt_hci_dev_event;
-#define EVT_HCI_DEV_EVENT_SIZE 4
+} __attribute__ ((packed)) evt_hci_dev_event;
+#define EVT_HCI_DEV_EVENT_SIZE 4
/* -------- HCI Packet structures -------- */
#define HCI_TYPE_LEN 1
#define HCI_SCO_HDR_SIZE 3
/* Command opcode pack/unpack */
-#define cmd_opcode_pack(ocf, ogf) (__u16)((ocf & 0x03ff)|(ogf << 10))
+#define cmd_opcode_pack(ogf, ocf) (__u16)((ocf & 0x03ff)|(ogf << 10))
#define cmd_opcode_ogf(op) (op >> 10)
#define cmd_opcode_ocf(op) (op & 0x03ff)
/* ACL handle and flags pack/unpack */
#define acl_handle_pack(h, f) (__u16)((h & 0x0fff)|(f << 12))
-#define acl_handle(h) (h & 0x0fff)
-#define acl_flags(h) (h >> 12)
-
-/* ACL flags */
-#define ACL_CONT 0x0001
-#define ACL_START 0x0002
-#define ACL_ACTIVE_BCAST 0x0010
-#define ACL_PICO_BCAST 0x0020
-
-/* Max frame size */
-#define HCI_MAX_FRAME 4096
-
-/* HCI device types */
-#define HCI_UART 0
-#define HCI_USB 1
-#define HCI_EMU 2
-
-/* HCI device modes */
-#define HCI_NORMAL 0x0001
-#define HCI_RAW 0x0002
-#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
-#define HCI_SOCK 0x1000
-
-/* HCI device states */
-#define HCI_INIT 0x0010
-#define HCI_UP 0x0020
-#define HCI_RUNNING 0x0040
-
-/* HCI device flags */
-#define HCI_PSCAN 0x0100
-#define HCI_ISCAN 0x0200
-#define HCI_AUTH 0x0400
-
-/* HCI Packet types */
-#define HCI_DM1 0x0008
-#define HCI_DM3 0x0400
-#define HCI_DM5 0x4000
-#define HCI_DH1 0x0010
-#define HCI_DH3 0x0800
-#define HCI_DH5 0x8000
+#define acl_handle(h) (h & 0x0fff)
+#define acl_flags(h) (h >> 12)
-/* HCI Ioctl defines */
-#define HCIDEVUP _IOW('H', 201, int)
-#define HCIDEVDOWN _IOW('H', 202, int)
-#define HCIDEVRESET _IOW('H', 203, int)
-#define HCIRESETSTAT _IOW('H', 204, int)
-#define HCIGETINFO _IOR('H', 205, int)
-#define HCIGETDEVLIST _IOR('H', 206, int)
-#define HCISETRAW _IOW('H', 207, int)
-#define HCISETSCAN _IOW('H', 208, int)
-#define HCISETAUTH _IOW('H', 209, int)
-#define HCIINQUIRY _IOWR('H', 210, int)
+#endif /* _NO_HCI_DEFS */
/* HCI Socket options */
#define HCI_DATA_DIR 0x0001
#define HCI_FILTER 0x0002
-/* HCI CMSG types */
+/* HCI CMSG flags */
#define HCI_CMSG_DIR 0x0001
struct sockaddr_hci {
- sa_family_t hci_family;
- unsigned short hci_dev;
+ sa_family_t hci_family;
+ unsigned short hci_dev;
};
#define HCI_DEV_NONE 0xffff
+struct hci_filter {
+ __u32 type_mask;
+ __u32 event_mask[2];
+};
+
struct hci_dev_req {
__u16 dev_id;
__u32 dev_opt;
__u16 dev_id;
char name[8];
+ bdaddr_t bdaddr;
+
__u32 flags;
__u8 type;
+ __u8 features[8];
+
+ __u32 pkt_type;
+
__u16 acl_mtu;
__u16 acl_max;
__u16 sco_mtu;
__u16 sco_max;
- bdaddr_t bdaddr;
-
struct hci_dev_stats stat;
};
-/* Number of devices */
-#define HCI_MAX_DEV 8
+struct hci_conn_info {
+ __u16 handle;
+ bdaddr_t bdaddr;
+};
-/* HCI dev events */
-#define HCI_DEV_REG 1
-#define HCI_DEV_UNREG 2
-#define HCI_DEV_UP 3
-#define HCI_DEV_DOWN 4
+struct hci_conn_list_req {
+ __u16 dev_id;
+ __u16 conn_num;
+ struct hci_conn_info conn_info[0];
+};
-#endif /* __IF_HCI_H */
+#endif /* __HCI_H */
*/
/*
- * $Id: hci_core.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_core.h,v 1.11 2001/08/05 06:02:15 maxk Exp $
*/
-#ifndef __IF_HCI_CORE_H
-#define __IF_HCI_CORE_H
+#ifndef __HCI_CORE_H
+#define __HCI_CORE_H
-#include "hci.h"
+#include <net/bluetooth/hci.h>
/* HCI upper protocols */
#define HCI_MAX_PROTO 1
struct inquiry_entry *list;
};
-static __inline__ void inquiry_cache_init(struct inquiry_cache *cache)
+static inline void inquiry_cache_init(struct inquiry_cache *cache)
{
spin_lock_init(&cache->lock);
cache->list = NULL;
}
-static __inline__ void inquiry_cache_lock(struct inquiry_cache *cache)
+static inline void inquiry_cache_lock(struct inquiry_cache *cache)
{
spin_lock(&cache->lock);
}
-static __inline__ void inquiry_cache_unlock(struct inquiry_cache *cache)
+static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
{
spin_unlock(&cache->lock);
}
-static __inline__ void inquiry_cache_lock_bh(struct inquiry_cache *cache)
+static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
{
spin_lock_bh(&cache->lock);
}
-static __inline__ void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
+static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
{
spin_unlock_bh(&cache->lock);
}
-static __inline__ long inquiry_cache_age(struct inquiry_cache *cache)
+static inline long inquiry_cache_age(struct inquiry_cache *cache)
{
return jiffies - cache->timestamp;
}
-static __inline__ long inquiry_entry_age(struct inquiry_entry *e)
+static inline long inquiry_entry_age(struct inquiry_entry *e)
{
return jiffies - e->timestamp;
}
extern void inquiry_cache_flush(struct inquiry_cache *cache);
-/* ----- Connection hash ----- */
-#define HCI_MAX_CONN 10
+struct hci_dev;
+
+/* ----- HCI Connections ----- */
+struct hci_conn {
+ struct list_head list;
+ bdaddr_t dst;
+ __u16 handle;
+ __u8 type;
+ unsigned int sent;
+
+ struct hci_dev *hdev;
+ void *l2cap_data;
+ void *priv;
+
+ struct sk_buff_head data_q;
+};
-/* FIXME:
- * We assume that handle is a number - 0 ... HCI_MAX_CONN.
- */
struct conn_hash {
- spinlock_t lock;
- unsigned int num;
- void *conn[HCI_MAX_CONN];
+ struct list_head list;
+ spinlock_t lock;
+ unsigned int num;
};
-static __inline__ void conn_hash_init(struct conn_hash *h)
+static inline void conn_hash_init(struct conn_hash *h)
{
- memset(h, 0, sizeof(struct conn_hash));
+ INIT_LIST_HEAD(&h->list);
spin_lock_init(&h->lock);
+ h->num = 0;
}
-static __inline__ void conn_hash_lock(struct conn_hash *h)
+static inline void conn_hash_lock(struct conn_hash *h)
{
spin_lock(&h->lock);
}
-static __inline__ void conn_hash_unlock(struct conn_hash *h)
+static inline void conn_hash_unlock(struct conn_hash *h)
{
spin_unlock(&h->lock);
}
-static __inline__ void *__conn_hash_add(struct conn_hash *h, __u16 handle, void *conn)
+static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
{
- if (!h->conn[handle]) {
- h->conn[handle] = conn;
- h->num++;
- return conn;
- } else
- return NULL;
+ list_add(&c->list, &h->list);
+ h->num++;
}
-static __inline__ void *conn_hash_add(struct conn_hash *h, __u16 handle, void *conn)
+static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
{
- if (handle >= HCI_MAX_CONN)
- return NULL;
-
conn_hash_lock(h);
- conn = __conn_hash_add(h, handle, conn);
+ __conn_hash_add(h, handle, c);
conn_hash_unlock(h);
-
- return conn;
}
-static __inline__ void *__conn_hash_del(struct conn_hash *h, __u16 handle)
+static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
{
- void *conn = h->conn[handle];
-
- if (conn) {
- h->conn[handle] = NULL;
- h->num--;
- return conn;
- } else
- return NULL;
+ list_del(&c->list);
+ h->num--;
}
-static __inline__ void *conn_hash_del(struct conn_hash *h, __u16 handle)
+static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
{
- void *conn;
-
- if (handle >= HCI_MAX_CONN)
- return NULL;
conn_hash_lock(h);
- conn = __conn_hash_del(h, handle);
+ __conn_hash_del(h, c);
conn_hash_unlock(h);
-
- return conn;
}
-static __inline__ void *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
+static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
{
- return h->conn[handle];
+ register struct list_head *p;
+ register struct hci_conn *c;
+
+ list_for_each(p, &h->list) {
+ c = list_entry(p, struct hci_conn, list);
+ if (c->handle == handle)
+ return c;
+ }
+ return NULL;
}
-static __inline__ void *conn_hash_lookup(struct conn_hash *h, __u16 handle)
+static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
{
- void *conn;
-
- if (handle >= HCI_MAX_CONN)
- return NULL;
+ struct hci_conn *conn;
conn_hash_lock(h);
conn = __conn_hash_lookup(h, handle);
conn_hash_unlock(h);
-
return conn;
}
-struct hci_dev;
-
-/* ----- HCI Connections ----- */
-struct hci_conn {
- bdaddr_t dst;
- __u16 handle;
-
- unsigned int acl_sent;
- unsigned int sco_sent;
-
- struct hci_dev *hdev;
- void *l2cap_data;
- void *priv;
-
- struct sk_buff_head acl_q;
- struct sk_buff_head sco_q;
-};
-
/* ----- HCI Devices ----- */
struct hci_dev {
atomic_t refcnt;
__u16 id;
__u8 type;
bdaddr_t bdaddr;
+ __u8 features[8];
+
+ __u16 pkt_type;
atomic_t cmd_cnt;
unsigned int acl_cnt;
struct sk_buff_head rx_q;
struct sk_buff_head raw_q;
struct sk_buff_head cmd_q;
- struct sk_buff *cmd_sent;
+
+ struct sk_buff *sent_cmd;
struct semaphore req_lock;
wait_queue_head_t req_wait_q;
int (*send)(struct sk_buff *skb);
};
-static __inline__ void hci_dev_hold(struct hci_dev *hdev)
+static inline void hci_dev_hold(struct hci_dev *hdev)
{
atomic_inc(&hdev->refcnt);
}
-static __inline__ void hci_dev_put(struct hci_dev *hdev)
+static inline void hci_dev_put(struct hci_dev *hdev)
{
atomic_dec(&hdev->refcnt);
}
extern struct hci_dev *hci_dev_get(int index);
-
-#define SENT_CMD_PARAM(X) (((X->cmd_sent->data) + HCI_COMMAND_HDR_SIZE))
-
extern int hci_register_dev(struct hci_dev *hdev);
extern int hci_unregister_dev(struct hci_dev *hdev);
extern int hci_dev_open(__u16 dev);
extern int hci_dev_list(unsigned long arg);
extern int hci_dev_setscan(unsigned long arg);
extern int hci_dev_setauth(unsigned long arg);
+extern int hci_dev_setptype(unsigned long arg);
+extern int hci_conn_list(unsigned long arg);
extern int hci_inquiry(unsigned long arg);
extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
extern int hci_recv_frame(struct sk_buff *skb);
+/* ----- LMP capabilities ----- */
+#define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
+
/* ----- HCI tasks ----- */
-static __inline__ void hci_sched_cmd(struct hci_dev *hdev)
+static inline void hci_sched_cmd(struct hci_dev *hdev)
{
tasklet_schedule(&hdev->cmd_task);
}
-static __inline__ void hci_sched_rx(struct hci_dev *hdev)
+static inline void hci_sched_rx(struct hci_dev *hdev)
{
tasklet_schedule(&hdev->rx_task);
}
-static __inline__ void hci_sched_tx(struct hci_dev *hdev)
+static inline void hci_sched_tx(struct hci_dev *hdev)
{
tasklet_schedule(&hdev->tx_task);
}
/* HCI info for socket */
#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
struct hci_pinfo {
- struct hci_dev *hdev;
- __u32 cmsg_flags;
- __u32 mask;
+ struct hci_dev *hdev;
+ struct hci_filter filter;
+ __u32 cmsg_mask;
};
/* ----- HCI requests ----- */
#define HCI_REQ_PEND 1
#define HCI_REQ_CANCELED 2
-#endif /* __IF_HCI_CORE_H */
+#endif /* __HCI_CORE_H */
+++ /dev/null
-/*
- BlueZ - Bluetooth protocol stack for Linux
- Copyright (C) 2000-2001 Qualcomm Incorporated
-
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
- SOFTWARE IS DISCLAIMED.
-*/
-
-/*
- * $Id: hci_emu.h,v 1.1 2001/06/01 08:12:11 davem Exp $
- */
-
-#ifndef __IF_HCI_EMU_H
-#define __IF_HCI_EMU_H
-
-#ifdef __KERNEL__
-
-struct hci_emu_struct {
- struct hci_dev hdev;
- __u32 flags;
- wait_queue_head_t read_wait;
- struct sk_buff_head readq;
- struct fasync_struct *fasync;
-};
-
-#endif /* __KERNEL__ */
-
-#define HCI_EMU_MINOR 250
-
-/* Max frame size */
-#define HCI_EMU_MAX_FRAME 4096
-
-/* HCI_EMU device flags */
-#define HCI_EMU_FASYNC 0x0010
-
-#endif /* __IF_HCI_EMU_H */
*/
/*
- * $Id: hci_uart.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_uart.h,v 1.2 2001/06/02 01:40:08 maxk Exp $
*/
-#define HCI_MAX_READ 2048
+#ifndef N_HCI
+#define N_HCI 15
+#endif
#ifdef __KERNEL__
*/
/*
- * $Id: hci_usb.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_usb.h,v 1.3 2001/06/02 01:40:08 maxk Exp $
*/
#ifdef __KERNEL__
-#define HCI_USB_MAX_READ 2048
-
/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
#define HCI_DEV_CLASS 0xe0 /* Wireless class */
#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
--- /dev/null
+/*
+ BlueZ - Bluetooth protocol stack for Linux
+ Copyright (C) 2000-2001 Qualcomm Incorporated
+
+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation;
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
+ SOFTWARE IS DISCLAIMED.
+*/
+
+/*
+ * $Id: hci_vhci.h,v 1.2 2001/08/01 01:02:20 maxk Exp $
+ */
+
+#ifndef __HCI_VHCI_H
+#define __HCI_VHCI_H
+
+#ifdef __KERNEL__
+
+struct hci_vhci_struct {
+ struct hci_dev hdev;
+ __u32 flags;
+ wait_queue_head_t read_wait;
+ struct sk_buff_head readq;
+ struct fasync_struct *fasync;
+};
+
+/* VHCI device flags */
+#define VHCI_FASYNC 0x0010
+
+#endif /* __KERNEL__ */
+
+#define VHCI_DEV "/dev/vhci"
+#define VHCI_MINOR 250
+
+#endif /* __HCI_VHCI_H */
*/
/*
- * $Id: l2cap.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: l2cap.h,v 1.5 2001/06/14 21:28:26 maxk Exp $
*/
#ifndef __L2CAP_H
#include <asm/types.h>
#include <asm/byteorder.h>
+/* L2CAP defaults */
+#define L2CAP_DEFAULT_MTU 672
+#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
+
+#define L2CAP_CONN_TIMEOUT (HZ * 40)
+#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
+#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
+
/* L2CAP socket address */
struct sockaddr_l2 {
sa_family_t l2_family;
__u32 delay_var;
};
-/* L2CAP defaults */
-#define L2CAP_DEFAULT_MTU 672
-#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-
-#define L2CAP_CONN_TIMEOUT (HZ * 40)
+#define L2CAP_CONNINFO 0x02
+struct l2cap_conninfo {
+ __u16 hci_handle;
+};
/* L2CAP command codes */
#define L2CAP_COMMAND_REJ 0x01
*/
/*
- * $Id: l2cap_core.h,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: l2cap_core.h,v 1.6 2001/08/03 04:19:49 maxk Exp $
*/
#ifndef __L2CAP_CORE_H
struct list_head conn_list;
};
-static __inline__ void l2cap_iff_lock(struct l2cap_iff *iff)
+static inline void l2cap_iff_lock(struct l2cap_iff *iff)
{
spin_lock(&iff->lock);
}
-static __inline__ void l2cap_iff_unlock(struct l2cap_iff *iff)
+static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
{
spin_unlock(&iff->lock);
}
__u8 tx_ident;
struct l2cap_chan_list chan_list;
+
+ struct timer_list timer;
};
-static __inline__ void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
+static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
{
list_add(&c->list, &iff->conn_list);
}
-static __inline__ void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
+static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
{
list_del(&c->list);
}
struct l2cap_accept_q accept_q;
};
-#define CONF_INPUT 0x01
-#define CONF_OUTPUT 0x02
-#define CONF_DONE (CONF_INPUT | CONF_OUTPUT)
+#define CONF_REQ_SENT 0x01
+#define CONF_INPUT_DONE 0x02
+#define CONF_OUTPUT_DONE 0x04
extern struct bluez_sock_list l2cap_sk_list;
extern struct list_head l2cap_iff_list;
Version 2 and 3 extensions to driver:
* Copyright (C) 1998 - 2001 Douglas Gilbert
- Version: 3.1.19 (20010623)
+ Version: 3.1.20 (20010814)
This version is for 2.4 series kernels.
+ Changes since 3.1.19 (20010623)
+ - add SG_GET_ACCESS_COUNT ioctl
+ - make open() increment and close() decrement access_count
+ - only register first 256 devices, reject subsequent devices
Changes since 3.1.18 (20010505)
- fix bug that caused long wait when large buffer requested
- fix leak in error case of sg_new_read() [report: Eric Barton]
#define SG_SET_KEEP_ORPHAN 0x2287 /* 1 -> hold for read(), 0 -> drop (def) */
#define SG_GET_KEEP_ORPHAN 0x2288
+/* yields scsi midlevel's access_count for this SCSI device */
+#define SG_GET_ACCESS_COUNT 0x2289
+
#define SG_SCATTER_SZ (8 * 4096) /* PAGE_SIZE not available to user */
/* Largest size (in bytes) a single scatter-gather list element can have.
EXPORT_SYMBOL(refile_buffer);
EXPORT_SYMBOL(max_sectors);
EXPORT_SYMBOL(max_readahead);
-EXPORT_SYMBOL(file_moveto);
/* tty routines */
EXPORT_SYMBOL(tty_hangup);
/*
* BlueZ Bluetooth address family and sockets.
*
- * $Id: af_bluetooth.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: af_bluetooth.c,v 1.4 2001/07/05 18:42:44 maxk Exp $
*/
+#define VERSION "1.1"
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
int bluez_init(void)
{
INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- BLUEZ_VER);
+ VERSION);
INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
proc_mkdir("bluetooth", NULL);
#ifdef MODULE
module_init(bluez_init);
module_exit(bluez_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
#endif
/*
* BlueZ HCI Core.
*
- * $Id: hci_core.c,v 1.2 2001/06/01 16:57:03 davem Exp $
+ * $Id: hci_core.c,v 1.22 2001/08/03 04:19:50 maxk Exp $
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
+#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/bluez.h>
return notifier_chain_unregister(&hci_dev_notifier, nb);
}
-static __inline__ void hci_notify(struct hci_dev *hdev, int event)
+static inline void hci_notify(struct hci_dev *hdev, int event)
{
notifier_call_chain(&hci_dev_notifier, event, hdev);
}
}
/* --------- BaseBand connections --------- */
-static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, bdaddr_t *dst)
+static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
{
struct hci_conn *conn;
DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
- if (handle > HCI_MAX_CONN) {
- ERR("%s BUG handle %d is to large", hdev->name, handle);
+ if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
+ ERR("%s handle 0x%x already exists", hdev->name, handle);
return NULL;
}
bacpy(&conn->dst, dst);
conn->handle = handle;
+ conn->type = type;
conn->hdev = hdev;
- skb_queue_head_init(&conn->acl_q);
- skb_queue_head_init(&conn->sco_q);
+ skb_queue_head_init(&conn->data_q);
- if (conn_hash_add(&hdev->conn_hash, handle, conn)) {
- hci_dev_hold(hdev);
- return conn;
- } else {
- kfree(conn);
- return NULL;
- }
+ hci_dev_hold(hdev);
+ conn_hash_add(&hdev->conn_hash, handle, conn);
+
+ return conn;
}
static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
{
DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
- if (conn_hash_del(&hdev->conn_hash, conn->handle)) {
- hci_dev_put(hdev);
+ conn_hash_del(&hdev->conn_hash, conn);
+ hci_dev_put(hdev);
- /* Unacked frames */
- hdev->acl_cnt += conn->acl_sent;
- }
+ /* Unacked frames */
+ hdev->acl_cnt += conn->sent;
- bluez_skb_queue_purge(&conn->acl_q);
- bluez_skb_queue_purge(&conn->sco_q);
+ skb_queue_purge(&conn->data_q);
kfree(conn);
return 0;
/* Drop all connection on the device */
static void hci_conn_hash_flush(struct hci_dev *hdev)
{
- struct hci_proto *hp = GET_HPROTO(HCI_PROTO_L2CAP);
struct conn_hash *h = &hdev->conn_hash;
- int i;
+ struct hci_proto *hp;
+ struct list_head *p;
DBG("hdev %s", hdev->name);
- for (i = 0; i < HCI_MAX_CONN; i++) {
- struct hci_conn *conn;
+ p = h->list.next;
+ while (p != &h->list) {
+ struct hci_conn *c;
- if (!(conn = conn_hash_lookup(h, i)))
- continue;
+ c = list_entry(p, struct hci_conn, list);
+ p = p->next;
- if (hp && hp->disconn_ind)
- hp->disconn_ind(conn, 0x16);
-
- hci_conn_del(hdev, conn);
+ if (c->type == ACL_LINK) {
+ /* ACL link notify L2CAP layer */
+ if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
+ hp->disconn_ind(c, 0x16);
+ } else {
+ /* SCO link (no notification) */
+ }
+
+ hci_conn_del(hdev, c);
}
}
inquiry_cache_unlock_bh(cache);
bacpy(&cc.bdaddr, bdaddr);
- cc.pkt_type = __cpu_to_le16(HCI_DM1 | HCI_DM3 | HCI_DM5 | HCI_DH1 | HCI_DH3 | HCI_DH5);
+ cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
cc.clock_offset = __cpu_to_le16(clock_offset);
- cc.role_switch = 0;
+
+ if (lmp_rswitch_capable(hdev))
+ cc.role_switch = 0x01;
+ else
+ cc.role_switch = 0x00;
+
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
return 0;
}
/* --------- HCI request handling ------------ */
-static __inline__ void hci_req_lock(struct hci_dev *hdev)
+static inline void hci_req_lock(struct hci_dev *hdev)
{
down(&hdev->req_lock);
}
-static __inline__ void hci_req_unlock(struct hci_dev *hdev)
+static inline void hci_req_unlock(struct hci_dev *hdev)
{
up(&hdev->req_lock);
}
-static __inline__ void hci_req_complete(struct hci_dev *hdev, int result)
+static inline void hci_req_complete(struct hci_dev *hdev, int result)
{
DBG("%s result 0x%2.2x", hdev->name, result);
}
}
-static __inline__ void hci_req_cancel(struct hci_dev *hdev, int err)
+static inline void hci_req_cancel(struct hci_dev *hdev, int err)
{
DBG("%s err 0x%2.2x", hdev->name, err);
return err;
}
-static __inline__ int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
+static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
unsigned long opt, __u32 timeout)
{
int ret;
/* Mandatory initialization */
+ /* Read Local Supported Features */
+ hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
+
/* Read Buffer Size (ACL mtu, max pkt, etc.) */
hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
/* Clear Event Filters */
ec.flt_type = FLT_CLEAR_ALL;
- ec.cond_type = 0;
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, SET_EVENT_FLT_CP_SIZE, &ec);
+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
- /* Page timeout ~ 20 secs */
+ /* Page timeout ~20 secs */
param = __cpu_to_le16(0x8000);
hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_PG_TIMEOUT, 2, ¶m);
hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
}
-/* Open HCI device */
+/* HCI ioctl helpers */
int hci_dev_open(__u16 dev)
{
struct hci_dev *hdev;
goto done;
}
- /* Initialize device */
if (hdev->open(hdev)) {
ret = -EIO;
goto done;
}
- atomic_set(&hdev->cmd_cnt, 1);
- hdev->cmd_sent= NULL;
- hdev->flags |= HCI_INIT;
+ if (hdev->flags & HCI_NORMAL) {
+ atomic_set(&hdev->cmd_cnt, 1);
+ hdev->flags |= HCI_INIT;
- __hci_request(hdev, hci_reset_req, 0, HZ);
+ //__hci_request(hdev, hci_reset_req, 0, HZ);
+ ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
+
+ hdev->flags &= ~HCI_INIT;
+ }
- if (!(ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT))) {
+ if (!ret) {
hdev->flags |= HCI_UP;
hci_notify(hdev, HCI_DEV_UP);
- }
+ } else {
+ /* Init failed, cleanup */
+ tasklet_kill(&hdev->rx_task);
+ tasklet_kill(&hdev->tx_task);
+ tasklet_kill(&hdev->cmd_task);
- hdev->flags &= ~HCI_INIT;
+ skb_queue_purge(&hdev->cmd_q);
+ skb_queue_purge(&hdev->rx_q);
+
+ if (hdev->flush)
+ hdev->flush(hdev);
+
+ if (hdev->sent_cmd) {
+ kfree_skb(hdev->sent_cmd);
+ hdev->sent_cmd = NULL;
+ }
+
+ hdev->close(hdev);
+ }
done:
hci_req_unlock(hdev);
return ret;
}
-/* Close HCI device */
int hci_dev_close(__u16 dev)
{
struct hci_dev *hdev;
hci_conn_hash_flush(hdev);
/* Clear flags */
- hdev->flags &= (HCI_NORMAL | HCI_SOCK);
+ hdev->flags &= HCI_SOCK;
+ hdev->flags |= HCI_NORMAL;
hci_notify(hdev, HCI_DEV_DOWN);
hdev->flush(hdev);
/* Reset device */
- bluez_skb_queue_purge(&hdev->cmd_q);
+ skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
hdev->flags |= HCI_INIT;
__hci_request(hdev, hci_reset_req, 0, HZ);
tasklet_kill(&hdev->cmd_task);
/* Drop queues */
- bluez_skb_queue_purge(&hdev->rx_q);
- bluez_skb_queue_purge(&hdev->cmd_q);
- bluez_skb_queue_purge(&hdev->raw_q);
+ skb_queue_purge(&hdev->rx_q);
+ skb_queue_purge(&hdev->cmd_q);
+ skb_queue_purge(&hdev->raw_q);
/* Drop last sent command */
- if (hdev->cmd_sent) {
- bluez_skb_free(hdev->cmd_sent);
- hdev->cmd_sent = NULL;
+ if (hdev->sent_cmd) {
+ kfree_skb(hdev->sent_cmd);
+ hdev->sent_cmd = NULL;
}
/* After this point our queues are empty
return 0;
}
+int hci_dev_reset(__u16 dev)
+{
+ struct hci_dev *hdev;
+ int ret = 0;
+
+ if (!(hdev = hci_dev_get(dev)))
+ return -ENODEV;
+
+ hci_req_lock(hdev);
+ tasklet_disable(&hdev->tx_task);
+
+ if (!(hdev->flags & HCI_UP))
+ goto done;
+
+ /* Drop queues */
+ skb_queue_purge(&hdev->rx_q);
+ skb_queue_purge(&hdev->cmd_q);
+
+ inquiry_cache_flush(&hdev->inq_cache);
+
+ hci_conn_hash_flush(hdev);
+
+ if (hdev->flush)
+ hdev->flush(hdev);
+
+ atomic_set(&hdev->cmd_cnt, 1);
+ hdev->acl_cnt = 0; hdev->sco_cnt = 0;
+
+ ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
+
+done:
+ tasklet_enable(&hdev->tx_task);
+ hci_req_unlock(hdev);
+ hci_dev_put(hdev);
+
+ return ret;
+}
+
+int hci_dev_reset_stat(__u16 dev)
+{
+ struct hci_dev *hdev;
+ int ret = 0;
+
+ if (!(hdev = hci_dev_get(dev)))
+ return -ENODEV;
+
+ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
+
+ hci_dev_put(hdev);
+
+ return ret;
+}
+
+int hci_dev_setauth(unsigned long arg)
+{
+ struct hci_dev *hdev;
+ struct hci_dev_req dr;
+ int ret = 0;
+
+ if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+ return -EFAULT;
+
+ if (!(hdev = hci_dev_get(dr.dev_id)))
+ return -ENODEV;
+
+ ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
+
+ hci_dev_put(hdev);
+
+ return ret;
+}
+
+int hci_dev_setscan(unsigned long arg)
+{
+ struct hci_dev *hdev;
+ struct hci_dev_req dr;
+ int ret = 0;
+
+ if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+ return -EFAULT;
+
+ if (!(hdev = hci_dev_get(dr.dev_id)))
+ return -ENODEV;
+
+ ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
+
+ hci_dev_put(hdev);
+
+ return ret;
+}
+
+int hci_dev_setptype(unsigned long arg)
+{
+ struct hci_dev *hdev;
+ struct hci_dev_req dr;
+ int ret = 0;
+
+ if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
+ return -EFAULT;
+
+ if (!(hdev = hci_dev_get(dr.dev_id)))
+ return -ENODEV;
+
+ hdev->pkt_type = (__u16) dr.dev_opt;
+
+ hci_dev_put(hdev);
+
+ return ret;
+}
+
+int hci_dev_list(unsigned long arg)
+{
+ struct hci_dev_list_req *dl;
+ struct hci_dev_req *dr;
+ struct hci_dev *hdev;
+ int i, n, size;
+ __u16 dev_num;
+
+ if (get_user(dev_num, (__u16 *) arg))
+ return -EFAULT;
+
+ size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
+
+ if (verify_area(VERIFY_WRITE, (void *) arg, size))
+ return -EFAULT;
+
+ if (!(dl = kmalloc(size, GFP_KERNEL)))
+ return -ENOMEM;
+ dr = dl->dev_req;
+
+ spin_lock_bh(&hdev_list_lock);
+ for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
+ if ((hdev = hdev_list[i])) {
+ (dr + n)->dev_id = hdev->id;
+ (dr + n)->dev_opt = hdev->flags;
+ n++;
+ }
+ }
+ spin_unlock_bh(&hdev_list_lock);
+
+ dl->dev_num = n;
+ size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
+
+ copy_to_user((void *) arg, dl, size);
+
+ return 0;
+}
+
+int hci_dev_info(unsigned long arg)
+{
+ struct hci_dev *hdev;
+ struct hci_dev_info di;
+ int err = 0;
+
+ if (copy_from_user(&di, (void *) arg, sizeof(di)))
+ return -EFAULT;
+
+ if (!(hdev = hci_dev_get(di.dev_id)))
+ return -ENODEV;
+
+ strcpy(di.name, hdev->name);
+ di.bdaddr = hdev->bdaddr;
+ di.type = hdev->type;
+ di.flags = hdev->flags;
+ di.pkt_type = hdev->pkt_type;
+ di.acl_mtu = hdev->acl_mtu;
+ di.acl_max = hdev->acl_max;
+ di.sco_mtu = hdev->sco_mtu;
+ di.sco_max = hdev->sco_max;
+
+ memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
+ memcpy(&di.features, &hdev->features, sizeof(di.features));
+
+ if (copy_to_user((void *) arg, &di, sizeof(di)))
+ err = -EFAULT;
+
+ hci_dev_put(hdev);
+
+ return err;
+}
+
+__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
+{
+ __u32 omode = hdev->flags & HCI_MODE_MASK;
+
+ hdev->flags &= ~HCI_MODE_MASK;
+ hdev->flags |= (mode & HCI_MODE_MASK);
+
+ return omode;
+}
+
+__u32 hci_dev_getmode(struct hci_dev *hdev)
+{
+ return hdev->flags & HCI_MODE_MASK;
+}
+
+int hci_conn_list(unsigned long arg)
+{
+ struct hci_conn_list_req req, *cl;
+ struct hci_conn_info *ci;
+ struct hci_dev *hdev;
+ struct list_head *p;
+ int n = 0, size;
+
+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
+ return -EFAULT;
+
+ if (!(hdev = hci_dev_get(req.dev_id)))
+ return -ENODEV;
+
+ size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
+
+ if (verify_area(VERIFY_WRITE, (void *)arg, size))
+ return -EFAULT;
+
+ if (!(cl = kmalloc(size, GFP_KERNEL)))
+ return -ENOMEM;
+ ci = cl->conn_info;
+
+ local_bh_disable();
+ conn_hash_lock(&hdev->conn_hash);
+ list_for_each(p, &hdev->conn_hash.list) {
+ register struct hci_conn *c;
+ c = list_entry(p, struct hci_conn, list);
+
+ (ci + n)->handle = c->handle;
+ bacpy(&(ci + n)->bdaddr, &c->dst);
+ n++;
+ }
+ conn_hash_unlock(&hdev->conn_hash);
+ local_bh_enable();
+
+ cl->dev_id = hdev->id;
+ cl->conn_num = n;
+ size = n * sizeof(struct hci_conn_info) + sizeof(req);
+
+ copy_to_user((void *) arg, cl, size);
+
+ hci_dev_put(hdev);
+
+ return 0;
+}
+
+int hci_inquiry(unsigned long arg)
+{
+ struct inquiry_cache *cache;
+ struct hci_inquiry_req ir;
+ struct hci_dev *hdev;
+ int err = 0, do_inquiry = 0;
+ long timeo;
+ __u8 *buf, *ptr;
+
+ ptr = (void *) arg;
+ if (copy_from_user(&ir, ptr, sizeof(ir)))
+ return -EFAULT;
+
+ if (!(hdev = hci_dev_get(ir.dev_id)))
+ return -ENODEV;
+
+ cache = &hdev->inq_cache;
+
+ inquiry_cache_lock(cache);
+ if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
+ inquiry_cache_flush(cache);
+ do_inquiry = 1;
+ }
+ inquiry_cache_unlock(cache);
+
+ timeo = ir.length * 2 * HZ;
+ if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
+ goto done;
+
+ /* cache_dump can't sleep. Therefore we allocate temp buffer and then
+ * copy it to the user space.
+ */
+ if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
+ err = -ENOMEM;
+ goto done;
+ }
+ ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
+
+ DBG("num_rsp %d", ir.num_rsp);
+
+ if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
+ copy_to_user(ptr, &ir, sizeof(ir));
+ ptr += sizeof(ir);
+ copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
+ } else
+ err = -EFAULT;
+
+ kfree(buf);
+
+done:
+ hci_dev_put(hdev);
+
+ return err;
+}
+
/* Interface to HCI drivers */
/* Register HCI device */
hdev->id = i;
hdev->flags = HCI_NORMAL;
+ hdev->pkt_type = (HCI_DM1 | HCI_DH1);
+
tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev) {
- bluez_skb_free(skb);
+ kfree_skb(skb);
return -ENODEV;
}
return hdev->send(skb);
}
-/* ACL scheduler */
-static __inline__ struct hci_conn *hci_low_acl_sent(struct hci_dev *hdev, int *quote)
+/* Connection scheduler */
+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
{
struct conn_hash *h = &hdev->conn_hash;
struct hci_conn *conn = NULL;
- int i, num = 0, min = 0xffff;
+ int num = 0, min = 0xffff;
+ struct list_head *p;
conn_hash_lock(h);
- for (i = 0; i < HCI_MAX_CONN; i++) {
- struct hci_conn *c;
+ list_for_each(p, &h->list) {
+ register struct hci_conn *c;
- if (!(c = __conn_hash_lookup(h,i)) || !skb_queue_len(&c->acl_q))
+ c = list_entry(p, struct hci_conn, list);
+
+ if (c->type != type || skb_queue_empty(&c->data_q))
continue;
num++;
- if (c->acl_sent < min) {
- min = c->acl_sent;
+ if (c->sent < min) {
+ min = c->sent;
conn = c;
}
}
return conn;
}
-static __inline__ void hci_sched_acl(struct hci_dev *hdev)
+static inline void hci_sched_acl(struct hci_dev *hdev)
{
struct hci_conn *conn;
- struct sk_buff *skb, *frag;
+ struct sk_buff *skb;
int quote;
DBG("%s", hdev->name);
- while (hdev->acl_cnt) {
- if (!(conn = hci_low_acl_sent(hdev, "e)))
- break;
-
- while (quote && (skb = skb_peek(&conn->acl_q))) {
- if (bluez_skb_frags(skb)+1 > hdev->acl_cnt) {
- /* FIXME: Schedule next connection */
- goto done;
- }
-
- if (!(frag = bluez_skb_clone(skb, GFP_ATOMIC)))
- break;
-
- skb_unlink(skb);
- do {
- DBG("frag %p len %d", frag, frag->len);
+ while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) {
+ while (quote && (skb = skb_dequeue(&conn->data_q))) {
+ DBG("skb %p len %d", skb, skb->len);
- hci_send_frame(frag);
+ hci_send_frame(skb);
- conn->acl_sent++;
- hdev->acl_cnt--;
- quote--;
- } while ((frag = bluez_skb_get_frag(skb)));
- kfree_skb(skb);
+ conn->sent++;
+ hdev->acl_cnt--;
+ quote--;
}
}
-done:
- return;
}
/* Schedule SCO */
-static __inline__ void hci_sched_sco(struct hci_dev *hdev)
+static inline void hci_sched_sco(struct hci_dev *hdev)
{
- struct conn_hash *h = &hdev->conn_hash;
- struct sk_buff *skb;
- int i;
+ /* FIXME: For now we queue SCO packets to the raw queue
- DBG("%s", hdev->name);
-
- conn_hash_lock(h);
- for (i = 0; i< HCI_MAX_CONN; i++) {
- struct hci_conn *conn;
-
- if (!(conn = __conn_hash_lookup(h, i)))
- continue;
-
- while (hdev->sco_cnt && (skb = skb_dequeue(&conn->sco_q))) {
+ while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
hci_send_frame(skb);
conn->sco_sent++;
hdev->sco_cnt--;
}
- }
- conn_hash_unlock(h);
+ */
+}
+
+/* Get data from the previously sent command */
+static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
+{
+ hci_command_hdr *hc;
+
+ if (!hdev->sent_cmd)
+ return NULL;
+
+ hc = (void *) hdev->sent_cmd->data;
+
+ if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
+ return NULL;
+
+ DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+
+ return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
}
/* Send raw HCI frame */
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev) {
- bluez_skb_free(skb);
+ kfree_skb(skb);
return -ENODEV;
}
DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
- /* Queue frame according it's type */
- switch (skb->pkt_type) {
- case HCI_COMMAND_PKT:
- skb_queue_tail(&hdev->cmd_q, skb);
- hci_sched_cmd(hdev);
- break;
-
- case HCI_ACLDATA_PKT:
- case HCI_SCODATA_PKT:
- /* FIXME:
- * Check header here and queue to aproptiate connection.
- */
- default:
- skb_queue_tail(&hdev->raw_q, skb);
- hci_sched_tx(hdev);
+ if (hdev->flags & HCI_NORMAL) {
+ /* Queue frame according it's type */
+ switch (skb->pkt_type) {
+ case HCI_COMMAND_PKT:
+ skb_queue_tail(&hdev->cmd_q, skb);
+ hci_sched_cmd(hdev);
+ return 0;
- return 0;
- };
+ case HCI_ACLDATA_PKT:
+ case HCI_SCODATA_PKT:
+ /* FIXME:
+ * Check header here and queue to apropriate connection.
+ */
+ break;
+ }
+ }
+ skb_queue_tail(&hdev->raw_q, skb);
+ hci_sched_tx(hdev);
return 0;
}
}
hc = (hci_command_hdr *) skb_put(skb, HCI_COMMAND_HDR_SIZE);
- hc->opcode = __cpu_to_le16(cmd_opcode_pack(ocf, ogf));
+ hc->opcode = __cpu_to_le16(cmd_opcode_pack(ogf, ocf));
hc->plen = plen;
if (plen)
}
/* Send ACL data */
-
static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
{
int len = skb->len;
int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags)
{
struct hci_dev *hdev = conn->hdev;
- struct sk_buff *frag;
- int sent = 0;
+ struct sk_buff *list;
- DBG("%s conn %p len %d flags 0x%x", hdev->name, conn, skb->len, flags);
- DBG("frags %d", bluez_skb_frags(skb));
+ DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
- /* Add ACL header to all fragments */
- flags |= ACL_START;
- frag = skb;
- do {
- DBG("frag %p len %d", frag, frag->len);
- sent += frag->len;
+ skb->dev = (void *) hdev;
+ skb->pkt_type = HCI_ACLDATA_PKT;
+ hci_add_acl_hdr(skb, conn->handle, flags | ACL_START);
- hci_add_acl_hdr(frag, conn->handle, flags);
- frag->pkt_type = HCI_ACLDATA_PKT;
- frag->dev = (void *) hdev;
+ if (!(list = skb_shinfo(skb)->frag_list)) {
+ /* Non fragmented */
+ DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
+
+ skb_queue_tail(&conn->data_q, skb);
+ } else {
+ /* Fragmented */
+ DBG("%s frag %p len %d", hdev->name, skb, skb->len);
- flags = ACL_CONT;
- } while ((frag = bluez_skb_next_frag(frag)));
+ skb_shinfo(skb)->frag_list = NULL;
- skb_queue_tail(&conn->acl_q, skb);
- hci_sched_tx(hdev);
+ /* Queue all fragments atomically */
+ spin_lock_bh(&conn->data_q.lock);
+
+ __skb_queue_tail(&conn->data_q, skb);
+ do {
+ skb = list; list = list->next;
+
+ skb->dev = (void *) hdev;
+ skb->pkt_type = HCI_ACLDATA_PKT;
+ hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
+
+ DBG("%s frag %p len %d", hdev->name, skb, skb->len);
- return sent;
+ __skb_queue_tail(&conn->data_q, skb);
+ } while (list);
+
+ spin_unlock_bh(&conn->data_q.lock);
+ }
+
+ hci_sched_tx(hdev);
+ return 0;
}
/* Send SCO data */
DBG("%s len %d", hdev->name, skb->len);
if (skb->len > hdev->sco_mtu) {
- bluez_skb_free(skb);
+ kfree_skb(skb);
return -EINVAL;
}
skb->dev = (void *) hdev;
skb->pkt_type = HCI_SCODATA_PKT;
- skb_queue_tail(&conn->sco_q, skb);
+ skb_queue_tail(&conn->data_q, skb);
hci_sched_tx(hdev);
return 0;
static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
{
__u8 status, param;
+ void *sent;
+
DBG("%s ocf 0x%x", hdev->name, ocf);
break;
case OCF_WRITE_AUTH_ENABLE:
+ if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
+ break;
+
status = *((__u8 *) skb->data);
- param = *(SENT_CMD_PARAM(hdev));
+ param = *((__u8 *) sent);
if (!status) {
if (param == AUTH_ENABLED)
break;
case OCF_WRITE_SCAN_ENABLE:
+ if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
+ break;
status = *((__u8 *) skb->data);
- param = *(SENT_CMD_PARAM(hdev));
+ param = *((__u8 *) sent);
+
+ DBG("param 0x%x", param);
if (!status) {
switch (param) {
/* Command Complete OGF INFO_PARAM */
static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
{
- read_buffer_size_rp *rsp;
- read_bd_addr_rp *rap;
+ read_local_features_rp *lf;
+ read_buffer_size_rp *bs;
+ read_bd_addr_rp *ba;
DBG("%s ocf 0x%x", hdev->name, ocf);
switch (ocf) {
+ case OCF_READ_LOCAL_FEATURES:
+ lf = (read_local_features_rp *) skb->data;
+
+ if (lf->status) {
+ DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
+ break;
+ }
+
+ memcpy(hdev->features, lf->features, sizeof(hdev->features));
+
+ /* Adjust default settings according to features
+ * supported by device. */
+ if (hdev->features[0] & LMP_3SLOT)
+ hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
+
+ if (hdev->features[0] & LMP_5SLOT)
+ hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
+
+ DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
+
+ break;
+
case OCF_READ_BUFFER_SIZE:
- rsp = (read_buffer_size_rp *) skb->data;
+ bs = (read_buffer_size_rp *) skb->data;
- if (rsp->status) {
- DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, rsp->status);
+ if (bs->status) {
+ DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
break;
}
- hdev->acl_mtu = __le16_to_cpu(rsp->acl_mtu);
- hdev->sco_mtu = rsp->sco_mtu;
- hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(rsp->acl_max_pkt);
- hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(rsp->sco_max_pkt);
+ hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
+ hdev->sco_mtu = bs->sco_mtu;
+ hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
+ hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
break;
case OCF_READ_BD_ADDR:
- rap = (read_bd_addr_rp *) skb->data;
+ ba = (read_bd_addr_rp *) skb->data;
- if (!rap->status) {
- bacpy(&hdev->bdaddr, &rap->bdaddr);
+ if (!ba->status) {
+ bacpy(&hdev->bdaddr, &ba->bdaddr);
} else {
- DBG("%s: READ_BD_ADDR failed %d", hdev->name, rap->status);
+ DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
}
- hci_req_complete(hdev, rap->status);
+ hci_req_complete(hdev, ba->status);
break;
default:
switch (ocf) {
case OCF_CREATE_CONN:
if (status) {
- create_conn_cp *cc = (void *) SENT_CMD_PARAM(hdev);
+ create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
+
+ if (!cc)
+ break;
+
DBG("%s Create connection error: status 0x%x %s", hdev->name,
status, batostr(&cc->bdaddr));
accept_conn_req_cp ac;
int accept = 0;
- DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->type);
+ DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
/* Notify upper protocols */
- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
- tasklet_disable(&hdev->tx_task);
- accept = hp->connect_ind(hdev, &cr->bdaddr);
- tasklet_enable(&hdev->tx_task);
+ if (cr->link_type == ACL_LINK) {
+ /* ACL link notify L2CAP */
+ if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
+ tasklet_disable(&hdev->tx_task);
+ accept = hp->connect_ind(hdev, &cr->bdaddr);
+ tasklet_enable(&hdev->tx_task);
+ }
+ } else {
+ /* SCO link (no notification) */
+ /* FIXME: Should be accept it here or let the requester (app) accept it ? */
+ accept = 1;
}
if (accept) {
tasklet_disable(&hdev->tx_task);
if (!cc->status)
- conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), &cc->bdaddr);
+ conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
/* Notify upper protocols */
- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
- hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
+ if (cc->link_type == ACL_LINK) {
+ /* ACL link notify L2CAP layer */
+ if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
+ hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
+ } else {
+ /* SCO link (no notification) */
+ }
tasklet_enable(&hdev->tx_task);
}
tasklet_disable(&hdev->tx_task);
/* Notify upper protocols */
- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
- hp->disconn_ind(conn, dc->reason);
+ if (conn->type == ACL_LINK) {
+ /* ACL link notify L2CAP layer */
+ if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
+ hp->disconn_ind(conn, dc->reason);
+ } else {
+ /* SCO link (no notification) */
+ }
hci_conn_del(hdev, conn);
struct hci_conn *conn;
__u16 handle, count;
- handle = __le16_to_cpu(*ptr++);
- count = __le16_to_cpu(*ptr++);
+ handle = __le16_to_cpu(get_unaligned(ptr++));
+ count = __le16_to_cpu(get_unaligned(ptr++));
hdev->acl_cnt += count;
if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
- conn->acl_sent -= count;
+ conn->sent -= count;
}
tasklet_enable(&hdev->tx_task);
hci_sched_tx(hdev);
}
-static __inline__ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
hci_event_hdr *he = (hci_event_hdr *) skb->data;
evt_cmd_status *cs;
ogf = cmd_opcode_ogf(opcode);
ocf = cmd_opcode_ocf(opcode);
- if (cs->ncmd) {
- atomic_set(&hdev->cmd_cnt, 1);
- hci_sched_cmd(hdev);
- }
-
switch (ogf) {
case OGF_INFO_PARAM:
hci_cs_info_param(hdev, ocf, cs->status);
break;
};
+ if (cs->ncmd) {
+ atomic_set(&hdev->cmd_cnt, 1);
+ if (!skb_queue_empty(&hdev->cmd_q))
+ hci_sched_cmd(hdev);
+ }
break;
case EVT_CMD_COMPLETE:
ogf = cmd_opcode_ogf(opcode);
ocf = cmd_opcode_ocf(opcode);
- if (ec->ncmd) {
- atomic_set(&hdev->cmd_cnt, 1);
- hci_sched_cmd(hdev);
- }
-
switch (ogf) {
case OGF_INFO_PARAM:
hci_cc_info_param(hdev, ocf, skb);
break;
};
+ if (ec->ncmd) {
+ atomic_set(&hdev->cmd_cnt, 1);
+ if (!skb_queue_empty(&hdev->cmd_q))
+ hci_sched_cmd(hdev);
+ }
break;
};
- bluez_skb_free(skb);
+ kfree_skb(skb);
hdev->stat.evt_rx++;
}
/* ACL data packet */
-static __inline__ void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
hci_acl_hdr *ah = (void *) skb->data;
struct hci_conn *conn;
DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
- struct hci_proto *hp;
+ register struct hci_proto *hp;
/* Send to upper protocol */
- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata)
+ if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
hp->recv_acldata(conn, skb, flags);
- else
- bluez_skb_free(skb);
+ goto sent;
+ }
+ } else {
+ ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
}
+ kfree_skb(skb);
+sent:
hdev->stat.acl_rx++;
}
/* SCO data packet */
-static __inline__ void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
+static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
{
- hci_sco_hdr *sh = (void *) skb->data;
- struct hci_conn *conn;
-
- skb_pull(skb, HCI_SCO_HDR_SIZE);
-
DBG("%s len %d", hdev->name, skb->len);
- if ((conn = conn_hash_lookup(&hdev->conn_hash, __le16_to_cpu(sh->handle)))) {
- struct hci_proto *hp;
-
- /* Send to upper protocol */
- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata)
- hp->recv_scodata(conn, skb);
- else
- bluez_skb_free(skb);
- }
-
+ kfree_skb(skb);
hdev->stat.sco_rx++;
}
switch (skb->pkt_type) {
case HCI_ACLDATA_PKT:
case HCI_SCODATA_PKT:
- bluez_skb_free(skb);
+ kfree_skb(skb);
continue;
};
}
if (hdev->flags & HCI_NORMAL) {
- /* Handle frame */
+ /* Process frame */
switch (skb->pkt_type) {
case HCI_EVENT_PKT:
hci_event_packet(hdev, skb);
break;
default:
- bluez_skb_free(skb);
+ kfree_skb(skb);
break;
};
} else {
- bluez_skb_free(skb);
+ kfree_skb(skb);
}
}
hci_sched_sco(hdev);
- /* Send next queued raw(unknown type) packet */
+ /* Send next queued raw (unknown type) packet */
while ((skb = skb_dequeue(&hdev->raw_q)))
hci_send_frame(skb);
/* Send queued commands */
if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
- if (hdev->cmd_sent)
- bluez_skb_free(hdev->cmd_sent);
+ if (hdev->sent_cmd)
+ kfree_skb(hdev->sent_cmd);
- if ((hdev->cmd_sent = bluez_skb_clone(skb, GFP_ATOMIC))) {
+ if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
atomic_dec(&hdev->cmd_cnt);
hci_send_frame(skb);
} else {
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
- bluez_skb_free(skb);
+ kfree_skb(skb);
return -1;
}
return 0;
}
-/* ----- HCI Ioctl helpers ----- */
-int hci_dev_reset(__u16 dev)
-{
- struct hci_dev *hdev;
- int ret = 0;
-
- if (!(hdev = hci_dev_get(dev)))
- return -ENODEV;
-
- hci_req_lock(hdev);
- tasklet_disable(&hdev->tx_task);
-
- if (!(hdev->flags & HCI_UP))
- goto done;
-
- /* Drop queues */
- bluez_skb_queue_purge(&hdev->rx_q);
- bluez_skb_queue_purge(&hdev->cmd_q);
-
- inquiry_cache_flush(&hdev->inq_cache);
-
- hci_conn_hash_flush(hdev);
-
- if (hdev->flush)
- hdev->flush(hdev);
-
- atomic_set(&hdev->cmd_cnt, 1);
- hdev->acl_cnt = 0; hdev->sco_cnt = 0;
-
- ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT);
-
-done:
- tasklet_enable(&hdev->tx_task);
- hci_req_unlock(hdev);
- hci_dev_put(hdev);
-
- return ret;
-}
-
-int hci_dev_reset_stat(__u16 dev)
-{
- struct hci_dev *hdev;
- int ret = 0;
-
- if (!(hdev = hci_dev_get(dev)))
- return -ENODEV;
-
- memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
- hci_dev_put(hdev);
-
- return ret;
-}
-
-int hci_dev_setauth(unsigned long arg)
-{
- struct hci_dev *hdev;
- struct hci_dev_req dr;
- int ret = 0;
-
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
- return -EFAULT;
-
- if (!(hdev = hci_dev_get(dr.dev_id)))
- return -ENODEV;
-
- ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-
- hci_dev_put(hdev);
-
- return ret;
-}
-
-int hci_dev_setscan(unsigned long arg)
-{
- struct hci_dev *hdev;
- struct hci_dev_req dr;
- int ret = 0;
-
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
- return -EFAULT;
-
- if (!(hdev = hci_dev_get(dr.dev_id)))
- return -ENODEV;
-
- ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-
- hci_dev_put(hdev);
-
- return ret;
-}
-
-int hci_dev_list(unsigned long arg)
-{
- struct hci_dev_list_req *dl;
- struct hci_dev_req *dr;
- struct hci_dev *hdev;
- int i, n, size;
- __u16 dev_num;
-
- if (get_user(dev_num, (__u16 *) arg))
- return -EFAULT;
-
- size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
-
- if (verify_area(VERIFY_WRITE, (void *) arg, size))
- return -EFAULT;
-
- if (!(dl = kmalloc(size, GFP_KERNEL)))
- return -ENOMEM;
- dr = dl->dev_req;
-
- spin_lock_bh(&hdev_list_lock);
- for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
- if ((hdev = hdev_list[i])) {
- (dr + n)->dev_id = hdev->id;
- (dr + n)->dev_opt = hdev->flags;
- n++;
- }
- }
- spin_unlock_bh(&hdev_list_lock);
-
- dl->dev_num = n;
- size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
-
- copy_to_user((void *) arg, dl, size);
-
- return 0;
-}
-
-int hci_dev_info(unsigned long arg)
-{
- struct hci_dev *hdev;
- struct hci_dev_info di;
- int err = 0;
-
- if (copy_from_user(&di, (void *) arg, sizeof(di)))
- return -EFAULT;
-
- if (!(hdev = hci_dev_get(di.dev_id)))
- return -ENODEV;
-
- strcpy(di.name, hdev->name);
- di.type = hdev->type;
- di.flags = hdev->flags;
- di.acl_mtu = hdev->acl_mtu;
- di.acl_max = hdev->acl_max;
- di.sco_mtu = hdev->sco_mtu;
- di.sco_max = hdev->sco_max;
- di.bdaddr = hdev->bdaddr;
-
- memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
-
- if (copy_to_user((void *) arg, &di, sizeof(di)))
- err = -EFAULT;
-
- hci_dev_put(hdev);
-
- return err;
-}
-
-__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
-{
- __u32 omode = hdev->flags & HCI_MODE_MASK;
-
- hdev->flags &= ~HCI_MODE_MASK;
- hdev->flags |= (mode & HCI_MODE_MASK);
-
- return omode;
-}
-
-__u32 hci_dev_getmode(struct hci_dev *hdev)
-{
- return hdev->flags & HCI_MODE_MASK;
-}
-
-int hci_inquiry(unsigned long arg)
-{
- struct inquiry_cache *cache;
- struct hci_inquiry_req ir;
- struct hci_dev *hdev;
- int err = 0, do_inquiry = 0;
- long timeo;
- __u8 *buf, *ptr;
-
- ptr = (void *) arg;
- if (copy_from_user(&ir, ptr, sizeof(ir)))
- return -EFAULT;
-
- if (!(hdev = hci_dev_get(ir.dev_id)))
- return -ENODEV;
-
- cache = &hdev->inq_cache;
-
- inquiry_cache_lock(cache);
- if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
- inquiry_cache_flush(cache);
- do_inquiry = 1;
- }
- inquiry_cache_unlock(cache);
-
- timeo = ir.length * 2 * HZ;
- if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
- goto done;
-
- /* cache_dump can't sleep. Therefore we allocate temp buffer and then
- * copy it to the user space.
- */
- if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
- err = -ENOMEM;
- goto done;
- }
- ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-
- DBG("num_rsp %d", ir.num_rsp);
-
- if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
- copy_to_user(ptr, &ir, sizeof(ir));
- ptr += sizeof(ir);
- copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
- } else
- err = -EFAULT;
-
- kfree(buf);
-
-done:
- hci_dev_put(hdev);
-
- return err;
-}
-
int hci_core_init(void)
{
/* Init locks */
/*
* BlueZ HCI socket layer.
*
- * $Id: hci_sock.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: hci_sock.c,v 1.9 2001/08/05 06:02:16 maxk Exp $
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
/* Send frame to RAW socket */
void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
{
- struct sk_buff *nskb;
struct sock * sk;
DBG("hdev %p len %d", hdev, skb->len);
read_lock(&hci_sk_list.lock);
for (sk = hci_sk_list.head; sk; sk = sk->next) {
+ struct hci_filter *flt;
+ struct sk_buff *nskb;
+
if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
continue;
if (skb->sk == sk)
continue;
- if (!(nskb = bluez_skb_clone(skb, GFP_ATOMIC)))
+ /* Apply filter */
+ flt = &hci_pi(sk)->filter;
+
+ if (!test_bit(skb->pkt_type, &flt->type_mask))
+ continue;
+
+ if (skb->pkt_type == HCI_EVENT_PKT) {
+ register int evt = (*(__u8 *)skb->data & 63);
+
+ if (!test_bit(evt, &flt->event_mask))
+ continue;
+ }
+
+ if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
continue;
/* Put type byte before the data */
sock_orphan(sk);
- bluez_skb_queue_purge(&sk->receive_queue);
- bluez_skb_queue_purge(&sk->write_queue);
+ skb_queue_purge(&sk->receive_queue);
+ skb_queue_purge(&sk->write_queue);
sock_put(sk);
struct hci_dev *hdev = hci_pi(sk)->hdev;
__u32 mode;
- DBG("cmd %x", cmd);
+ DBG("cmd %x arg %lx", cmd, arg);
switch (cmd) {
case HCIGETINFO:
case HCIDEVUP:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
-
return hci_dev_open(arg);
case HCIDEVDOWN:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
-
return hci_dev_close(arg);
case HCIDEVRESET:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
-
return hci_dev_reset(arg);
case HCIRESETSTAT:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
-
return hci_dev_reset_stat(arg);
case HCISETSCAN:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
-
return hci_dev_setscan(arg);
case HCISETAUTH:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
-
return hci_dev_setauth(arg);
case HCISETRAW:
return hci_dev_setmode(hdev, mode);
+ case HCISETPTYPE:
+ if (!capable(CAP_NET_ADMIN))
+ return -EACCES;
+ return hci_dev_setptype(arg);
+
case HCIINQUIRY:
return hci_inquiry(arg);
+ case HCIGETCONNLIST:
+ return hci_conn_list(arg);
+
default:
return -EINVAL;
};
return len;
}
-static __inline__ void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
+static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
{
- __u32 flags = hci_pi(sk)->cmsg_flags;
+ __u32 mask = hci_pi(sk)->cmsg_mask;
- if (flags & HCI_CMSG_DIR)
+ if (mask & HCI_CMSG_DIR)
put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
}
skb->h.raw = skb->data;
err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
- if (hci_pi(sk)->cmsg_flags)
+ if (hci_pi(sk)->cmsg_mask)
hci_sock_cmsg(sk, msg, skb);
skb_free_datagram(sk, skb);
return err ? : copied;
}
-int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
+int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
{
struct sock *sk = sock->sk;
- int err = 0, opt;
-
- if (get_user(opt, (int *)optval))
- return -EFAULT;
+ struct hci_filter flt;
+ int err = 0, opt = 0;
- DBG("sk %p, opt %d", sk, opt);
+ DBG("sk %p, opt %d", sk, optname);
lock_sock(sk);
switch (optname) {
case HCI_DATA_DIR:
+ if (get_user(opt, (int *)optval))
+ return -EFAULT;
+
if (opt)
- hci_pi(sk)->cmsg_flags |= HCI_CMSG_DIR;
+ hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
else
- hci_pi(sk)->cmsg_flags &= ~HCI_CMSG_DIR;
+ hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
+ break;
+
+ case HCI_FILTER:
+ len = MIN(len, sizeof(struct hci_filter));
+ if (copy_from_user(&flt, optval, len)) {
+ err = -EFAULT;
+ break;
+ }
+ memcpy(&hci_pi(sk)->filter, &flt, len);
break;
default:
switch (optname) {
case HCI_DATA_DIR:
- if (hci_pi(sk)->cmsg_flags & HCI_CMSG_DIR)
+ if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
opt = 1;
else
opt = 0;
return -EFAULT;
break;
+ case HCI_FILTER:
+ len = MIN(len, sizeof(struct hci_filter));
+ if (copy_to_user(optval, &hci_pi(sk)->filter, len))
+ return -EFAULT;
+ break;
+
default:
return -ENOPROTOOPT;
break;
sk->protocol = protocol;
sk->state = BT_OPEN;
+ /* Initialize filter */
+ hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
+ hci_pi(sk)->filter.event_mask[0] = ~0L;
+ hci_pi(sk)->filter.event_mask[1] = ~0L;
+
bluez_sock_link(&hci_sk_list, sk);
MOD_INC_USE_COUNT;
memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
hci_send_to_sock(NULL, skb);
- bluez_skb_free(skb);
+ kfree_skb(skb);
}
if (event == HCI_DEV_UNREG) {
/*
* BlueZ L2CAP core and sockets.
*
- * $Id: l2cap_core.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: l2cap_core.c,v 1.19 2001/08/03 04:19:50 maxk Exp $
*/
+#define VERSION "1.1"
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
static int l2cap_conn_del(struct l2cap_conn *conn, int err);
-static __inline__ void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
static void l2cap_chan_del(struct sock *sk, int err);
static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
}
/* ----- L2CAP timers ------ */
-static void l2cap_timeout(unsigned long arg)
+static void l2cap_sock_timeout(unsigned long arg)
{
struct sock *sk = (struct sock *) arg;
sock_put(sk);
}
-static void l2cap_set_timer(struct sock *sk, long timeout)
+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
{
DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
sock_hold(sk);
}
-static void l2cap_clear_timer(struct sock *sk)
+static void l2cap_sock_clear_timer(struct sock *sk)
{
DBG("sock %p state %d", sk, sk->state);
__sock_put(sk);
}
-static void l2cap_init_timer(struct sock *sk)
+static void l2cap_sock_init_timer(struct sock *sk)
{
init_timer(&sk->timer);
- sk->timer.function = l2cap_timeout;
+ sk->timer.function = l2cap_sock_timeout;
sk->timer.data = (unsigned long)sk;
}
+static void l2cap_conn_timeout(unsigned long arg)
+{
+ struct l2cap_conn *conn = (void *)arg;
+
+ DBG("conn %p state %d", conn, conn->state);
+
+ if (conn->state == BT_CONNECTED) {
+ hci_disconnect(conn->hconn, 0x13);
+ }
+
+ return;
+}
+
+static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
+{
+ DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
+
+ mod_timer(&conn->timer, jiffies + timeout);
+}
+
+static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
+{
+ DBG("conn %p state %d", conn, conn->state);
+
+ del_timer(&conn->timer);
+}
+
+static void l2cap_conn_init_timer(struct l2cap_conn *conn)
+{
+ init_timer(&conn->timer);
+ conn->timer.function = l2cap_conn_timeout;
+ conn->timer.data = (unsigned long)conn;
+}
+
/* -------- L2CAP connections --------- */
/* Add new connection to the interface.
* Interface must be locked
spin_lock_init(&conn->lock);
conn->chan_list.lock = RW_LOCK_UNLOCKED;
+ l2cap_conn_init_timer(conn);
+
__l2cap_conn_link(iff, conn);
DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
DBG("conn %p, state %d, err %d", conn, conn->state, err);
+ l2cap_conn_clear_timer(conn);
__l2cap_conn_unlink(conn->iff, conn);
conn->state = BT_CLOSED;
if (conn->rx_skb)
- bluez_skb_free(conn->rx_skb);
+ kfree_skb(conn->rx_skb);
/* Kill channels */
while ((sk = conn->chan_list.head)) {
bh_lock_sock(sk);
- l2cap_clear_timer(sk);
+ l2cap_sock_clear_timer(sk);
l2cap_chan_del(sk, err);
bh_unlock_sock(sk);
return 0;
}
-static __inline__ struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
+static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
{
struct list_head *p;
- list_for_each(p, &iff->conn_list){
+ list_for_each(p, &iff->conn_list) {
struct l2cap_conn *c;
c = list_entry(p, struct l2cap_conn, list);
l2cap_chan_add(conn, sk, NULL);
sk->state = BT_CONNECT;
- l2cap_set_timer(sk, sk->sndtimeo);
+ l2cap_sock_set_timer(sk, sk->sndtimeo);
switch (conn->state) {
case BT_CONNECTED:
req.psm = l2cap_pi(sk)->psm;
l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
} else {
+ l2cap_sock_clear_timer(sk);
sk->state = BT_CONNECTED;
- l2cap_clear_timer(sk);
}
break;
done:
read_unlock_bh(&l2cap_rt_lock);
-
return err;
}
struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
struct sock *sk;
- for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q){
+ for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
if (!state || sk->state == state) {
l2cap_accept_unlink(sk);
break;
{
DBG("sk %p", sk);
- bluez_skb_queue_purge(&sk->receive_queue);
- bluez_skb_queue_purge(&sk->write_queue);
+ skb_queue_purge(&sk->receive_queue);
+ skb_queue_purge(&sk->write_queue);
MOD_DEC_USE_COUNT;
}
{
struct l2cap_conn *conn;
+ l2cap_sock_clear_timer(sk);
+
lock_sock(sk);
conn = l2cap_pi(sk)->conn;
req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
- l2cap_set_timer(sk, sk->sndtimeo);
+ l2cap_sock_set_timer(sk, sk->sndtimeo);
} else {
l2cap_chan_del(sk, ECONNRESET);
}
sk->protocol = proto;
sk->state = BT_OPEN;
- l2cap_init_timer(sk);
+ l2cap_sock_init_timer(sk);
bluez_sock_link(&l2cap_sk_list, sk);
long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
int err = 0;
+ DBG("sk %p", sk);
+
add_wait_queue(sk->sleep, &wait);
current->state = TASK_INTERRUPTIBLE;
};
release_sock(sk);
-
return err;
}
{
struct sock *sk = sock->sk;
struct l2cap_options opts;
- int len;
+ struct l2cap_conninfo cinfo;
+ int len, err = 0;
if (get_user(len, optlen))
return -EFAULT;
+ lock_sock(sk);
+
switch (optname) {
case L2CAP_OPTIONS:
opts.imtu = l2cap_pi(sk)->imtu;
len = MIN(len, sizeof(opts));
if (copy_to_user(optval, (char *)&opts, len))
- return -EFAULT;
+ err = -EFAULT;
+
+ break;
+
+ case L2CAP_CONNINFO:
+ if (sk->state != BT_CONNECTED) {
+ err = -ENOTCONN;
+ break;
+ }
+
+ cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
+
+ len = MIN(len, sizeof(cinfo));
+ if (copy_to_user(optval, (char *)&cinfo, len))
+ err = -EFAULT;
break;
default:
- return -ENOPROTOOPT;
+ err = -ENOPROTOOPT;
break;
};
- return 0;
+ release_sock(sk);
+ return err;
+}
+
+static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
+{
+ struct sock *sk = sock->sk;
+ struct l2cap_accept_q *aq;
+ unsigned int mask;
+
+ DBG("sock %p, sk %p", sock, sk);
+
+ poll_wait(file, sk->sleep, wait);
+ mask = 0;
+
+ if (sk->err || !skb_queue_empty(&sk->error_queue))
+ mask |= POLLERR;
+
+ if (sk->shutdown == SHUTDOWN_MASK)
+ mask |= POLLHUP;
+
+ aq = &l2cap_pi(sk)->accept_q;
+ if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
+ mask |= POLLIN | POLLRDNORM;
+
+ if (sk->state == BT_CLOSED)
+ mask |= POLLHUP;
+
+ if (sock_writeable(sk))
+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+ else
+ set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
+
+ return mask;
}
static int l2cap_sock_release(struct socket *sock)
return s;
}
-static __inline__ struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
+static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
{
struct sock *s;
return s;
}
-static __inline__ struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
{
struct sock *s;
return s;
}
-static __inline__ struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
+static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
{
struct sock *s;
return 0;
}
-static __inline__ void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
{
sock_hold(sk);
l->head = sk;
}
-static __inline__ void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
{
struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
+ l2cap_conn_clear_timer(conn);
+
atomic_inc(&conn->refcnt);
l2cap_pi(sk)->conn = conn;
l2cap_accept_queue(parent, sk);
}
-static __inline__ void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
{
struct l2cap_chan_list *l = &conn->chan_list;
write_unlock(&l->lock);
}
-/* Delete channel. Must be called on the locked socket. */
+/* Delete channel.
+ * Must be called on the locked socket. */
static void l2cap_chan_del(struct sock *sk, int err)
{
struct l2cap_conn *conn;
bh_unlock_sock(parent);
}
- if (conn) {
+ if (conn) {
+ long timeout;
+
/* Unlink from channel list */
l2cap_chan_unlink(&conn->chan_list, sk);
l2cap_pi(sk)->conn = NULL;
- if (conn->out &&
- conn->state == BT_CONNECTED &&
- atomic_dec_and_test(&conn->refcnt)) {
- /* Disconnect baseband */
- hci_disconnect(conn->hconn, 0x13);
+ if (conn->out)
+ timeout = L2CAP_DISCONN_TIMEOUT;
+ else
+ timeout = L2CAP_CONN_IDLE_TIMEOUT;
+
+ if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
+ /* Schedule Baseband disconnect */
+ l2cap_conn_set_timer(conn, timeout);
}
}
if (sk->type != SOCK_SEQPACKET) {
sk->state = BT_CONNECTED;
sk->state_change(sk);
- l2cap_clear_timer(sk);
+ l2cap_sock_clear_timer(sk);
} else if (sk->state == BT_CONNECT) {
l2cap_conn_req req;
req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
- l2cap_set_timer(sk, sk->sndtimeo);
+ l2cap_sock_set_timer(sk, sk->sndtimeo);
}
bh_unlock_sock(sk);
DBG("sk %p, parent %p", sk, parent);
l2cap_pi(sk)->conf_state = 0;
- l2cap_clear_timer(sk);
+ l2cap_sock_clear_timer(sk);
if (!parent) {
/* Outgoing channel.
/* Incomming channel.
* Wake up socket sleeping on accept.
*/
- parent->state_change(parent);
+ parent->data_ready(parent, 1);
}
}
if (skb->sk == sk)
continue;
- if (!(nskb = bluez_skb_clone(skb, GFP_ATOMIC)))
+ if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
continue;
skb_queue_tail(&sk->receive_queue, nskb);
static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
- struct l2cap_iff *iff = conn->iff;
- struct sk_buff *skb, *frag;
+ struct sk_buff *skb, **frag;
int err, size, count, sent=0;
- l2cap_hdr * lh;
+ l2cap_hdr *lh;
/* Check outgoing MTU */
if (len > l2cap_pi(sk)->omtu)
return -EINVAL;
+ DBG("sk %p len %d", sk, len);
+
/* First fragment (with L2CAP header) */
- count = MIN(iff->mtu - L2CAP_HDR_SIZE, len);
+ count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
size = L2CAP_HDR_SIZE + count;
if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
return err;
len -= count;
/* Continuation fragments (no L2CAP header) */
+ frag = &skb_shinfo(skb)->frag_list;
while (len) {
- count = MIN(iff->mtu, len);
+ count = MIN(conn->iff->mtu, len);
- if (!(frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
+ *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
+ if (!*frag)
goto fail;
-
- bluez_skb_add_frag(skb, frag);
-
- if (memcpy_fromiovec(skb_put(frag, count), msg->msg_iov, count)) {
+
+ if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
err = -EFAULT;
goto fail;
}
sent += count;
len -= count;
+
+ frag = &(*frag)->next;
}
if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
return sent;
fail:
- bluez_skb_free(skb);
-
+ kfree_skb(skb);
return err;
}
+
/* --------- L2CAP signalling commands --------- */
-static __inline__ __u8 l2cap_get_ident(struct l2cap_conn *conn)
+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
{
__u8 id;
return id;
}
-static __inline__ struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
+static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
{
struct sk_buff *skb;
l2cap_cmd_hdr *cmd;
ident = l2cap_get_ident(conn);
if (!(skb = l2cap_build_cmd(code, ident, len, data)))
return -ENOMEM;
- skb->dev = (void *) conn->iff->hdev;
return hci_send_acl(conn->hconn, skb, 0);
}
if (!(skb = l2cap_build_cmd(code, ident, len, data)))
return -ENOMEM;
-
- skb->dev = (void *) conn->iff->hdev;
-
return hci_send_acl(conn->hconn, skb, 0);
}
-static __inline__ int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
+static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
{
l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
int len;
return len;
}
-static __inline__ void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
+static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
{
- __u8 type; __u32 val;
+ __u8 type, hint; __u32 val;
__u8 *ptr = data;
DBG("sk %p len %d", sk, len);
while (len >= L2CAP_CONF_OPT_SIZE) {
len -= l2cap_get_conf_opt(&ptr, &type, &val);
+ hint = type & 0x80;
+ type &= 0x7f;
+
switch (type) {
case L2CAP_CONF_MTU:
l2cap_pi(sk)->conf_mtu = val;
case L2CAP_CONF_QOS:
break;
+
+ default:
+ if (hint)
+ break;
+
+ /* FIXME: Reject unknon option */
+ break;
};
}
}
-static __inline__ void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
+static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
{
register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
return ptr - data;
}
-static __inline__ int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
{
struct l2cap_chan_list *list = &conn->chan_list;
l2cap_conn_req *req = (l2cap_conn_req *) data;
return 0;
}
-static __inline__ int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
{
l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
__u16 scid, dcid, result, status;
if (!result) {
char req[64];
- l2cap_pi(sk)->dcid = dcid;
sk->state = BT_CONFIG;
+ l2cap_pi(sk)->dcid = dcid;
+ l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
} else {
return 0;
}
-static __inline__ int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
{
l2cap_conf_req * req = (l2cap_conf_req *) data;
__u16 dcid, flags;
goto unlock;
/* Output config done */
- l2cap_pi(sk)->conf_state |= CONF_OUTPUT;
+ l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
- if (l2cap_pi(sk)->conf_state == CONF_DONE) {
+ if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
sk->state = BT_CONNECTED;
l2cap_chan_ready(sk);
- } else {
+ } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
char req[64];
l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
}
return 0;
}
-static __inline__ int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
{
l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
__u16 scid, flags, result;
bh_lock_sock(sk);
- if (sk->state != BT_CONFIG) {
- err = -EINVAL;
- goto done;
- }
-
if (result) {
l2cap_disconn_req req;
req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
- l2cap_set_timer(sk, sk->sndtimeo);
+ l2cap_sock_set_timer(sk, sk->sndtimeo);
goto done;
}
goto done;
/* Input config done */
- l2cap_pi(sk)->conf_state |= CONF_INPUT;
+ l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
- if (l2cap_pi(sk)->conf_state == CONF_DONE) {
+ if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
sk->state = BT_CONNECTED;
l2cap_chan_ready(sk);
}
return err;
}
-static __inline__ int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
{
l2cap_disconn_req *req = (l2cap_disconn_req *) data;
l2cap_disconn_rsp rsp;
return 0;
}
-static __inline__ int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
{
l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
__u16 dcid, scid;
return -ENOENT;
bh_lock_sock(sk);
- l2cap_clear_timer(sk);
+ l2cap_sock_clear_timer(sk);
l2cap_chan_del(sk, ECONNABORTED);
bh_unlock_sock(sk);
return 0;
}
-static __inline__ void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
{
__u8 *data = skb->data;
int len = skb->len;
data += L2CAP_CMD_HDR_SIZE;
len -= L2CAP_CMD_HDR_SIZE;
- cmd.len = le16_to_cpu(cmd.len);
+ cmd.len = __le16_to_cpu(cmd.len);
DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
DBG("error %d", err);
/* FIXME: Map err to a valid reason. */
- rej.reason = cpu_to_le16(0);
+ rej.reason = __cpu_to_le16(0);
l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
}
len -= cmd.len;
}
- bluez_skb_free(skb);
+ kfree_skb(skb);
}
-static __inline__ int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
{
struct sock *sk;
return 0;
drop:
- bluez_skb_free(skb);
+ kfree_skb(skb);
return 0;
}
__u16 cid, len;
skb_pull(skb, L2CAP_HDR_SIZE);
- cid = le16_to_cpu(lh->cid);
- len = le16_to_cpu(lh->len);
+ cid = __le16_to_cpu(lh->cid);
+ len = __le16_to_cpu(lh->len);
DBG("len %d, cid 0x%4.4x", len, cid);
goto done;
}
- conn->state = BT_CONNECTED;
conn->hconn = hconn;
-
hconn->l2cap_data = (void *)conn;
+
+ conn->state = BT_CONNECTED;
}
done:
struct l2cap_conn *conn = hconn->l2cap_data;
if (!conn) {
- ERR("unknown connection");
+ ERR("unknown connection %p", hconn);
goto drop;
}
int flen, tlen, size;
l2cap_hdr *lh;
+ if (conn->rx_len) {
+ ERR("Unexpected start frame (len %d)", skb->len);
+ kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
+ conn->rx_len = 0;
+ }
+
if (skb->len < L2CAP_HDR_SIZE) {
- DBG("Corrupted L2CAP frame %d", skb->len);
+ ERR("Frame is too small (len %d)", skb->len);
goto drop;
}
} else {
DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
- /* Check length */
+ if (!conn->rx_len) {
+ ERR("Unexpected continuation frame (len %d)", skb->len);
+ goto drop;
+ }
+
if (skb->len > conn->rx_len) {
- if (conn->rx_skb) {
- bluez_skb_free(conn->rx_skb);
- conn->rx_skb = NULL;
- }
+ ERR("Fragment is too large (len %d)", skb->len);
+ kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
goto drop;
}
/* Complete frame received */
l2cap_recv_frame(conn, conn->rx_skb);
conn->rx_skb = NULL;
- conn->rx_len = 0;
}
}
drop:
- bluez_skb_free(skb);
-
+ kfree_skb(skb);
return 0;
}
getname: l2cap_sock_getname,
sendmsg: l2cap_sock_sendmsg,
recvmsg: l2cap_sock_recvmsg,
- poll: datagram_poll,
+ poll: l2cap_sock_poll,
socketpair: sock_no_socketpair,
ioctl: sock_no_ioctl,
shutdown: sock_no_shutdown,
int __init l2cap_init(void)
{
INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- BLUEZ_VER);
+ VERSION);
INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
module_init(l2cap_init);
module_exit(l2cap_cleanup);
+
+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
/*
* BlueZ L2CAP proc fs support.
*
- * $Id: l2cap_proc.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: l2cap_proc.c,v 1.2 2001/06/02 01:40:09 maxk Exp $
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
/*
* BlueZ kernel library.
*
- * $Id: lib.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: lib.c,v 1.3 2001/06/22 23:14:23 maxk Exp $
*/
#include <linux/kernel.h>
i ^= 1;
sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
- ba->b0, ba->b1, ba->b2, ba->b3, ba->b4, ba->b5);
+ ba->b[0], ba->b[1], ba->b[2],
+ ba->b[3], ba->b[4], ba->b[5]);
return str[i];
}
/*
* BlueZ symbols.
*
- * $Id: syms.c,v 1.1 2001/06/01 08:12:11 davem Exp $
+ * $Id: syms.c,v 1.1 2001/07/12 19:31:24 maxk Exp $
*/
#include <linux/config.h>
}
return ret;
+ /*
+ * These ioctl calls:
+ * - require superuser power.
+ * - require strict serialization.
+ * - return a value
+ */
+
+ case SIOCETHTOOL:
+ case SIOCGMIIPHY:
+ case SIOCGMIIREG:
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
+ dev_load(ifr.ifr_name);
+ dev_probe_lock();
+ rtnl_lock();
+ ret = dev_ifsioc(&ifr, cmd);
+ rtnl_unlock();
+ dev_probe_unlock();
+ if (!ret) {
+ if (colon)
+ *colon = ':';
+ if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+ return -EFAULT;
+ }
+ return ret;
+
/*
* These ioctl calls:
* - require superuser power.
case SIOCSIFHWBROADCAST:
case SIOCSIFTXQLEN:
case SIOCSIFNAME:
- case SIOCETHTOOL:
- case SIOCGMIIPHY:
- case SIOCGMIIREG:
case SIOCSMIIREG:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
/* linux/net/inet/arp.c
*
- * Version: $Id: arp.c,v 1.98 2001/05/16 16:45:35 davem Exp $
+ * Version: $Id: arp.c,v 1.99 2001/08/30 22:55:42 davem Exp $
*
* Copyright (C) 1994 by Florian La Roche
*
memset(arp_ptr, 0, dev->addr_len);
arp_ptr+=dev->addr_len;
memcpy(arp_ptr, &dest_ip, 4);
- skb->dev = dev;
dev_queue_xmit(skb);
return;
*
* Alan Cox, <alan@redhat.com>
*
- * Version: $Id: icmp.c,v 1.80 2001/08/22 20:38:41 davem Exp $
+ * Version: $Id: icmp.c,v 1.81 2001/09/01 00:31:50 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
case CHECKSUM_HW:
if ((u16)csum_fold(skb->csum) == 0)
break;
- NETDEBUG(printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "icmp v4 hw csum failure\n"));
case CHECKSUM_NONE:
if ((u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))
goto error;
*
* The IP fragmentation functionality.
*
- * Version: $Id: ip_fragment.c,v 1.57 2001/03/07 22:00:57 davem Exp $
+ * Version: $Id: ip_fragment.c,v 1.58 2001/09/01 00:31:50 davem Exp $
*
* Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
* Alan Cox <Alan.Cox@linux.org>
return ip_frag_intern(hash, qp);
out_nomem:
- NETDEBUG(printk(KERN_ERR "ip_frag_create: no memory left !\n"));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_ERR "ip_frag_create: no memory left !\n"));
return NULL;
}
return head;
out_nomem:
- NETDEBUG(printk(KERN_ERR
+ NETDEBUG(if (net_ratelimit())
+ printk(KERN_ERR
"IP: queue_glue: no memory for gluing queue %p\n",
qp));
goto out_fail;
*
* The options processing module for ip.c
*
- * Version: $Id: ip_options.c,v 1.20 2000/08/09 09:17:00 davem Exp $
+ * Version: $Id: ip_options.c,v 1.21 2001/09/01 00:31:50 davem Exp $
*
* Authors: A.N.Kuznetsov
*
ip_rt_get_source(&optptr[srrptr-1], rt);
skb->nh.iph->daddr = rt->rt_dst;
optptr[2] = srrptr+4;
- } else
+ } else if (net_ratelimit())
printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
if (opt->ts_needaddr) {
optptr = raw + opt->ts;
*
* The Internet Protocol (IP) output module.
*
- * Version: $Id: ip_output.c,v 1.97 2001/08/09 17:53:40 davem Exp $
+ * Version: $Id: ip_output.c,v 1.98 2001/09/01 00:31:50 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
} else if (dst->neighbour)
return dst->neighbour->output(skb);
- printk(KERN_DEBUG "khm\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
kfree_skb(skb);
return -EINVAL;
}
name: "IPIP"
};
-static const char banner[] __initdata =
+static char banner[] __initdata =
KERN_INFO "IPv4 over IPv4 tunneling driver\n";
int __init ipip_init(void)
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_ipv4.c,v 1.229 2001/04/20 20:46:19 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.230 2001/09/01 00:31:50 davem Exp $
*
* IPv4 specific functions
*
skb->nh.iph->daddr,skb->csum))
return 0;
- NETDEBUG(printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "hw tcp v4 csum failed\n"));
skb->ip_summed = CHECKSUM_NONE;
}
if (skb->len <= 76) {
*
* The User Datagram Protocol (UDP).
*
- * Version: $Id: udp.c,v 1.98 2001/03/06 21:15:10 davem Exp $
+ * Version: $Id: udp.c,v 1.99 2001/09/01 00:31:50 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (!udp_check(uh, ulen, saddr, daddr, skb->csum))
return 0;
- NETDEBUG(printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v4 hw csum failure.\n"));
skb->ip_summed = CHECKSUM_NONE;
}
if (skb->ip_summed != CHECKSUM_UNNECESSARY)
return(0);
short_packet:
- NETDEBUG(printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "UDP: short packet: %d/%d\n", ulen, len));
UDP_INC_STATS_BH(UdpInErrors);
kfree_skb(skb);
return(0);
* RFC1122: OK. Discards the bad packet silently (as far as
* the network is concerned, anyway) as per 4.1.3.4 (MUST).
*/
- NETDEBUG(printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
+ NETDEBUG(if (net_ratelimit())
+ printk(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
NIPQUAD(saddr),
ntohs(uh->source),
NIPQUAD(daddr),
* Pedro Roque <roque@di.fc.ul.pt>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
- * $Id: addrconf.c,v 1.67 2001/08/03 09:32:17 davem Exp $
+ * $Id: addrconf.c,v 1.68 2001/09/01 00:31:50 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
void addrconf_dad_failure(struct inet6_ifaddr *ifp)
{
- printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
+ if (net_ratelimit())
+ printk(KERN_INFO "%s: duplicate address detected!\n", ifp->idev->dev->name);
if (ifp->flags&IFA_F_PERMANENT) {
spin_lock_bh(&ifp->lock);
addrconf_del_timer(ifp);
prefered_lft = ntohl(pinfo->prefered);
if (prefered_lft > valid_lft) {
- printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n");
+ if (net_ratelimit())
+ printk(KERN_WARNING "addrconf: prefix option has invalid lifetime\n");
return;
}
in6_dev = in6_dev_get(dev);
if (in6_dev == NULL) {
- printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name);
+ if (net_ratelimit())
+ printk(KERN_DEBUG "addrconf: device %s not configured\n", dev->name);
return;
}
}
goto ok;
}
- printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n", pinfo->prefix_len);
+ if (net_ratelimit())
+ printk(KERN_DEBUG "IPv6 addrconf: prefix with wrong length %d\n",
+ pinfo->prefix_len);
in6_dev_put(in6_dev);
return;
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: datagram.c,v 1.22 2000/12/13 18:31:50 davem Exp $
+ * $Id: datagram.c,v 1.23 2001/09/01 00:31:50 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
break;
default:
- printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type);
+ if (net_ratelimit())
+ printk(KERN_DEBUG "invalid cmsg type: %d\n", cmsg->cmsg_type);
err = -EINVAL;
break;
};
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: icmp.c,v 1.35 2001/08/13 18:56:13 davem Exp $
+ * $Id: icmp.c,v 1.36 2001/09/01 00:31:50 davem Exp $
*
* Based on net/ipv4/icmp.c
*
* for now we don't know that.
*/
if ((addr_type == IPV6_ADDR_ANY) || (addr_type & IPV6_ADDR_MULTICAST)) {
- printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "icmpv6_send: addr_any/mcast source\n");
return;
}
len = min(unsigned int, len, IPV6_MIN_MTU - sizeof(struct ipv6hdr));
if (len < 0) {
- printk(KERN_DEBUG "icmp: len problem\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "icmp: len problem\n");
goto out;
}
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
skb->csum)) {
- printk(KERN_DEBUG "ICMPv6 hw checksum failed\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "ICMPv6 hw checksum failed\n");
skb->ip_summed = CHECKSUM_NONE;
}
}
if (skb->ip_summed == CHECKSUM_NONE) {
if (csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_ICMPV6,
skb_checksum(skb, 0, skb->len, 0))) {
- printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
- ntohs(saddr->in6_u.u6_addr16[0]),
- ntohs(saddr->in6_u.u6_addr16[1]),
- ntohs(saddr->in6_u.u6_addr16[2]),
- ntohs(saddr->in6_u.u6_addr16[3]),
- ntohs(saddr->in6_u.u6_addr16[4]),
- ntohs(saddr->in6_u.u6_addr16[5]),
- ntohs(saddr->in6_u.u6_addr16[6]),
- ntohs(saddr->in6_u.u6_addr16[7]),
- ntohs(daddr->in6_u.u6_addr16[0]),
- ntohs(daddr->in6_u.u6_addr16[1]),
- ntohs(daddr->in6_u.u6_addr16[2]),
- ntohs(daddr->in6_u.u6_addr16[3]),
- ntohs(daddr->in6_u.u6_addr16[4]),
- ntohs(daddr->in6_u.u6_addr16[5]),
- ntohs(daddr->in6_u.u6_addr16[6]),
- ntohs(daddr->in6_u.u6_addr16[7]));
+ if (net_ratelimit())
+ printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
+ ntohs(saddr->in6_u.u6_addr16[0]),
+ ntohs(saddr->in6_u.u6_addr16[1]),
+ ntohs(saddr->in6_u.u6_addr16[2]),
+ ntohs(saddr->in6_u.u6_addr16[3]),
+ ntohs(saddr->in6_u.u6_addr16[4]),
+ ntohs(saddr->in6_u.u6_addr16[5]),
+ ntohs(saddr->in6_u.u6_addr16[6]),
+ ntohs(saddr->in6_u.u6_addr16[7]),
+ ntohs(daddr->in6_u.u6_addr16[0]),
+ ntohs(daddr->in6_u.u6_addr16[1]),
+ ntohs(daddr->in6_u.u6_addr16[2]),
+ ntohs(daddr->in6_u.u6_addr16[3]),
+ ntohs(daddr->in6_u.u6_addr16[4]),
+ ntohs(daddr->in6_u.u6_addr16[5]),
+ ntohs(daddr->in6_u.u6_addr16[6]),
+ ntohs(daddr->in6_u.u6_addr16[7]));
goto discard_it;
}
}
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: ip6_output.c,v 1.31 2001/04/17 20:39:51 davem Exp $
+ * $Id: ip6_output.c,v 1.32 2001/09/01 00:31:50 davem Exp $
*
* Based on linux/net/ipv4/ip_output.c
*
dst = ip6_route_output(skb->sk, &fl);
if (dst->error) {
- printk(KERN_DEBUG "route6_me_harder: No more route.\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "route6_me_harder: No more route.\n");
return -EINVAL;
}
return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
}
- printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
kfree_skb(skb);
return -EMSGSIZE;
* Pedro Roque <roque@di.fc.ul.pt>
* Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
*
- * $Id: sit.c,v 1.51 2001/05/17 04:12:18 davem Exp $
+ * $Id: sit.c,v 1.52 2001/09/01 00:31:50 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
neigh = skb->dst->neighbour;
if (neigh == NULL) {
- printk(KERN_DEBUG "sit: nexthop == NULL\n");
+ if (net_ratelimit())
+ printk(KERN_DEBUG "sit: nexthop == NULL\n");
goto tx_error;
}
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: tcp_ipv6.c,v 1.137 2001/06/13 16:25:03 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.138 2001/09/01 00:31:50 davem Exp $
*
* Based on:
* linux/net/ipv4/tcp.c
if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
&skb->nh.ipv6h->daddr,skb->csum))
return 0;
- NETDEBUG(printk(KERN_DEBUG "hw tcp v6 csum failed\n"));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "hw tcp v6 csum failed\n"));
}
if (skb->len <= 76) {
if (tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
*
* Based on linux/ipv4/udp.c
*
- * $Id: udp.c,v 1.63 2001/06/13 16:25:03 davem Exp $
+ * $Id: udp.c,v 1.64 2001/09/01 00:31:50 davem Exp $
*
* Fixes:
* Hideaki YOSHIFUJI : sin6_scope_id support
if (skb->ip_summed==CHECKSUM_HW) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
if (csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) {
- NETDEBUG(printk(KERN_DEBUG "udp v6 hw csum failure.\n"));
+ NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "udp v6 hw csum failure.\n"));
skb->ip_summed = CHECKSUM_NONE;
}
}
dongle_t *irda_device_dongle_init(struct net_device *dev, int type)
{
struct dongle_reg *reg;
- char modname[32];
dongle_t *dongle;
ASSERT(dev != NULL, return NULL;);
#ifdef CONFIG_KMOD
+ {
+ char modname[32];
/* Try to load the module needed */
sprintf(modname, "irda-dongle-%d", type);
request_module(modname);
+ }
#endif /* CONFIG_KMOD */
if (!(reg = hashbin_find(dongles, type, NULL))) {
EXPORT_SYMBOL(lapb_data_request);
EXPORT_SYMBOL(lapb_data_received);
-static const char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
+static char banner[] __initdata = KERN_INFO "NET4: LAPB for Linux. Version 0.01 for NET4.0\n";
static int __init lapb_init(void)
{
static struct net_device *dev_nr;
-static const char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
+static char banner[] __initdata = KERN_INFO "G4KLX NET/ROM for Linux. Version 0.7 for AX25.037 Linux 2.4\n";
static int __init nr_proto_init(void)
{
#ifdef RPC_DEBUG
rpc_register_sysctl();
#endif
- xdr_init();
if (!xprt)
goto out;
EXPORT_SYMBOL(xdr_decode_string);
EXPORT_SYMBOL(xdr_decode_netobj);
EXPORT_SYMBOL(xdr_encode_netobj);
-EXPORT_SYMBOL(xdr_zero);
-EXPORT_SYMBOL(xdr_one);
-EXPORT_SYMBOL(xdr_two);
EXPORT_SYMBOL(xdr_shift_iovec);
EXPORT_SYMBOL(xdr_zero_iovec);
-/* RPC errors */
-EXPORT_SYMBOL(rpc_success);
-EXPORT_SYMBOL(rpc_garbage_args);
-EXPORT_SYMBOL(rpc_system_err);
-
/* Debugging symbols */
#ifdef RPC_DEBUG
EXPORT_SYMBOL(rpc_debug);
{
struct svc_serv *serv;
- xdr_init();
#ifdef RPC_DEBUG
rpc_register_sysctl();
#endif
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/msg_prot.h>
-u32 rpc_success, rpc_prog_unavail, rpc_prog_mismatch, rpc_proc_unavail,
- rpc_garbage_args, rpc_system_err;
-u32 rpc_auth_ok, rpc_autherr_badcred, rpc_autherr_rejectedcred,
- rpc_autherr_badverf, rpc_autherr_rejectedverf, rpc_autherr_tooweak;
-u32 xdr_zero, xdr_one, xdr_two;
-
-void
-xdr_init(void)
-{
- static int inited = 0;
-
- if (inited)
- return;
-
- xdr_zero = htonl(0);
- xdr_one = htonl(1);
- xdr_two = htonl(2);
-
- rpc_success = htonl(RPC_SUCCESS);
- rpc_prog_unavail = htonl(RPC_PROG_UNAVAIL);
- rpc_prog_mismatch = htonl(RPC_PROG_MISMATCH);
- rpc_proc_unavail = htonl(RPC_PROC_UNAVAIL);
- rpc_garbage_args = htonl(RPC_GARBAGE_ARGS);
- rpc_system_err = htonl(RPC_SYSTEM_ERR);
-
- rpc_auth_ok = htonl(RPC_AUTH_OK);
- rpc_autherr_badcred = htonl(RPC_AUTH_BADCRED);
- rpc_autherr_rejectedcred = htonl(RPC_AUTH_REJECTEDCRED);
- rpc_autherr_badverf = htonl(RPC_AUTH_BADVERF);
- rpc_autherr_rejectedverf = htonl(RPC_AUTH_REJECTEDVERF);
- rpc_autherr_tooweak = htonl(RPC_AUTH_TOOWEAK);
-
- inited = 1;
-}
-
/*
* XDR functions for basic NFS types
*/