summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-05-12 23:48:34 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-05-12 23:48:34 +0000
commit7fd36ebeeec9244a7431bb010e6e3c5e4848a0d5 (patch)
tree5fb03a9aafdd1cec5f4f6ff7f1873174cb89b66c /drivers
parentba2dacab305c598cd4c34a604f8e276bf5bab5ff (diff)
Merge with Linux 2.3.99-pre8. Linus must hate me, too man patches ;-)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acorn/scsi/arxescsi.c83
-rw-r--r--drivers/acorn/scsi/arxescsi.h2
-rw-r--r--drivers/acorn/scsi/cumana_2.h2
-rw-r--r--drivers/block/Config.in9
-rw-r--r--drivers/block/Makefile26
-rw-r--r--drivers/block/linear.c2
-rw-r--r--drivers/block/ll_rw_blk.c48
-rw-r--r--drivers/block/md.c425
-rw-r--r--drivers/block/raid0.c6
-rw-r--r--drivers/block/raid1.c1716
-rw-r--r--drivers/block/raid5.c2484
-rw-r--r--drivers/block/xor.c1894
-rw-r--r--drivers/char/cyclades.c384
-rw-r--r--drivers/char/nwbutton.c6
-rw-r--r--drivers/char/nwflash.c6
-rw-r--r--drivers/net/Config.in2
-rw-r--r--drivers/net/Makefile29
-rw-r--r--drivers/net/acenic.c51
-rw-r--r--drivers/net/acenic.h2
-rw-r--r--drivers/net/acenic_firmware.h6537
-rw-r--r--drivers/net/bsd_comp.c12
-rw-r--r--drivers/net/pcmcia/Config.in2
-rw-r--r--drivers/net/pppoe.c1
-rw-r--r--drivers/net/pppox.c1
-rw-r--r--drivers/net/skfp/fplustm.c28
-rw-r--r--drivers/net/skfp/h/fplustm.h24
-rw-r--r--drivers/net/skfp/h/osdef1st.h17
-rw-r--r--drivers/net/skfp/h/smt.h114
-rw-r--r--drivers/net/skfp/h/targetos.h11
-rw-r--r--drivers/net/skfp/hwmtm.c52
-rw-r--r--drivers/net/skfp/skfddi.c208
-rw-r--r--drivers/net/tokenring/ibmtr.c4
-rw-r--r--drivers/s390/Config.in70
-rw-r--r--drivers/s390/Makefile40
-rw-r--r--drivers/s390/block/Makefile31
-rw-r--r--drivers/s390/block/dasd.c1560
-rw-r--r--drivers/s390/block/dasd_ccwstuff.c419
-rw-r--r--drivers/s390/block/dasd_ccwstuff.h9
-rw-r--r--drivers/s390/block/dasd_eckd.c973
-rw-r--r--drivers/s390/block/dasd_erp.c21
-rw-r--r--drivers/s390/block/dasd_erp.h15
-rw-r--r--drivers/s390/block/dasd_mdsk.c14
-rw-r--r--drivers/s390/block/dasd_proc.c116
-rw-r--r--drivers/s390/block/dasd_profile.c208
-rw-r--r--drivers/s390/block/dasd_types.h284
-rw-r--r--drivers/s390/block/mdisk.c790
-rw-r--r--drivers/s390/block/mdisk.h94
-rw-r--r--drivers/s390/char/Makefile16
-rw-r--r--drivers/s390/char/con3215.c1129
-rw-r--r--drivers/s390/char/hwc.h249
-rw-r--r--drivers/s390/char/hwc_con.c99
-rw-r--r--drivers/s390/char/hwc_rw.c2016
-rw-r--r--drivers/s390/char/hwc_rw.h113
-rw-r--r--drivers/s390/char/hwc_tty.c265
-rw-r--r--drivers/s390/misc/Makefile13
-rw-r--r--drivers/s390/misc/chandev.c759
-rw-r--r--drivers/s390/net/Makefile16
-rw-r--r--drivers/s390/net/ctc.c1581
-rw-r--r--drivers/s390/net/iucv.c1178
-rw-r--r--drivers/s390/net/iucv.h146
-rw-r--r--drivers/sound/maestro.c12
-rw-r--r--drivers/sound/via82cxxx_audio.c160
-rw-r--r--drivers/usb/Config.in2
-rw-r--r--drivers/usb/uhci.c8
-rw-r--r--drivers/video/acornfb.c77
-rw-r--r--drivers/video/acornfb.h1
-rw-r--r--drivers/video/cyber2000fb.c1450
-rw-r--r--drivers/video/cyber2000fb.h68
68 files changed, 22043 insertions, 6147 deletions
diff --git a/drivers/acorn/scsi/arxescsi.c b/drivers/acorn/scsi/arxescsi.c
index 27e5b266a..2e04df6ca 100644
--- a/drivers/acorn/scsi/arxescsi.c
+++ b/drivers/acorn/scsi/arxescsi.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/drivers/scsi/arxescsi.c
*
- * Copyright (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King, Stefan Hanske
*
* This driver is based on experimentation. Hence, it may have made
* assumptions about the particular card that I have available, and
@@ -11,9 +11,11 @@
* 30-08-1997 RMK 0.0.0 Created, READONLY version as cumana_2.c
* 22-01-1998 RMK 0.0.1 Updated to 2.1.80
* 15-04-1998 RMK 0.0.1 Only do PIO if FAS216 will allow it.
- * 11-06-1998 0.0.2 Changed to support ARXE 16-bit SCSI card, enabled writing
- * by Stefan Hanske
- * 02-04-2000 RMK 0.0.3 Updated for new error handling code.
+ * 11-06-1998 SH 0.0.2 Changed to support ARXE 16-bit SCSI card
+ * enabled writing
+ * 01-01-2000 SH 0.1.0 Added *real* pseudo dma writing
+ * (arxescsi_pseudo_dma_write)
+ * 02-04-2000 RMK 0.1.1 Updated for new error handling code.
*/
#include <linux/module.h>
@@ -54,8 +56,8 @@
* Version
*/
#define VER_MAJOR 0
-#define VER_MINOR 0
-#define VER_PATCH 3
+#define VER_MINOR 1
+#define VER_PATCH 1
static struct expansion_card *ecs[MAX_ECARDS];
@@ -115,6 +117,33 @@ static __inline__ void putw(unsigned int address, unsigned int reg, unsigned lon
: "r" (value), "r" (address), "r" (reg) );
}
+void arxescsi_pseudo_dma_write(unsigned char *addr, unsigned int io)
+{
+ __asm__ __volatile__(
+ " stmdb sp!, {r0-r12}\n"
+ " mov r3, %0\n"
+ " mov r1, %1\n"
+ " add r2, r1, #512\n"
+ " mov r4, #256\n"
+ ".loop_1: ldmia r3!, {r6, r8, r10, r12}\n"
+ " mov r5, r6, lsl #16\n"
+ " mov r7, r8, lsl #16\n"
+ ".loop_2: ldrb r0, [r1, #1536]\n"
+ " tst r0, #1\n"
+ " beq .loop_2\n"
+ " stmia r2, {r5-r8}\n\t"
+ " mov r9, r10, lsl #16\n"
+ " mov r11, r12, lsl #16\n"
+ ".loop_3: ldrb r0, [r1, #1536]\n"
+ " tst r0, #1\n"
+ " beq .loop_3\n"
+ " stmia r2, {r9-r12}\n"
+ " subs r4, r4, #16\n"
+ " bne .loop_1\n"
+ " ldmia sp!, {r0-r12}\n"
+ :
+ : "r" (addr), "r" (io) );
+}
/*
* Function: int arxescsi_dma_pseudo(host, SCpnt, direction, transfer)
@@ -136,26 +165,36 @@ void arxescsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp,
io = __ioaddr(host->io_port);
if (direction == DMA_OUT) {
- while (length > 0) {
- unsigned long word;
-
-
- word = *addr | *(addr + 1) << 8;
- if (getb(io, 4) & STAT_INT)
+ unsigned int word;
+ while (length > 256) {
+ if (getb(io, 4) & STAT_INT) {
+ error=1;
break;
+ }
+ arxescsi_pseudo_dma_write(addr, io);
+ addr += 256;
+ length -= 256;
+ }
+
+ if (!error)
+ while (length > 0) {
+ if (getb(io, 4) & STAT_INT)
+ break;
+
+ if (!(getb(io, 48) & CSTATUS_IRQ))
+ continue;
- if (!(getb(io, 48) & CSTATUS_IRQ))
- continue;
+ word = *addr | *(addr + 1) << 8;
- putw(io, 16, word);
- if (length > 1) {
- addr += 2;
- length -= 2;
- } else {
- addr += 1;
- length -= 1;
+ putw(io, 16, word);
+ if (length > 1) {
+ addr += 2;
+ length -= 2;
+ } else {
+ addr += 1;
+ length -= 1;
+ }
}
- }
}
else {
if (transfer && (transfer & 255)) {
diff --git a/drivers/acorn/scsi/arxescsi.h b/drivers/acorn/scsi/arxescsi.h
index dd97233ae..b95c9340a 100644
--- a/drivers/acorn/scsi/arxescsi.h
+++ b/drivers/acorn/scsi/arxescsi.h
@@ -41,9 +41,7 @@ extern int arxescsi_proc_info (char *buffer, char **start, off_t offset,
#include <scsi/scsicam.h>
-#ifndef HOSTS_C
#include "fas216.h"
-#endif
#define ARXEScsi { \
proc_info: arxescsi_proc_info, \
diff --git a/drivers/acorn/scsi/cumana_2.h b/drivers/acorn/scsi/cumana_2.h
index 48ac695b7..ec63eb347 100644
--- a/drivers/acorn/scsi/cumana_2.h
+++ b/drivers/acorn/scsi/cumana_2.h
@@ -39,9 +39,7 @@ extern int cumanascsi_2_proc_info (char *buffer, char **start, off_t offset,
#include <scsi/scsicam.h>
-#ifndef HOSTS_C
#include "fas216.h"
-#endif
#define CUMANASCSI_2 { \
proc_info: cumanascsi_2_proc_info, \
diff --git a/drivers/block/Config.in b/drivers/block/Config.in
index 4abd42a54..679545b7c 100644
--- a/drivers/block/Config.in
+++ b/drivers/block/Config.in
@@ -48,9 +48,12 @@ fi
bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED $CONFIG_BLK_DEV_MD
-#dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING $CONFIG_BLK_DEV_MD
-#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
+dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
+bool ' DANGEROUS! RAID1/RAID5 code' CONFIG_RAID15_DANGEROUS
+if [ "$CONFIG_RAID15_DANGEROUS" = "y" ]; then
+ dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
+ dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
+fi
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index 9f5c813d7..66d5ba316 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -149,46 +149,32 @@ else
endif
endif
-ifeq ($(CONFIG_MD_STRIPED),y)
+ifeq ($(CONFIG_MD_RAID0),y)
L_OBJS += raid0.o
else
- ifeq ($(CONFIG_MD_STRIPED),m)
+ ifeq ($(CONFIG_MD_RAID0),m)
M_OBJS += raid0.o
endif
endif
-ifeq ($(CONFIG_MD_MIRRORING),y)
+ifeq ($(CONFIG_MD_RAID1),y)
L_OBJS += raid1.o
else
- ifeq ($(CONFIG_MD_MIRRORING),m)
+ ifeq ($(CONFIG_MD_RAID1),m)
M_OBJS += raid1.o
endif
endif
ifeq ($(CONFIG_MD_RAID5),y)
+LX_OBJS += xor.o
L_OBJS += raid5.o
else
ifeq ($(CONFIG_MD_RAID5),m)
+ LX_OBJS += xor.o
M_OBJS += raid5.o
endif
endif
-ifeq ($(CONFIG_MD_TRANSLUCENT),y)
-L_OBJS += translucent.o
-else
- ifeq ($(CONFIG_MD_TRANSLUCENT),m)
- M_OBJS += translucent.o
- endif
-endif
-
-ifeq ($(CONFIG_MD_HSM),y)
-L_OBJS += hsm.o
-else
- ifeq ($(CONFIG_MD_HSM),m)
- M_OBJS += hsm.o
- endif
-endif
-
endif
ifeq ($(CONFIG_BLK_DEV_NBD),y)
diff --git a/drivers/block/linear.c b/drivers/block/linear.c
index 978d75b80..926792a0f 100644
--- a/drivers/block/linear.c
+++ b/drivers/block/linear.c
@@ -184,13 +184,11 @@ static int linear_status (char *page, mddev_t *mddev)
static mdk_personality_t linear_personality=
{
"linear",
- NULL,
linear_make_request,
NULL,
linear_run,
linear_stop,
linear_status,
- NULL,
0,
NULL,
NULL,
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
index 12a08384f..4380900e9 100644
--- a/drivers/block/ll_rw_blk.c
+++ b/drivers/block/ll_rw_blk.c
@@ -373,40 +373,23 @@ void set_device_ro(kdev_t dev,int flag)
else ro_bits[major][minor >> 5] &= ~(1 << (minor & 31));
}
-static inline void drive_stat_acct(struct request *req,
+inline void drive_stat_acct (kdev_t dev, int rw,
unsigned long nr_sectors, int new_io)
{
- int major = MAJOR(req->rq_dev);
- int minor = MINOR(req->rq_dev);
- unsigned int disk_index;
+ unsigned int major = MAJOR(dev);
+ unsigned int index;
- switch (major) {
- case DAC960_MAJOR+0:
- disk_index = (minor & 0x00f8) >> 3;
- break;
- case SCSI_DISK0_MAJOR:
- disk_index = (minor & 0x00f0) >> 4;
- break;
- case IDE0_MAJOR: /* same as HD_MAJOR */
- case XT_DISK_MAJOR:
- disk_index = (minor & 0x0040) >> 6;
- break;
- case IDE1_MAJOR:
- disk_index = ((minor & 0x0040) >> 6) + 2;
- break;
- default:
- return;
- }
- if (disk_index >= DK_NDRIVE)
+ index = disk_index(dev);
+ if ((index >= DK_MAX_DISK) || (major >= DK_MAX_MAJOR))
return;
- kstat.dk_drive[disk_index] += new_io;
- if (req->cmd == READ) {
- kstat.dk_drive_rio[disk_index] += new_io;
- kstat.dk_drive_rblk[disk_index] += nr_sectors;
- } else if (req->cmd == WRITE) {
- kstat.dk_drive_wio[disk_index] += new_io;
- kstat.dk_drive_wblk[disk_index] += nr_sectors;
+ kstat.dk_drive[major][index] += new_io;
+ if (rw == READ) {
+ kstat.dk_drive_rio[major][index] += new_io;
+ kstat.dk_drive_rblk[major][index] += nr_sectors;
+ } else if (rw == WRITE) {
+ kstat.dk_drive_wio[major][index] += new_io;
+ kstat.dk_drive_wblk[major][index] += nr_sectors;
} else
printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
}
@@ -426,7 +409,7 @@ static inline void add_request(request_queue_t * q, struct request * req,
{
int major;
- drive_stat_acct(req, req->nr_sectors, 1);
+ drive_stat_acct(req->rq_dev, req->cmd, req->nr_sectors, 1);
if (list_empty(head)) {
req->elevator_sequence = elevator_sequence(&q->elevator, latency);
@@ -686,7 +669,7 @@ static inline void __make_request(request_queue_t * q, int rw,
req->bhtail->b_reqnext = bh;
req->bhtail = bh;
req->nr_sectors = req->hard_nr_sectors += count;
- drive_stat_acct(req, count, 0);
+ drive_stat_acct(req->rq_dev, req->cmd, count, 0);
elevator_merge_after(elevator, req, latency);
@@ -716,7 +699,7 @@ static inline void __make_request(request_queue_t * q, int rw,
req->current_nr_sectors = count;
req->sector = req->hard_sector = sector;
req->nr_sectors = req->hard_nr_sectors += count;
- drive_stat_acct(req, count, 0);
+ drive_stat_acct(req->rq_dev, req->cmd, count, 0);
elevator_merge_before(elevator, req, latency);
@@ -1090,6 +1073,7 @@ EXPORT_SYMBOL(io_request_lock);
EXPORT_SYMBOL(end_that_request_first);
EXPORT_SYMBOL(end_that_request_last);
EXPORT_SYMBOL(blk_init_queue);
+EXPORT_SYMBOL(blk_get_queue);
EXPORT_SYMBOL(blk_cleanup_queue);
EXPORT_SYMBOL(blk_queue_headactive);
EXPORT_SYMBOL(blk_queue_pluggable);
diff --git a/drivers/block/md.c b/drivers/block/md.c
index d9c1ab9c0..1af15fd05 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -1,6 +1,6 @@
/*
md.c : Multiple Devices driver for Linux
- Copyright (C) 1998, 1999, 2000 Ingo Molnar
+ Copyright (C) 1998, 1999, 2000 Ingo Molnar
completely rewritten, based on the MD driver code from Marc Zyngier
@@ -13,6 +13,11 @@
- RAID0 bugfixes: Mark Anthony Lisher <markal@iname.com>
- Devfs support by Richard Gooch <rgooch@atnf.csiro.au>
+ - lots of fixes and improvements to the RAID1/RAID5 and generic
+ RAID code (such as request based resynchronization):
+
+ Neil Brown <neilb@cse.unsw.edu.au>.
+
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)
@@ -25,6 +30,7 @@
#include <linux/config.h>
#include <linux/raid/md.h>
+#include <linux/raid/xor.h>
#include <linux/devfs_fs_kernel.h>
#ifdef CONFIG_KMOD
@@ -39,8 +45,6 @@
extern asmlinkage int sys_sched_yield(void);
extern asmlinkage int sys_setsid(void);
-extern unsigned long io_events[MAX_BLKDEV];
-
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
@@ -56,6 +60,41 @@ extern unsigned long io_events[MAX_BLKDEV];
static mdk_personality_t *pers[MAX_PERSONALITY] = {NULL, };
/*
+ * Current RAID-1,4,5 parallel reconstruction 'guaranteed speed limit'
+ * is 100 KB/sec, so the extra system load does not show up that much.
+ * Increase it if you want to have more _guaranteed_ speed. Note that
+ * the RAID driver will use the maximum available bandwith if the IO
+ * subsystem is idle. There is also an 'absolute maximum' reconstruction
+ * speed limit - in case reconstruction slows down your system despite
+ * idle IO detection.
+ *
+ * you can change it via /proc/sys/dev/raid/speed_limit_min and _max.
+ */
+
+static int sysctl_speed_limit_min = 100;
+static int sysctl_speed_limit_max = 100000;
+
+static struct ctl_table_header *raid_table_header;
+
+static ctl_table raid_table[] = {
+ {DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min",
+ &sysctl_speed_limit_min, sizeof(int), 0644, NULL, &proc_dointvec},
+ {DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max",
+ &sysctl_speed_limit_max, sizeof(int), 0644, NULL, &proc_dointvec},
+ {0}
+};
+
+static ctl_table raid_dir_table[] = {
+ {DEV_RAID, "raid", NULL, 0, 0555, raid_table},
+ {0}
+};
+
+static ctl_table raid_root_table[] = {
+ {CTL_DEV, "dev", NULL, 0, 0555, raid_dir_table},
+ {0}
+};
+
+/*
* these have to be allocated separately because external
* subsystems want to have a pre-defined structure
*/
@@ -215,8 +254,8 @@ static mddev_t * alloc_mddev (kdev_t dev)
blk_queue_make_request(q, md_make_request);
q->plug_tq.sync = 0;
- q->plug_tq.routine = &md_unplug_device;
- q->plug_tq.data = mddev;
+ q->plug_tq.routine = &md_unplug_device;
+ q->plug_tq.data = mddev;
/*
* The 'base' mddev is the one with data NULL.
@@ -504,7 +543,7 @@ static int read_disk_sb (mdk_rdev_t * rdev)
struct buffer_head *bh = NULL;
kdev_t dev = rdev->dev;
mdp_super_t *sb;
- u32 sb_offset;
+ unsigned long sb_offset;
if (!rdev->sb) {
MD_BUG();
@@ -517,8 +556,7 @@ static int read_disk_sb (mdk_rdev_t * rdev)
*/
sb_offset = calc_dev_sboffset(rdev->dev, rdev->mddev, 1);
rdev->sb_offset = sb_offset;
- printk("(read) %s's sb offset: %d", partition_name(dev),
- sb_offset);
+ printk("(read) %s's sb offset: %ld", partition_name(dev), sb_offset);
fsync_dev(dev);
set_blocksize (dev, MD_SB_BYTES);
bh = bread (dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
@@ -606,6 +644,18 @@ static mdk_rdev_t * match_dev_unit(mddev_t *mddev, kdev_t dev)
return NULL;
}
+static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
+{
+ struct md_list_head *tmp;
+ mdk_rdev_t *rdev;
+
+ ITERATE_RDEV(mddev1,rdev,tmp)
+ if (match_dev_unit(mddev2, rdev->dev))
+ return 1;
+
+ return 0;
+}
+
static MD_LIST_HEAD(all_raid_disks);
static MD_LIST_HEAD(pending_raid_disks);
@@ -798,7 +848,7 @@ static void print_sb(mdp_super_t *sb)
static void print_rdev(mdk_rdev_t *rdev)
{
- printk(" rdev %s: O:%s, SZ:%08d F:%d DN:%d ",
+ printk(" rdev %s: O:%s, SZ:%08ld F:%d DN:%d ",
partition_name(rdev->dev), partition_name(rdev->old_dev),
rdev->size, rdev->faulty, rdev->desc_nr);
if (rdev->sb) {
@@ -815,9 +865,9 @@ void md_print_devices (void)
mddev_t *mddev;
printk("\n");
- printk(" **********************************\n");
- printk(" * <COMPLETE RAID STATE PRINTOUT> *\n");
- printk(" **********************************\n");
+ printk(" **********************************\n");
+ printk(" * <COMPLETE RAID STATE PRINTOUT> *\n");
+ printk(" **********************************\n");
ITERATE_MDDEV(mddev,tmp) {
printk("md%d: ", mdidx(mddev));
@@ -833,7 +883,7 @@ void md_print_devices (void)
ITERATE_RDEV(mddev,rdev,tmp2)
print_rdev(rdev);
}
- printk(" **********************************\n");
+ printk(" **********************************\n");
printk("\n");
}
@@ -907,7 +957,7 @@ static int write_disk_sb(mdk_rdev_t * rdev)
{
struct buffer_head *bh;
kdev_t dev;
- u32 sb_offset, size;
+ unsigned long sb_offset, size;
mdp_super_t *sb;
if (!rdev->sb) {
@@ -926,7 +976,7 @@ static int write_disk_sb(mdk_rdev_t * rdev)
dev = rdev->dev;
sb_offset = calc_dev_sboffset(dev, rdev->mddev, 1);
if (rdev->sb_offset != sb_offset) {
- printk("%s's sb offset has changed from %d to %d, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
+ printk("%s's sb offset has changed from %ld to %ld, skipping\n", partition_name(dev), rdev->sb_offset, sb_offset);
goto skip;
}
/*
@@ -936,11 +986,11 @@ static int write_disk_sb(mdk_rdev_t * rdev)
*/
size = calc_dev_size(dev, rdev->mddev, 1);
if (size != rdev->size) {
- printk("%s's size has changed from %d to %d since import, skipping\n", partition_name(dev), rdev->size, size);
+ printk("%s's size has changed from %ld to %ld since import, skipping\n", partition_name(dev), rdev->size, size);
goto skip;
}
- printk("(write) %s's sb offset: %d\n", partition_name(dev), sb_offset);
+ printk("(write) %s's sb offset: %ld\n", partition_name(dev), sb_offset);
fsync_dev(dev);
set_blocksize(dev, MD_SB_BYTES);
bh = getblk(dev, sb_offset / MD_SB_BLOCKS, MD_SB_BYTES);
@@ -1053,7 +1103,7 @@ repeat:
printk("%s ", partition_name(rdev->dev));
if (!rdev->faulty) {
printk("[events: %08lx]",
- (unsigned long)get_unaligned(&rdev->sb->events));
+ (unsigned long)get_unaligned(&rdev->sb->events));
err += write_disk_sb(rdev);
} else
printk(")\n");
@@ -1244,7 +1294,7 @@ static int analyze_sbs (mddev_t * mddev)
}
printk("%s's event counter: %08lx\n", partition_name(rdev->dev),
- (unsigned long)get_unaligned(&rdev->sb->events));
+ (unsigned long)get_unaligned(&rdev->sb->events));
if (!freshest) {
freshest = rdev;
continue;
@@ -1488,7 +1538,7 @@ static int device_size_calculation (mddev_t * mddev)
rdev->size = calc_dev_size(rdev->dev, mddev, persistent);
if (rdev->size < sb->chunk_size / 1024) {
printk (KERN_WARNING
- "Dev %s smaller than chunk_size: %dk < %dk\n",
+ "Dev %s smaller than chunk_size: %ldk < %dk\n",
partition_name(rdev->dev),
rdev->size, sb->chunk_size / 1024);
return -EINVAL;
@@ -2640,7 +2690,7 @@ static int md_ioctl (struct inode *inode, struct file *file,
case STOP_ARRAY:
err = do_md_stop (mddev, 0);
- goto done_unlock;
+ goto done;
case STOP_ARRAY_RO:
err = do_md_stop (mddev, 1);
@@ -2817,13 +2867,13 @@ int md_thread(void * arg)
DECLARE_WAITQUEUE(wait, current);
add_wait_queue(&thread->wqueue, &wait);
+ set_task_state(current, TASK_INTERRUPTIBLE);
if (!test_bit(THREAD_WAKEUP, &thread->flags)) {
- set_task_state(current, TASK_INTERRUPTIBLE);
dprintk("thread %p went to sleep.\n", thread);
schedule();
dprintk("thread %p woke up.\n", thread);
- current->state = TASK_RUNNING;
}
+ current->state = TASK_RUNNING;
remove_wait_queue(&thread->wqueue, &wait);
clear_bit(THREAD_WAKEUP, &thread->flags);
@@ -2914,12 +2964,13 @@ void md_recover_arrays (void)
int md_error (kdev_t dev, kdev_t rdev)
{
- mddev_t *mddev = kdev_to_mddev(dev);
+ mddev_t *mddev;
mdk_rdev_t * rrdev;
int rc;
- printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3));
-
+ mddev = kdev_to_mddev(dev);
+/* printk("md_error dev:(%d:%d), rdev:(%d:%d), (caller: %p,%p,%p,%p).\n",MAJOR(dev),MINOR(dev),MAJOR(rdev),MINOR(rdev), __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2),__builtin_return_address(3));
+ */
if (!mddev) {
MD_BUG();
return 0;
@@ -2970,11 +3021,10 @@ static int status_unused (char * page)
static int status_resync (char * page, mddev_t * mddev)
{
int sz = 0;
- unsigned int blocksize, max_blocks, resync, res, dt, tt, et;
+ unsigned int max_blocks, resync, res, dt, tt, et;
resync = mddev->curr_resync;
- blocksize = blksize_size[MD_MAJOR][mdidx(mddev)];
- max_blocks = blk_size[MD_MAJOR][mdidx(mddev)] / (blocksize >> 10);
+ max_blocks = mddev->sb->size;
/*
* Should not happen.
@@ -3093,7 +3143,7 @@ static int md_status_read_proc(char *page, char **start, off_t off,
sz += status_resync (page+sz, mddev);
} else {
if (md_atomic_read(&mddev->resync_sem.count) != 1)
- sz += sprintf(page + sz, " resync=DELAYED");
+ sz += sprintf(page + sz, " resync=DELAYED");
}
sz += sprintf(page + sz, "\n");
}
@@ -3125,6 +3175,298 @@ int unregister_md_personality (int pnum)
return 0;
}
+static mdp_disk_t *get_spare(mddev_t *mddev)
+{
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *disk;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty)
+ continue;
+ if (!rdev->sb) {
+ MD_BUG();
+ continue;
+ }
+ disk = &sb->disks[rdev->desc_nr];
+ if (disk_faulty(disk)) {
+ MD_BUG();
+ continue;
+ }
+ if (disk_active(disk))
+ continue;
+ return disk;
+ }
+ return NULL;
+}
+
+static int is_mddev_idle (mddev_t *mddev)
+{
+ mdk_rdev_t * rdev;
+ struct md_list_head *tmp;
+ int idle;
+ unsigned long curr_events;
+
+ idle = 1;
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ int major = MAJOR(rdev->dev);
+ int idx = disk_index(rdev->dev);
+
+ curr_events = kstat.dk_drive_rblk[major][idx] +
+ kstat.dk_drive_wblk[major][idx] ;
+// printk("events(major: %d, idx: %d): %ld\n", major, idx, curr_events);
+ if (curr_events != rdev->last_events) {
+// printk("!I(%ld)", curr_events - rdev->last_events);
+ rdev->last_events = curr_events;
+ idle = 0;
+ }
+ }
+ return idle;
+}
+
+MD_DECLARE_WAIT_QUEUE_HEAD(resync_wait);
+
+void md_done_sync(mddev_t *mddev, int blocks, int ok)
+{
+ /* another "blocks" (1K) blocks have been synced */
+ atomic_sub(blocks, &mddev->recovery_active);
+ wake_up(&mddev->recovery_wait);
+ if (!ok) {
+ // stop recovery, signal do_sync ....
+ }
+}
+
+int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
+{
+ mddev_t *mddev2;
+ unsigned int max_blocks, currspeed,
+ j, window, err, serialize;
+ kdev_t read_disk = mddev_to_kdev(mddev);
+ unsigned long starttime;
+ struct md_list_head *tmp;
+ unsigned long last_check;
+
+
+ err = down_interruptible(&mddev->resync_sem);
+ if (err)
+ goto out_nolock;
+
+recheck:
+ serialize = 0;
+ ITERATE_MDDEV(mddev2,tmp) {
+ if (mddev2 == mddev)
+ continue;
+ if (mddev2->curr_resync && match_mddev_units(mddev,mddev2)) {
+ printk(KERN_INFO "md: serializing resync, md%d has overlapping physical units with md%d!\n", mdidx(mddev), mdidx(mddev2));
+ serialize = 1;
+ break;
+ }
+ }
+ if (serialize) {
+ interruptible_sleep_on(&resync_wait);
+ if (md_signal_pending(current)) {
+ md_flush_signals();
+ err = -EINTR;
+ goto out;
+ }
+ goto recheck;
+ }
+
+ mddev->curr_resync = 1;
+
+ max_blocks = mddev->sb->size;
+
+ printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
+ printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d KB/sec/disc.\n",
+ sysctl_speed_limit_min);
+ printk(KERN_INFO "md: using maximum available idle IO bandwith (but not more than %d KB/sec) for reconstruction.\n", sysctl_speed_limit_max);
+
+ /*
+ * Resync has low priority.
+ */
+ current->priority = 1;
+
+ is_mddev_idle(mddev); /* this also initializes IO event counters */
+ starttime = jiffies;
+ mddev->resync_start = starttime;
+
+ /*
+ * Tune reconstruction:
+ */
+ window = md_maxreadahead[mdidx(mddev)]/1024;
+ printk(KERN_INFO "md: using %dk window, over a total of %d blocks.\n",window,max_blocks);
+
+ atomic_set(&mddev->recovery_active, 0);
+ init_waitqueue_head(&mddev->recovery_wait);
+ last_check = 0;
+ for (j = 0; j < max_blocks;) {
+ int blocks;
+ if (j)
+ mddev->curr_resync = j;
+
+/* wait_event(mddev->recovery_wait,
+ atomic_read(&mddev->recovery_active) < window);
+*/
+ blocks = mddev->pers->sync_request(mddev, j);
+
+ if (blocks < 0) {
+ err = blocks;
+ goto out;
+ }
+ atomic_add(blocks, &mddev->recovery_active);
+ j += blocks;
+
+ if (last_check + window > j)
+ continue;
+
+ run_task_queue(&tq_disk); //??
+
+
+ if (md_signal_pending(current)) {
+ /*
+ * got a signal, exit.
+ */
+ mddev->curr_resync = 0;
+ printk("md_do_sync() got signal ... exiting\n");
+ md_flush_signals();
+ err = -EINTR;
+ goto out;
+ }
+
+ /*
+ * this loop exits only if either when we are slower than
+ * the 'hard' speed limit, or the system was IO-idle for
+ * a jiffy.
+ * the system might be non-idle CPU-wise, but we only care
+ * 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();
+
+ currspeed = j/((jiffies-starttime)/HZ + 1) + 1;
+ if (currspeed > sysctl_speed_limit_min) {
+ current->priority = 1;
+
+ if ((currspeed > sysctl_speed_limit_max) ||
+ !is_mddev_idle(mddev)) {
+ current->state = TASK_INTERRUPTIBLE;
+ md_schedule_timeout(HZ/4);
+ if (!md_signal_pending(current))
+ goto repeat;
+ }
+ } else
+ current->priority = 40;
+ }
+ wait_event(mddev->recovery_wait, atomic_read(&mddev->recovery_active)==0);
+ fsync_dev(read_disk);
+ printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
+ err = 0;
+ /*
+ * this also signals 'finished resyncing' to md_stop
+ */
+out:
+ up(&mddev->resync_sem);
+out_nolock:
+ mddev->curr_resync = 0;
+ wake_up(&resync_wait);
+ return err;
+}
+
+
+/*
+ * This is a kernel thread which syncs a spare disk with the active array
+ *
+ * the amount of foolproofing might seem to be a tad excessive, but an
+ * early (not so error-safe) version of raid1syncd synced the first 0.5 gigs
+ * of my root partition with the first 0.5 gigs of my /home partition ... so
+ * i'm a bit nervous ;)
+ */
+void md_do_recovery (void *data)
+{
+ int err;
+ mddev_t *mddev;
+ mdp_super_t *sb;
+ mdp_disk_t *spare;
+ struct md_list_head *tmp;
+
+ printk(KERN_INFO "md: recovery thread got woken up ...\n");
+restart:
+ ITERATE_MDDEV(mddev,tmp) {
+ sb = mddev->sb;
+ if (!sb)
+ continue;
+ if (mddev->recovery_running)
+ continue;
+ if (sb->active_disks == sb->raid_disks)
+ continue;
+ if (!sb->spare_disks) {
+ printk(KERN_ERR "md%d: no spare disk to reconstruct array! -- continuing in degraded mode\n", mdidx(mddev));
+ continue;
+ }
+ /*
+ * now here we get the spare and resync it.
+ */
+ if ((spare = get_spare(mddev)) == NULL)
+ continue;
+ printk(KERN_INFO "md%d: resyncing spare disk %s to replace failed disk\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+ if (!mddev->pers->diskop)
+ continue;
+ if (mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_WRITE))
+ continue;
+ down(&mddev->recovery_sem);
+ mddev->recovery_running = 1;
+ err = md_do_sync(mddev, spare);
+ if (err == -EIO) {
+ printk(KERN_INFO "md%d: spare disk %s failed, skipping to next spare.\n", mdidx(mddev), partition_name(MKDEV(spare->major,spare->minor)));
+ if (!disk_faulty(spare)) {
+ mddev->pers->diskop(mddev,&spare,DISKOP_SPARE_INACTIVE);
+ mark_disk_faulty(spare);
+ mark_disk_nonsync(spare);
+ mark_disk_inactive(spare);
+ sb->spare_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+ }
+ } else
+ if (disk_faulty(spare))
+ mddev->pers->diskop(mddev, &spare,
+ DISKOP_SPARE_INACTIVE);
+ if (err == -EINTR) {
+ /*
+ * Recovery got interrupted ...
+ * signal back that we have finished using the array.
+ */
+ mddev->pers->diskop(mddev, &spare,
+ DISKOP_SPARE_INACTIVE);
+ up(&mddev->recovery_sem);
+ mddev->recovery_running = 0;
+ continue;
+ } else {
+ mddev->recovery_running = 0;
+ up(&mddev->recovery_sem);
+ }
+ if (!disk_faulty(spare)) {
+ /*
+ * the SPARE_ACTIVE diskop possibly changes the
+ * pointer too
+ */
+ mddev->pers->diskop(mddev, &spare, DISKOP_SPARE_ACTIVE);
+ mark_disk_sync(spare);
+ mark_disk_active(spare);
+ sb->active_disks++;
+ sb->spare_disks--;
+ }
+ mddev->sb_dirty = 1;
+ md_update_sb(mddev);
+ goto restart;
+ }
+ printk(KERN_INFO "md: recovery thread finished ...\n");
+
+}
+
int md_notify_reboot(struct notifier_block *this,
unsigned long code, void *x)
{
@@ -3211,6 +3553,8 @@ void raid5_init (void);
int md__init md_init (void)
{
+ static char * name = "mdrecoveryd";
+
printk (KERN_INFO "md driver %d.%d.%d MAX_MD_DEVS=%d, MAX_REAL=%d\n",
MD_MAJOR_VERSION, MD_MINOR_VERSION,
MD_PATCHLEVEL_VERSION, MAX_MD_DEVS, MAX_REAL);
@@ -3222,8 +3566,8 @@ int md__init md_init (void)
}
devfs_handle = devfs_mk_dir (NULL, "md", 0, NULL);
devfs_register_series (devfs_handle, "%u",MAX_MD_DEVS,DEVFS_FL_DEFAULT,
- MAJOR_NR, 0, S_IFBLK | S_IRUSR | S_IWUSR, 0, 0,
- &md_fops, NULL);
+ MAJOR_NR, 0, S_IFBLK | S_IRUSR | S_IWUSR, 0, 0,
+ &md_fops, NULL);
blk_dev[MD_MAJOR].queue = md_get_queue;
@@ -3232,24 +3576,29 @@ int md__init md_init (void)
gendisk_head = &md_gendisk;
+ md_recovery_thread = md_register_thread(md_do_recovery, NULL, name);
+ if (!md_recovery_thread)
+ printk(KERN_ALERT "bug: couldn't allocate md_recovery_thread\n");
+
md_register_reboot_notifier(&md_notifier);
+ raid_table_header = register_sysctl_table(raid_root_table, 1);
#ifdef CONFIG_MD_LINEAR
linear_init ();
#endif
-#ifdef CONFIG_MD_STRIPED
+#ifdef CONFIG_MD_RAID0
raid0_init ();
#endif
-#ifdef CONFIG_MD_MIRRORING
+#ifdef CONFIG_MD_RAID1
raid1_init ();
#endif
#ifdef CONFIG_MD_RAID5
raid5_init ();
#endif
#if defined(CONFIG_MD_RAID5) || defined(CONFIG_MD_RAID5_MODULE)
- /*
- * pick a XOR routine, runtime.
- */
+ /*
+ * pick a XOR routine, runtime.
+ */
calibrate_xor_block();
#endif
md_geninit();
@@ -3261,6 +3610,8 @@ MD_EXPORT_SYMBOL(register_md_personality);
MD_EXPORT_SYMBOL(unregister_md_personality);
MD_EXPORT_SYMBOL(partition_name);
MD_EXPORT_SYMBOL(md_error);
+MD_EXPORT_SYMBOL(md_do_sync);
+MD_EXPORT_SYMBOL(md_done_sync);
MD_EXPORT_SYMBOL(md_recover_arrays);
MD_EXPORT_SYMBOL(md_register_thread);
MD_EXPORT_SYMBOL(md_unregister_thread);
diff --git a/drivers/block/raid0.c b/drivers/block/raid0.c
index 0e075277a..83700e235 100644
--- a/drivers/block/raid0.c
+++ b/drivers/block/raid0.c
@@ -41,7 +41,7 @@ static int create_strip_zones (mddev_t *mddev)
printk("raid0: looking at %s\n", partition_name(rdev1->dev));
c = 0;
ITERATE_RDEV_ORDERED(mddev,rdev2,j2) {
- printk("raid0: comparing %s(%d) with %s(%d)\n", partition_name(rdev1->dev), rdev1->size, partition_name(rdev2->dev), rdev2->size);
+ printk("raid0: comparing %s(%ld) with %s(%ld)\n", partition_name(rdev1->dev), rdev1->size, partition_name(rdev2->dev), rdev2->size);
if (rdev2 == rdev1) {
printk("raid0: END\n");
break;
@@ -95,7 +95,7 @@ static int create_strip_zones (mddev_t *mddev)
c++;
if (!smallest || (rdev->size <smallest->size)) {
smallest = rdev;
- printk(" (%d) is smallest!.\n", rdev->size);
+ printk(" (%ld) is smallest!.\n", rdev->size);
}
} else
printk(" nope.\n");
@@ -326,13 +326,11 @@ static int raid0_status (char *page, mddev_t *mddev)
static mdk_personality_t raid0_personality=
{
"raid0",
- NULL, /* no special map */
raid0_make_request,
NULL, /* no special end_request */
raid0_run,
raid0_stop,
raid0_status,
- NULL, /* no ioctls */
0,
NULL, /* no error_handler */
NULL, /* no diskop */
diff --git a/drivers/block/raid1.c b/drivers/block/raid1.c
index 057be0d64..89b3e7514 100644
--- a/drivers/block/raid1.c
+++ b/drivers/block/raid1.c
@@ -1,6 +1,9 @@
-/************************************************************************
+/*
* raid1.c : Multiple Devices driver for Linux
- * Copyright (C) 1996 Ingo Molnar, Miguel de Icaza, Gadi Oxman
+ *
+ * Copyright (C) 1999, 2000 Ingo Molnar, Red Hat
+ *
+ * Copyright (C) 1996, 1997, 1998 Ingo Molnar, Miguel de Icaza, Gadi Oxman
*
* RAID-1 management functions.
*
@@ -15,50 +18,86 @@
*/
#include <linux/module.h>
-#include <linux/locks.h>
#include <linux/malloc.h>
-#include <linux/md.h>
-#include <linux/raid1.h>
-#include <asm/bitops.h>
+#include <linux/raid/raid1.h>
#include <asm/atomic.h>
#define MAJOR_NR MD_MAJOR
#define MD_DRIVER
#define MD_PERSONALITY
+#define MAX_LINEAR_SECTORS 128
+
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
/*
* The following can be used to debug the driver
*/
-/*#define RAID1_DEBUG*/
-#ifdef RAID1_DEBUG
-#define PRINTK(x) do { printk x; } while (0);
+#define RAID1_DEBUG 0
+
+#if RAID1_DEBUG
+#define PRINTK(x...) printk(x)
+#define inline
+#define __inline__
#else
-#define PRINTK(x) do { ; } while (0);
+#define inline
+#define __inline__
+#define PRINTK(x...) do { } while (0)
#endif
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#define MIN(a,b) ((a) < (b) ? (a) : (b))
-static struct md_personality raid1_personality;
-static struct md_thread *raid1_thread = NULL;
-struct buffer_head *raid1_retry_list = NULL;
+static mdk_personality_t raid1_personality;
+static md_spinlock_t retry_list_lock = MD_SPIN_LOCK_UNLOCKED;
+struct buffer_head *raid1_retry_list = NULL, **raid1_retry_tail;
+
+static void * raid1_kmalloc (int size)
+{
+ void * ptr;
+ /*
+ * now we are rather fault tolerant than nice, but
+ * there are a couple of places in the RAID code where we
+ * simply can not afford to fail an allocation because
+ * there is no failure return path (eg. make_request())
+ */
+ while (!(ptr = kmalloc (size, GFP_KERNEL)))
+ printk ("raid1: out of memory, retrying...\n");
+
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+static struct page * raid1_gfp (void)
+{
+ struct page *page;
+ /*
+ * now we are rather fault tolerant than nice, but
+ * there are a couple of places in the RAID code where we
+ * simply can not afford to fail an allocation because
+ * there is no failure return path (eg. make_request())
+ * FIXME: be nicer here.
+ */
+ while (!(page = (void*)alloc_page(GFP_KERNEL))) {
+ printk ("raid1: GFP out of memory, retrying...\n");
+ schedule_timeout(2);
+ }
+
+ return page;
+}
-static int __raid1_map (struct md_dev *mddev, kdev_t *rdev,
- unsigned long *rsector, unsigned long size)
+static int raid1_map (mddev_t *mddev, kdev_t *rdev, unsigned long size)
{
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
- int i, n = raid_conf->raid_disks;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ int i, disks = MD_SB_DISKS;
/*
* Later we do read balancing on the read side
* now we use the first available disk.
*/
- PRINTK(("raid1_map().\n"));
-
- for (i=0; i<n; i++) {
- if (raid_conf->mirrors[i].operational) {
- *rdev = raid_conf->mirrors[i].dev;
+ for (i = 0; i < disks; i++) {
+ if (conf->mirrors[i].operational) {
+ *rdev = conf->mirrors[i].dev;
return (0);
}
}
@@ -67,59 +106,80 @@ static int __raid1_map (struct md_dev *mddev, kdev_t *rdev,
return (-1);
}
-static int raid1_map (struct md_dev *mddev, kdev_t *rdev,
- unsigned long *rsector, unsigned long size)
+static void raid1_reschedule_retry (struct buffer_head *bh)
{
- return 0;
+ unsigned long flags;
+ struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_dev_id);
+ mddev_t *mddev = r1_bh->mddev;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+
+ md_spin_lock_irqsave(&retry_list_lock, flags);
+ if (raid1_retry_list == NULL)
+ raid1_retry_tail = &raid1_retry_list;
+ *raid1_retry_tail = bh;
+ raid1_retry_tail = &r1_bh->next_retry;
+ r1_bh->next_retry = NULL;
+ md_spin_unlock_irqrestore(&retry_list_lock, flags);
+ md_wakeup_thread(conf->thread);
}
-void raid1_reschedule_retry (struct buffer_head *bh)
-{
- struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_dev_id);
- PRINTK(("raid1_reschedule_retry().\n"));
+static void inline io_request_done(unsigned long sector, raid1_conf_t *conf, int phase)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&conf->segment_lock, flags);
+ if (sector < conf->start_active)
+ conf->cnt_done--;
+ else if (sector >= conf->start_future && conf->phase == phase)
+ conf->cnt_future--;
+ else if (!--conf->cnt_pending)
+ wake_up(&conf->wait_ready);
+
+ spin_unlock_irqrestore(&conf->segment_lock, flags);
+}
- r1_bh->next_retry = raid1_retry_list;
- raid1_retry_list = bh;
- md_wakeup_thread(raid1_thread);
+static void inline sync_request_done (unsigned long sector, raid1_conf_t *conf)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&conf->segment_lock, flags);
+ if (sector >= conf->start_ready)
+ --conf->cnt_ready;
+ else if (sector >= conf->start_active) {
+ if (!--conf->cnt_active) {
+ conf->start_active = conf->start_ready;
+ wake_up(&conf->wait_done);
+ }
+ }
+ spin_unlock_irqrestore(&conf->segment_lock, flags);
}
/*
- * raid1_end_buffer_io() is called when we have finished servicing a mirrored
+ * raid1_end_bh_io() is called when we have finished servicing a mirrored
* operation and are ready to return a success/failure code to the buffer
* cache layer.
*/
-static inline void raid1_end_buffer_io(struct raid1_bh *r1_bh, int uptodate)
+static void raid1_end_bh_io (struct raid1_bh *r1_bh, int uptodate)
{
struct buffer_head *bh = r1_bh->master_bh;
+ io_request_done(bh->b_rsector, mddev_to_conf(r1_bh->mddev),
+ test_bit(R1BH_SyncPhase, &r1_bh->state));
+
bh->b_end_io(bh, uptodate);
kfree(r1_bh);
}
-
-int raid1_one_error=0;
-
void raid1_end_request (struct buffer_head *bh, int uptodate)
{
struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_dev_id);
- unsigned long flags;
- save_flags(flags);
- cli();
- PRINTK(("raid1_end_request().\n"));
-
- if (raid1_one_error) {
- raid1_one_error=0;
- uptodate=0;
- }
/*
* this branch is our 'one mirror IO has finished' event handler:
*/
if (!uptodate)
md_error (bh->b_dev, bh->b_rdev);
- else {
+ else
/*
- * Set BH_Uptodate in our master buffer_head, so that
+ * Set R1BH_Uptodate in our master buffer_head, so that
* we will return a good error code for to the higher
* levels even if IO on some other mirrored buffer fails.
*
@@ -127,8 +187,7 @@ void raid1_end_request (struct buffer_head *bh, int uptodate)
* user-side. So if something waits for IO, then it will
* wait for the 'master' buffer_head.
*/
- set_bit (BH_Uptodate, &r1_bh->state);
- }
+ set_bit (R1BH_Uptodate, &r1_bh->state);
/*
* We split up the read and write side, imho they are
@@ -136,239 +195,253 @@ void raid1_end_request (struct buffer_head *bh, int uptodate)
*/
if ( (r1_bh->cmd == READ) || (r1_bh->cmd == READA) ) {
-
- PRINTK(("raid1_end_request(), read branch.\n"));
-
/*
* we have only one buffer_head on the read side
*/
+
if (uptodate) {
- PRINTK(("raid1_end_request(), read branch, uptodate.\n"));
- raid1_end_buffer_io(r1_bh, uptodate);
- restore_flags(flags);
+ raid1_end_bh_io(r1_bh, uptodate);
return;
}
/*
* oops, read error:
*/
printk(KERN_ERR "raid1: %s: rescheduling block %lu\n",
- kdevname(bh->b_dev), bh->b_blocknr);
- raid1_reschedule_retry (bh);
- restore_flags(flags);
+ partition_name(bh->b_dev), bh->b_blocknr);
+ raid1_reschedule_retry(bh);
return;
}
/*
- * WRITE.
- */
- PRINTK(("raid1_end_request(), write branch.\n"));
-
- /*
+ * WRITE:
+ *
* Let's see if all mirrored write operations have finished
- * already [we have irqs off, so we can decrease]:
+ * already.
*/
- if (!--r1_bh->remaining) {
- struct md_dev *mddev = r1_bh->mddev;
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
- int i, n = raid_conf->raid_disks;
-
- PRINTK(("raid1_end_request(), remaining == 0.\n"));
+ if (atomic_dec_and_test(&r1_bh->remaining)) {
+ int i, disks = MD_SB_DISKS;
- for ( i=0; i<n; i++)
- if (r1_bh->mirror_bh[i]) kfree(r1_bh->mirror_bh[i]);
+ for ( i = 0; i < disks; i++) {
+ struct buffer_head *bh = r1_bh->mirror_bh[i];
+ if (bh) {
+ // FIXME: make us a regular bcache member
+ kfree(bh);
+ }
+ }
- raid1_end_buffer_io(r1_bh, test_bit(BH_Uptodate, &r1_bh->state));
+ raid1_end_bh_io(r1_bh, test_bit(R1BH_Uptodate, &r1_bh->state));
}
- else PRINTK(("raid1_end_request(), remaining == %u.\n", r1_bh->remaining));
- restore_flags(flags);
}
-/* This routine checks if the undelying device is an md device and in that
- * case it maps the blocks before putting the request on the queue
- */
-static inline void
-map_and_make_request (int rw, struct buffer_head *bh)
-{
- if (MAJOR (bh->b_rdev) == MD_MAJOR)
- md_map (MINOR (bh->b_rdev), &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9);
- clear_bit(BH_Lock, &bh->b_state);
- make_request (MAJOR (bh->b_rdev), rw, bh);
-}
-
-static int
-raid1_make_request (struct md_dev *mddev, int rw, struct buffer_head * bh)
+static int raid1_make_request (request_queue_t *q, mddev_t *mddev, int rw,
+ struct buffer_head * bh)
{
-
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
struct buffer_head *mirror_bh[MD_SB_DISKS], *bh_req;
struct raid1_bh * r1_bh;
- int n = raid_conf->raid_disks, i, sum_bhs = 0, switch_disks = 0, sectors;
+ int disks = MD_SB_DISKS;
+ int i, sum_bhs = 0, switch_disks = 0, sectors;
struct mirror_info *mirror;
+ DECLARE_WAITQUEUE(wait, current);
- PRINTK(("raid1_make_request().\n"));
-
- while (!( /* FIXME: now we are rather fault tolerant than nice */
- r1_bh = kmalloc (sizeof (struct raid1_bh), GFP_KERNEL)
- ) )
- {
- printk ("raid1_make_request(#1): out of memory\n");
- current->policy |= SCHED_YIELD;
- schedule();
- }
- memset (r1_bh, 0, sizeof (struct raid1_bh));
-
+ if (!buffer_locked(bh))
+ BUG();
+
/*
* make_request() can abort the operation when READA is being
* used and no empty request is available.
*
* Currently, just replace the command with READ/WRITE.
*/
- if (rw == READA) rw = READ;
+ if (rw == READA)
+ rw = READ;
- if (rw == WRITE)
- mark_buffer_clean(bh); /* Too early ? */
+ if (rw == WRITE) {
+ rw = WRITERAW;
+ /*
+ * we first clean the bh, then we start the IO, then
+ * when the IO has finished, we end_io the bh and
+ * mark it uptodate. This way we do not miss the
+ * case when the bh got dirty again during the IO.
+ *
+ * We do an important optimization here - if the
+ * buffer was not dirty and we are during resync or
+ * reconstruction, then we can skip writing it back
+ * to the master disk! (we still have to write it
+ * back to the other disks, because we are not sync
+ * yet.)
+ */
+ if (atomic_set_buffer_clean(bh))
+ __mark_buffer_clean(bh);
+ else {
+ bh->b_end_io(bh, test_bit(BH_Uptodate, &bh->b_state));
+ return 0;
+ }
+ }
+ r1_bh = raid1_kmalloc (sizeof (struct raid1_bh));
-/*
- * i think the read and write branch should be separated completely, since we want
- * to do read balancing on the read side for example. Comments? :) --mingo
- */
- r1_bh->master_bh=bh;
- r1_bh->mddev=mddev;
+ spin_lock_irq(&conf->segment_lock);
+ wait_event_lock_irq(conf->wait_done,
+ bh->b_rsector < conf->start_active ||
+ bh->b_rsector >= conf->start_future,
+ conf->segment_lock);
+ if (bh->b_rsector < conf->start_active)
+ conf->cnt_done++;
+ else {
+ conf->cnt_future++;
+ if (conf->phase)
+ set_bit(R1BH_SyncPhase, &r1_bh->state);
+ }
+ spin_unlock_irq(&conf->segment_lock);
+
+ /*
+ * i think the read and write branch should be separated completely,
+ * since we want to do read balancing on the read side for example.
+ * Alternative implementations? :) --mingo
+ */
+
+ r1_bh->master_bh = bh;
+ r1_bh->mddev = mddev;
r1_bh->cmd = rw;
+ bh->b_rsector = bh->b_blocknr * (bh->b_size>>9);
+
+ if (rw == READ) {
+ int last_used = conf->last_used;
- if (rw==READ || rw==READA) {
- int last_used = raid_conf->last_used;
- PRINTK(("raid1_make_request(), read branch.\n"));
- mirror = raid_conf->mirrors + last_used;
+ /*
+ * read balancing logic:
+ */
+ mirror = conf->mirrors + last_used;
bh->b_rdev = mirror->dev;
sectors = bh->b_size >> 9;
- if (bh->b_blocknr * sectors == raid_conf->next_sect) {
- raid_conf->sect_count += sectors;
- if (raid_conf->sect_count >= mirror->sect_limit)
+
+ switch_disks = 0;
+ if (bh->b_blocknr * sectors == conf->next_sect) {
+ conf->sect_count += sectors;
+ if (conf->sect_count >= mirror->sect_limit)
switch_disks = 1;
} else
switch_disks = 1;
- raid_conf->next_sect = (bh->b_blocknr + 1) * sectors;
- if (switch_disks) {
- PRINTK(("read-balancing: switching %d -> %d (%d sectors)\n", last_used, mirror->next, raid_conf->sect_count));
- raid_conf->sect_count = 0;
- last_used = raid_conf->last_used = mirror->next;
+ conf->next_sect = (bh->b_blocknr + 1) * sectors;
+ /*
+ * Do not switch disks if full resync is in progress ...
+ */
+ if (switch_disks && !conf->resync_mirrors) {
+ conf->sect_count = 0;
+ last_used = conf->last_used = mirror->next;
/*
- * Do not switch to write-only disks ... resyncing
- * is in progress
+ * Do not switch to write-only disks ...
+ * reconstruction is in progress
*/
- while (raid_conf->mirrors[last_used].write_only)
- raid_conf->last_used = raid_conf->mirrors[last_used].next;
+ while (conf->mirrors[last_used].write_only)
+ conf->last_used = conf->mirrors[last_used].next;
}
- PRINTK (("raid1 read queue: %d %d\n", MAJOR (bh->b_rdev), MINOR (bh->b_rdev)));
bh_req = &r1_bh->bh_req;
memcpy(bh_req, bh, sizeof(*bh));
bh_req->b_end_io = raid1_end_request;
bh_req->b_dev_id = r1_bh;
- map_and_make_request (rw, bh_req);
+ q = blk_get_queue(bh_req->b_rdev);
+ generic_make_request (q, rw, bh_req);
return 0;
}
/*
- * WRITE.
+ * WRITE:
*/
- PRINTK(("raid1_make_request(n=%d), write branch.\n",n));
- for (i = 0; i < n; i++) {
+ for (i = 0; i < disks; i++) {
- if (!raid_conf->mirrors [i].operational) {
+ if (!conf->mirrors[i].operational) {
/*
* the r1_bh->mirror_bh[i] pointer remains NULL
*/
mirror_bh[i] = NULL;
continue;
}
-
+
/*
* We should use a private pool (size depending on NR_REQUEST),
* to avoid writes filling up the memory with bhs
*
- * Such pools are much faster than kmalloc anyways (so we waste almost
- * nothing by not using the master bh when writing and win alot of cleanness)
- *
- * but for now we are cool enough. --mingo
- *
+ * Such pools are much faster than kmalloc anyways (so we waste
+ * almost nothing by not using the master bh when writing and
+ * win alot of cleanness) but for now we are cool enough. --mingo
+ *
* It's safe to sleep here, buffer heads cannot be used in a shared
- * manner in the write branch. Look how we lock the buffer at the beginning
- * of this function to grok the difference ;)
+ * manner in the write branch. Look how we lock the buffer at the
+ * beginning of this function to grok the difference ;)
*/
- while (!( /* FIXME: now we are rather fault tolerant than nice */
- mirror_bh[i] = kmalloc (sizeof (struct buffer_head), GFP_KERNEL)
- ) )
- {
- printk ("raid1_make_request(#2): out of memory\n");
- current->policy |= SCHED_YIELD;
- schedule();
- }
- memset (mirror_bh[i], 0, sizeof (struct buffer_head));
-
- /*
- * prepare mirrored bh (fields ordered for max mem throughput):
- */
- mirror_bh [i]->b_blocknr = bh->b_blocknr;
- mirror_bh [i]->b_dev = bh->b_dev;
- mirror_bh [i]->b_rdev = raid_conf->mirrors [i].dev;
- mirror_bh [i]->b_rsector = bh->b_rsector;
- mirror_bh [i]->b_state = (1<<BH_Req) | (1<<BH_Dirty);
- atomic_set(&mirror_bh [i]->b_count, 1);
- mirror_bh [i]->b_size = bh->b_size;
- mirror_bh [i]->b_data = bh->b_data;
- mirror_bh [i]->b_list = BUF_LOCKED;
- mirror_bh [i]->b_end_io = raid1_end_request;
- mirror_bh [i]->b_dev_id = r1_bh;
-
- r1_bh->mirror_bh[i] = mirror_bh[i];
+ mirror_bh[i] = raid1_kmalloc(sizeof(struct buffer_head));
+ mirror_bh[i]->b_this_page = (struct buffer_head *)1;
+
+ /*
+ * prepare mirrored bh (fields ordered for max mem throughput):
+ */
+ mirror_bh[i]->b_blocknr = bh->b_blocknr;
+ mirror_bh[i]->b_dev = bh->b_dev;
+ mirror_bh[i]->b_rdev = conf->mirrors[i].dev;
+ mirror_bh[i]->b_rsector = bh->b_rsector;
+ mirror_bh[i]->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
+ (1<<BH_Mapped) | (1<<BH_Lock);
+
+ atomic_set(&mirror_bh[i]->b_count, 1);
+ mirror_bh[i]->b_size = bh->b_size;
+ mirror_bh[i]->b_data = bh->b_data;
+ mirror_bh[i]->b_list = BUF_LOCKED;
+ mirror_bh[i]->b_end_io = raid1_end_request;
+ mirror_bh[i]->b_dev_id = r1_bh;
+
+ r1_bh->mirror_bh[i] = mirror_bh[i];
sum_bhs++;
}
- r1_bh->remaining = sum_bhs;
-
- PRINTK(("raid1_make_request(), write branch, sum_bhs=%d.\n",sum_bhs));
+ md_atomic_set(&r1_bh->remaining, sum_bhs);
/*
- * We have to be a bit careful about the semaphore above, thats why we
- * start the requests separately. Since kmalloc() could fail, sleep and
- * make_request() can sleep too, this is the safer solution. Imagine,
- * end_request decreasing the semaphore before we could have set it up ...
- * We could play tricks with the semaphore (presetting it and correcting
- * at the end if sum_bhs is not 'n' but we have to do end_request by hand
- * if all requests finish until we had a chance to set up the semaphore
- * correctly ... lots of races).
+ * We have to be a bit careful about the semaphore above, thats
+ * why we start the requests separately. Since kmalloc() could
+ * fail, sleep and make_request() can sleep too, this is the
+ * safer solution. Imagine, end_request decreasing the semaphore
+ * before we could have set it up ... We could play tricks with
+ * the semaphore (presetting it and correcting at the end if
+ * sum_bhs is not 'n' but we have to do end_request by hand if
+ * all requests finish until we had a chance to set up the
+ * semaphore correctly ... lots of races).
*/
- for (i = 0; i < n; i++)
- if (mirror_bh [i] != NULL)
- map_and_make_request (rw, mirror_bh [i]);
-
+ for (i = 0; i < disks; i++) {
+ struct buffer_head *mbh = mirror_bh[i];
+ if (mbh) {
+ q = blk_get_queue(mbh->b_rdev);
+ generic_make_request(q, rw, mbh);
+ }
+ }
return (0);
}
-
-static int raid1_status (char *page, int minor, struct md_dev *mddev)
+
+static int raid1_status (char *page, mddev_t *mddev)
{
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
int sz = 0, i;
- sz += sprintf (page+sz, " [%d/%d] [", raid_conf->raid_disks, raid_conf->working_disks);
- for (i = 0; i < raid_conf->raid_disks; i++)
- sz += sprintf (page+sz, "%s", raid_conf->mirrors [i].operational ? "U" : "_");
+ sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks,
+ conf->working_disks);
+ for (i = 0; i < conf->raid_disks; i++)
+ sz += sprintf (page+sz, "%s",
+ conf->mirrors[i].operational ? "U" : "_");
sz += sprintf (page+sz, "]");
return sz;
}
-static void raid1_fix_links (struct raid1_data *raid_conf, int failed_index)
+static void unlink_disk (raid1_conf_t *conf, int target)
{
- int disks = raid_conf->raid_disks;
- int j;
+ int disks = MD_SB_DISKS;
+ int i;
- for (j = 0; j < disks; j++)
- if (raid_conf->mirrors [j].next == failed_index)
- raid_conf->mirrors [j].next = raid_conf->mirrors [failed_index].next;
+ for (i = 0; i < disks; i++)
+ if (conf->mirrors[i].next == target)
+ conf->mirrors[i].next = conf->mirrors[target].next;
}
#define LAST_DISK KERN_ALERT \
@@ -379,7 +452,7 @@ static void raid1_fix_links (struct raid1_data *raid_conf, int failed_index)
#define DISK_FAILED KERN_ALERT \
"raid1: Disk failure on %s, disabling device. \n" \
-" Operation continuing on %d devices\n"
+" Operation continuing on %d devices\n"
#define START_SYNCING KERN_ALERT \
"raid1: start syncing spare disk.\n"
@@ -387,48 +460,53 @@ static void raid1_fix_links (struct raid1_data *raid_conf, int failed_index)
#define ALREADY_SYNCING KERN_INFO \
"raid1: syncing already in progress.\n"
-static int raid1_error (struct md_dev *mddev, kdev_t dev)
+static void mark_disk_bad (mddev_t *mddev, int failed)
{
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
- struct mirror_info *mirror;
- md_superblock_t *sb = mddev->sb;
- int disks = raid_conf->raid_disks;
- int i;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ struct mirror_info *mirror = conf->mirrors+failed;
+ mdp_super_t *sb = mddev->sb;
+
+ mirror->operational = 0;
+ unlink_disk(conf, failed);
+ mark_disk_faulty(sb->disks+mirror->number);
+ mark_disk_nonsync(sb->disks+mirror->number);
+ mark_disk_inactive(sb->disks+mirror->number);
+ sb->active_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+ mddev->sb_dirty = 1;
+ md_wakeup_thread(conf->thread);
+ conf->working_disks--;
+ printk (DISK_FAILED, partition_name (mirror->dev),
+ conf->working_disks);
+}
- PRINTK(("raid1_error called\n"));
+static int raid1_error (mddev_t *mddev, kdev_t dev)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ struct mirror_info * mirrors = conf->mirrors;
+ int disks = MD_SB_DISKS;
+ int i;
- if (raid_conf->working_disks == 1) {
+ if (conf->working_disks == 1) {
/*
* Uh oh, we can do nothing if this is our last disk, but
* first check if this is a queued request for a device
* which has just failed.
*/
- for (i = 0, mirror = raid_conf->mirrors; i < disks;
- i++, mirror++)
- if (mirror->dev == dev && !mirror->operational)
+ for (i = 0; i < disks; i++) {
+ if (mirrors[i].dev==dev && !mirrors[i].operational)
return 0;
+ }
printk (LAST_DISK);
} else {
- /* Mark disk as unusable */
- for (i = 0, mirror = raid_conf->mirrors; i < disks;
- i++, mirror++) {
- if (mirror->dev == dev && mirror->operational){
- mirror->operational = 0;
- raid1_fix_links (raid_conf, i);
- sb->disks[mirror->number].state |=
- (1 << MD_FAULTY_DEVICE);
- sb->disks[mirror->number].state &=
- ~(1 << MD_SYNC_DEVICE);
- sb->disks[mirror->number].state &=
- ~(1 << MD_ACTIVE_DEVICE);
- sb->active_disks--;
- sb->working_disks--;
- sb->failed_disks++;
- mddev->sb_dirty = 1;
- md_wakeup_thread(raid1_thread);
- raid_conf->working_disks--;
- printk (DISK_FAILED, kdevname (dev),
- raid_conf->working_disks);
+ /*
+ * Mark disk as unusable
+ */
+ for (i = 0; i < disks; i++) {
+ if (mirrors[i].dev==dev && mirrors[i].operational) {
+ mark_disk_bad(mddev, i);
+ break;
}
}
}
@@ -441,219 +519,658 @@ static int raid1_error (struct md_dev *mddev, kdev_t dev)
#undef START_SYNCING
/*
- * This is the personality-specific hot-addition routine
+ * Insert the spare disk into the drive-ring
*/
+static void link_disk(raid1_conf_t *conf, struct mirror_info *mirror)
+{
+ int j, next;
+ int disks = MD_SB_DISKS;
+ struct mirror_info *p = conf->mirrors;
-#define NO_SUPERBLOCK KERN_ERR \
-"raid1: cannot hot-add disk to the array with no RAID superblock\n"
-
-#define WRONG_LEVEL KERN_ERR \
-"raid1: hot-add: level of disk is not RAID-1\n"
+ for (j = 0; j < disks; j++, p++)
+ if (p->operational && !p->write_only) {
+ next = p->next;
+ p->next = mirror->raid_disk;
+ mirror->next = next;
+ return;
+ }
-#define HOT_ADD_SUCCEEDED KERN_INFO \
-"raid1: device %s hot-added\n"
+ printk("raid1: bug: no read-operational devices\n");
+}
-static int raid1_hot_add_disk (struct md_dev *mddev, kdev_t dev)
+static void print_raid1_conf (raid1_conf_t *conf)
{
- unsigned long flags;
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
- struct mirror_info *mirror;
- md_superblock_t *sb = mddev->sb;
- struct real_dev * realdev;
- int n;
+ int i;
+ struct mirror_info *tmp;
+
+ printk("RAID1 conf printout:\n");
+ if (!conf) {
+ printk("(conf==NULL)\n");
+ return;
+ }
+ printk(" --- wd:%d rd:%d nd:%d\n", conf->working_disks,
+ conf->raid_disks, conf->nr_disks);
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n",
+ i, tmp->spare,tmp->operational,
+ tmp->number,tmp->raid_disk,tmp->used_slot,
+ partition_name(tmp->dev));
+ }
+}
+static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
+{
+ int err = 0;
+ int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;
+ raid1_conf_t *conf = mddev->private;
+ struct mirror_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+
+ print_raid1_conf(conf);
+ md_spin_lock_irq(&conf->device_lock);
/*
- * The device has its superblock already read and it was found
- * to be consistent for generic RAID usage. Now we check whether
- * it's usable for RAID-1 hot addition.
+ * find the disk ...
*/
+ switch (state) {
- n = mddev->nb_dev++;
- realdev = &mddev->devices[n];
- if (!realdev->sb) {
- printk (NO_SUPERBLOCK);
- return -EINVAL;
- }
- if (realdev->sb->level != 1) {
- printk (WRONG_LEVEL);
- return -EINVAL;
+ case DISKOP_SPARE_ACTIVE:
+
+ /*
+ * Find the failed disk within the RAID1 configuration ...
+ * (this can only be in the first conf->working_disks part)
+ */
+ for (i = 0; i < conf->raid_disks; i++) {
+ tmp = conf->mirrors + i;
+ if ((!tmp->operational && !tmp->spare) ||
+ !tmp->used_slot) {
+ failed_disk = i;
+ break;
+ }
+ }
+ /*
+ * When we activate a spare disk we _must_ have a disk in
+ * the lower (active) part of the array to replace.
+ */
+ if ((failed_disk == -1) || (failed_disk >= conf->raid_disks)) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ /* fall through */
+
+ case DISKOP_SPARE_WRITE:
+ case DISKOP_SPARE_INACTIVE:
+
+ /*
+ * Find the spare disk ... (can only be in the 'high'
+ * area of the array)
+ */
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ if (tmp->spare && tmp->number == (*d)->number) {
+ spare_disk = i;
+ break;
+ }
+ }
+ if (spare_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ if (tmp->used_slot && (tmp->number == (*d)->number)) {
+ if (tmp->operational) {
+ err = -EBUSY;
+ goto abort;
+ }
+ removed_disk = i;
+ break;
+ }
+ }
+ if (removed_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->mirrors + i;
+ if (!tmp->used_slot) {
+ added_disk = i;
+ break;
+ }
+ }
+ if (added_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
}
- /* FIXME: are there other things left we could sanity-check? */
+ switch (state) {
+ /*
+ * Switch the spare disk to write-only mode:
+ */
+ case DISKOP_SPARE_WRITE:
+ sdisk = conf->mirrors + spare_disk;
+ sdisk->operational = 1;
+ sdisk->write_only = 1;
+ break;
/*
- * We have to disable interrupts, as our RAID-1 state is used
- * from irq handlers as well.
+ * Deactivate a spare disk:
*/
- save_flags(flags);
- cli();
+ case DISKOP_SPARE_INACTIVE:
+ sdisk = conf->mirrors + spare_disk;
+ sdisk->operational = 0;
+ sdisk->write_only = 0;
+ break;
+ /*
+ * Activate (mark read-write) the (now sync) spare disk,
+ * which means we switch it's 'raid position' (->raid_disk)
+ * with the failed disk. (only the first 'conf->nr_disks'
+ * slots are used for 'real' disks and we must preserve this
+ * property)
+ */
+ case DISKOP_SPARE_ACTIVE:
- raid_conf->raid_disks++;
- mirror = raid_conf->mirrors+n;
+ sdisk = conf->mirrors + spare_disk;
+ fdisk = conf->mirrors + failed_disk;
- mirror->number=n;
- mirror->raid_disk=n;
- mirror->dev=dev;
- mirror->next=0; /* FIXME */
- mirror->sect_limit=128;
+ spare_desc = &sb->disks[sdisk->number];
+ failed_desc = &sb->disks[fdisk->number];
- mirror->operational=0;
- mirror->spare=1;
- mirror->write_only=0;
+ if (spare_desc != *d) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
- sb->disks[n].state |= (1 << MD_FAULTY_DEVICE);
- sb->disks[n].state &= ~(1 << MD_SYNC_DEVICE);
- sb->disks[n].state &= ~(1 << MD_ACTIVE_DEVICE);
- sb->nr_disks++;
- sb->spare_disks++;
+ if (spare_desc->raid_disk != sdisk->raid_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (sdisk->raid_disk != spare_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
- restore_flags(flags);
+ if (failed_desc->raid_disk != fdisk->raid_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
- md_update_sb(MINOR(dev));
+ if (fdisk->raid_disk != failed_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
- printk (HOT_ADD_SUCCEEDED, kdevname(realdev->dev));
+ /*
+ * do the switch finally
+ */
+ xchg_values(*spare_desc, *failed_desc);
+ xchg_values(*fdisk, *sdisk);
- return 0;
-}
+ /*
+ * (careful, 'failed' and 'spare' are switched from now on)
+ *
+ * we want to preserve linear numbering and we want to
+ * give the proper raid_disk number to the now activated
+ * disk. (this means we switch back these values)
+ */
+
+ xchg_values(spare_desc->raid_disk, failed_desc->raid_disk);
+ xchg_values(sdisk->raid_disk, fdisk->raid_disk);
+ xchg_values(spare_desc->number, failed_desc->number);
+ xchg_values(sdisk->number, fdisk->number);
-#undef NO_SUPERBLOCK
-#undef WRONG_LEVEL
-#undef HOT_ADD_SUCCEEDED
+ *d = failed_desc;
-/*
- * Insert the spare disk into the drive-ring
- */
-static void add_ring(struct raid1_data *raid_conf, struct mirror_info *mirror)
-{
- int j, next;
- struct mirror_info *p = raid_conf->mirrors;
+ if (sdisk->dev == MKDEV(0,0))
+ sdisk->used_slot = 0;
+ /*
+ * this really activates the spare.
+ */
+ fdisk->spare = 0;
+ fdisk->write_only = 0;
+ link_disk(conf, fdisk);
- for (j = 0; j < raid_conf->raid_disks; j++, p++)
- if (p->operational && !p->write_only) {
- next = p->next;
- p->next = mirror->raid_disk;
- mirror->next = next;
- return;
+ /*
+ * if we activate a spare, we definitely replace a
+ * non-operational disk slot in the 'low' area of
+ * the disk array.
+ */
+
+ conf->working_disks++;
+
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+ rdisk = conf->mirrors + removed_disk;
+
+ if (rdisk->spare && (removed_disk < conf->raid_disks)) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ rdisk->dev = MKDEV(0,0);
+ rdisk->used_slot = 0;
+ conf->nr_disks--;
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+ adisk = conf->mirrors + added_disk;
+ added_desc = *d;
+
+ if (added_disk != added_desc->number) {
+ MD_BUG();
+ err = 1;
+ goto abort;
}
- printk("raid1: bug: no read-operational devices\n");
-}
-static int raid1_mark_spare(struct md_dev *mddev, md_descriptor_t *spare,
- int state)
-{
- int i = 0, failed_disk = -1;
- struct raid1_data *raid_conf = mddev->private;
- struct mirror_info *mirror = raid_conf->mirrors;
- md_descriptor_t *descriptor;
- unsigned long flags;
+ adisk->number = added_desc->number;
+ adisk->raid_disk = added_desc->raid_disk;
+ adisk->dev = MKDEV(added_desc->major,added_desc->minor);
- for (i = 0; i < MD_SB_DISKS; i++, mirror++) {
- if (mirror->spare && mirror->number == spare->number)
- goto found;
- }
- return 1;
-found:
- for (i = 0, mirror = raid_conf->mirrors; i < raid_conf->raid_disks;
- i++, mirror++)
- if (!mirror->operational)
- failed_disk = i;
+ adisk->operational = 0;
+ adisk->write_only = 0;
+ adisk->spare = 1;
+ adisk->used_slot = 1;
+ conf->nr_disks++;
- save_flags(flags);
- cli();
- switch (state) {
- case SPARE_WRITE:
- mirror->operational = 1;
- mirror->write_only = 1;
- raid_conf->raid_disks = MAX(raid_conf->raid_disks,
- mirror->raid_disk + 1);
- break;
- case SPARE_INACTIVE:
- mirror->operational = 0;
- mirror->write_only = 0;
- break;
- case SPARE_ACTIVE:
- mirror->spare = 0;
- mirror->write_only = 0;
- raid_conf->working_disks++;
- add_ring(raid_conf, mirror);
-
- if (failed_disk != -1) {
- descriptor = &mddev->sb->disks[raid_conf->mirrors[failed_disk].number];
- i = spare->raid_disk;
- spare->raid_disk = descriptor->raid_disk;
- descriptor->raid_disk = i;
- }
- break;
- default:
- printk("raid1_mark_spare: bug: state == %d\n", state);
- restore_flags(flags);
- return 1;
+ break;
+
+ default:
+ MD_BUG();
+ err = 1;
+ goto abort;
}
- restore_flags(flags);
- return 0;
+abort:
+ md_spin_unlock_irq(&conf->device_lock);
+ print_raid1_conf(conf);
+ return err;
}
+
+#define IO_ERROR KERN_ALERT \
+"raid1: %s: unrecoverable I/O read error for block %lu\n"
+
+#define REDIRECT_SECTOR KERN_ERR \
+"raid1: %s: redirecting sector %lu to another mirror\n"
+
/*
* This is a kernel thread which:
*
* 1. Retries failed read operations on working mirrors.
* 2. Updates the raid superblock when problems encounter.
+ * 3. Performs writes following reads for array syncronising.
*/
-void raid1d (void *data)
+static void end_sync_write(struct buffer_head *bh, int uptodate);
+static void end_sync_read(struct buffer_head *bh, int uptodate);
+
+static void raid1d (void *data)
{
+ struct raid1_bh *r1_bh;
struct buffer_head *bh;
- kdev_t dev;
unsigned long flags;
- struct raid1_bh * r1_bh;
- struct md_dev *mddev;
+ request_queue_t *q;
+ mddev_t *mddev;
+ kdev_t dev;
- PRINTK(("raid1d() active\n"));
- save_flags(flags);
- cli();
- while (raid1_retry_list) {
+
+ for (;;) {
+ md_spin_lock_irqsave(&retry_list_lock, flags);
bh = raid1_retry_list;
+ if (!bh)
+ break;
r1_bh = (struct raid1_bh *)(bh->b_dev_id);
raid1_retry_list = r1_bh->next_retry;
- restore_flags(flags);
+ md_spin_unlock_irqrestore(&retry_list_lock, flags);
- mddev = md_dev + MINOR(bh->b_dev);
+ mddev = kdev_to_mddev(bh->b_dev);
if (mddev->sb_dirty) {
- printk("dirty sb detected, updating.\n");
+ printk(KERN_INFO "dirty sb detected, updating.\n");
mddev->sb_dirty = 0;
- md_update_sb(MINOR(bh->b_dev));
- }
- dev = bh->b_rdev;
- __raid1_map (md_dev + MINOR(bh->b_dev), &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9);
- if (bh->b_rdev == dev) {
- printk (KERN_ALERT
- "raid1: %s: unrecoverable I/O read error for block %lu\n",
- kdevname(bh->b_dev), bh->b_blocknr);
- raid1_end_buffer_io(r1_bh, 0);
- } else {
- printk (KERN_ERR "raid1: %s: redirecting sector %lu to another mirror\n",
- kdevname(bh->b_dev), bh->b_blocknr);
- map_and_make_request (r1_bh->cmd, bh);
+ md_update_sb(mddev);
}
- cli();
+ switch(r1_bh->cmd) {
+ case SPECIAL:
+ /* have to allocate lots of bh structures and
+ * schedule writes
+ */
+ if (test_bit(R1BH_Uptodate, &r1_bh->state)) {
+ int i, sum_bhs = 0;
+ int disks = MD_SB_DISKS;
+ struct buffer_head *mirror_bh[MD_SB_DISKS];
+ raid1_conf_t *conf;
+
+ conf = mddev_to_conf(mddev);
+ for (i = 0; i < disks ; i++) {
+ if (!conf->mirrors[i].operational) {
+ mirror_bh[i] = NULL;
+ continue;
+ }
+ if (i==conf->last_used) {
+ /* we read from here, no need to write */
+ mirror_bh[i] = NULL;
+ continue;
+ }
+ if (i < conf->raid_disks
+ && !conf->resync_mirrors) {
+ /* don't need to write this,
+ * we are just rebuilding */
+ mirror_bh[i] = NULL;
+ continue;
+ }
+
+ mirror_bh[i] = raid1_kmalloc(sizeof(struct buffer_head));
+ mirror_bh[i]->b_this_page = (struct buffer_head *)1;
+
+ /*
+ * prepare mirrored bh (fields ordered for max mem throughput):
+ */
+ mirror_bh[i]->b_blocknr = bh->b_blocknr;
+ mirror_bh[i]->b_dev = bh->b_dev;
+ mirror_bh[i]->b_rdev = conf->mirrors[i].dev;
+ mirror_bh[i]->b_rsector = bh->b_rsector;
+ mirror_bh[i]->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
+ (1<<BH_Mapped) | (1<<BH_Lock);
+
+ atomic_set(&mirror_bh[i]->b_count, 1);
+ mirror_bh[i]->b_size = bh->b_size;
+ mirror_bh[i]->b_data = bh->b_data;
+ mirror_bh[i]->b_list = BUF_LOCKED;
+ mirror_bh[i]->b_end_io = end_sync_write;
+ mirror_bh[i]->b_dev_id = r1_bh;
+
+ r1_bh->mirror_bh[i] = mirror_bh[i];
+ sum_bhs++;
+ }
+ md_atomic_set(&r1_bh->remaining, sum_bhs);
+ for ( i = 0; i < disks ; i++) {
+ struct buffer_head *mbh = mirror_bh[i];
+ if (mbh) {
+ q = blk_get_queue(mbh->b_rdev);
+ generic_make_request(q, WRITE, mbh);
+ }
+ }
+ } else {
+ dev = bh->b_rdev;
+ raid1_map (mddev, &bh->b_rdev, bh->b_size >> 9);
+ if (bh->b_rdev == dev) {
+ printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
+ md_done_sync(mddev, bh->b_size>>10, 0);
+ } else {
+ printk (REDIRECT_SECTOR,
+ partition_name(bh->b_dev), bh->b_blocknr);
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request (q, READ, bh);
+ }
+ }
+
+ break;
+ case READ:
+ case READA:
+ dev = bh->b_rdev;
+
+ raid1_map (mddev, &bh->b_rdev, bh->b_size >> 9);
+ if (bh->b_rdev == dev) {
+ printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
+ raid1_end_bh_io(r1_bh, 0);
+ } else {
+ printk (REDIRECT_SECTOR,
+ partition_name(bh->b_dev), bh->b_blocknr);
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request (q, r1_bh->cmd, bh);
+ }
+ break;
+ }
+ }
+ md_spin_unlock_irqrestore(&retry_list_lock, flags);
+}
+#undef IO_ERROR
+#undef REDIRECT_SECTOR
+
+/*
+ * Private kernel thread to reconstruct mirrors after an unclean
+ * shutdown.
+ */
+static void raid1syncd (void *data)
+{
+ raid1_conf_t *conf = data;
+ mddev_t *mddev = conf->mddev;
+
+ if (!conf->resync_mirrors)
+ return;
+ if (conf->resync_mirrors == 2)
+ return;
+ down(&mddev->recovery_sem);
+ if (md_do_sync(mddev, NULL)) {
+ up(&mddev->recovery_sem);
+ return;
+ }
+ /*
+ * Only if everything went Ok.
+ */
+ conf->resync_mirrors = 0;
+ up(&mddev->recovery_sem);
+}
+
+/*
+ * perform a "sync" on one "block"
+ *
+ * We need to make sure that no normal I/O request - particularly write
+ * requests - conflict with active sync requests.
+ * This is achieved by conceptually dividing the device space into a
+ * number of sections:
+ * DONE: 0 .. a-1 These blocks are in-sync
+ * ACTIVE: a.. b-1 These blocks may have active sync requests, but
+ * no normal IO requests
+ * READY: b .. c-1 These blocks have no normal IO requests - sync
+ * request may be happening
+ * PENDING: c .. d-1 These blocks may have IO requests, but no new
+ * ones will be added
+ * FUTURE: d .. end These blocks are not to be considered yet. IO may
+ * be happening, but not sync
+ *
+ * We keep a
+ * phase which flips (0 or 1) each time d moves and
+ * a count of:
+ * z = active io requests in FUTURE since d moved - marked with
+ * current phase
+ * y = active io requests in FUTURE before d moved, or PENDING -
+ * marked with previous phase
+ * x = active sync requests in READY
+ * w = active sync requests in ACTIVE
+ * v = active io requests in DONE
+ *
+ * Normally, a=b=c=d=0 and z= active io requests
+ * or a=b=c=d=END and v= active io requests
+ * Allowed changes to a,b,c,d:
+ * A: c==d && y==0 -> d+=window, y=z, z=0, phase=!phase
+ * B: y==0 -> c=d
+ * C: b=c, w+=x, x=0
+ * D: w==0 -> a=b
+ * E: a==b==c==d==end -> a=b=c=d=0, z=v, v=0
+ *
+ * At start of sync we apply A.
+ * When y reaches 0, we apply B then A then being sync requests
+ * When sync point reaches c-1, we wait for y==0, and W==0, and
+ * then apply apply B then A then D then C.
+ * Finally, we apply E
+ *
+ * The sync request simply issues a "read" against a working drive
+ * This is marked so that on completion the raid1d thread is woken to
+ * issue suitable write requests
+ */
+
+static int raid1_sync_request (mddev_t *mddev, unsigned long block_nr)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ struct mirror_info *mirror;
+ request_queue_t *q;
+ struct raid1_bh *r1_bh;
+ struct buffer_head *bh;
+ int bsize;
+
+ spin_lock_irq(&conf->segment_lock);
+ if (!block_nr) {
+ /* initialize ...*/
+ conf->start_active = 0;
+ conf->start_ready = 0;
+ conf->start_pending = 0;
+ conf->start_future = 0;
+ conf->phase = 0;
+ conf->window = 128;
+ conf->cnt_future += conf->cnt_done+conf->cnt_pending;
+ conf->cnt_done = conf->cnt_pending = 0;
+ if (conf->cnt_ready || conf->cnt_active)
+ MD_BUG();
+ }
+ while ((block_nr<<1) >= conf->start_pending) {
+ PRINTK("wait .. sect=%lu start_active=%d ready=%d pending=%d future=%d, cnt_done=%d active=%d ready=%d pending=%d future=%d\n",
+ block_nr<<1, conf->start_active, conf->start_ready, conf->start_pending, conf->start_future,
+ conf->cnt_done, conf->cnt_active, conf->cnt_ready, conf->cnt_pending, conf->cnt_future);
+ wait_event_lock_irq(conf->wait_done,
+ !conf->cnt_active,
+ conf->segment_lock);
+ wait_event_lock_irq(conf->wait_ready,
+ !conf->cnt_pending,
+ conf->segment_lock);
+ conf->start_active = conf->start_ready;
+ conf->start_ready = conf->start_pending;
+ conf->start_pending = conf->start_future;
+ conf->start_future = conf->start_future+conf->window;
+ // Note: falling of the end is not a problem
+ conf->phase = conf->phase ^1;
+ conf->cnt_active = conf->cnt_ready;
+ conf->cnt_ready = 0;
+ conf->cnt_pending = conf->cnt_future;
+ conf->cnt_future = 0;
+ wake_up(&conf->wait_done);
+ }
+ conf->cnt_ready++;
+ spin_unlock_irq(&conf->segment_lock);
+
+
+ /* If reconstructing, and >1 working disc,
+ * could dedicate one to rebuild and others to
+ * service read requests ..
+ */
+ mirror = conf->mirrors+conf->last_used;
+
+ r1_bh = raid1_kmalloc (sizeof (struct raid1_bh));
+ r1_bh->master_bh = NULL;
+ r1_bh->mddev = mddev;
+ r1_bh->cmd = SPECIAL;
+ bh = &r1_bh->bh_req;
+ memset(bh, 0, sizeof(*bh));
+
+ bh->b_blocknr = block_nr;
+ bsize = 1024;
+ while (!(bh->b_blocknr & 1) && bsize < PAGE_SIZE
+ && (bh->b_blocknr+2)*(bsize>>10) < mddev->sb->size) {
+ bh->b_blocknr >>= 1;
+ bsize <<= 1;
+ }
+ bh->b_size = bsize;
+ bh->b_list = BUF_LOCKED;
+ bh->b_dev = mddev_to_kdev(mddev);
+ bh->b_rdev = mirror->dev;
+ bh->b_state = (1<<BH_Req) | (1<<BH_Mapped);
+ bh->b_page = raid1_gfp();
+ bh->b_data = (char *) page_address(bh->b_page);
+ bh->b_end_io = end_sync_read;
+ bh->b_dev_id = (void *) r1_bh;
+ bh->b_rsector = block_nr<<1;
+ init_waitqueue_head(&bh->b_wait);
+
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, READ, bh);
+ drive_stat_acct(bh->b_rdev, READ, -bh->b_size/512, 0);
+
+ return (bsize >> 10);
+}
+
+static void end_sync_read(struct buffer_head *bh, int uptodate)
+{
+ struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_dev_id);
+
+ /* we have read a block, now it needs to be re-written,
+ * or re-read if the read failed.
+ * We don't do much here, just schedule handling by raid1d
+ */
+ if (!uptodate)
+ md_error (bh->b_dev, bh->b_rdev);
+ else
+ set_bit(R1BH_Uptodate, &r1_bh->state);
+ raid1_reschedule_retry(bh);
+}
+
+static void end_sync_write(struct buffer_head *bh, int uptodate)
+{
+ struct raid1_bh * r1_bh = (struct raid1_bh *)(bh->b_dev_id);
+
+ if (!uptodate)
+ md_error (bh->b_dev, bh->b_rdev);
+ if (atomic_dec_and_test(&r1_bh->remaining)) {
+ int i, disks = MD_SB_DISKS;
+ mddev_t *mddev = r1_bh->mddev;
+ unsigned long sect = bh->b_rsector;
+ int size = bh->b_size;
+
+ free_page((unsigned long)bh->b_data);
+ for ( i = 0; i < disks; i++) {
+ struct buffer_head *bh = r1_bh->mirror_bh[i];
+ if (bh) {
+ // FIXME: make us a regular bcache member
+ kfree(bh);
+ }
+ }
+ kfree(r1_bh);
+ sync_request_done(sect, mddev_to_conf(mddev));
+ md_done_sync(mddev,size>>10, uptodate);
}
- restore_flags(flags);
}
/*
* This will catch the scenario in which one of the mirrors was
* mounted as a normal device rather than as a part of a raid set.
+ *
+ * check_consistency is very personality-dependent, eg. RAID5 cannot
+ * do this check, it uses another method.
*/
-static int __check_consistency (struct md_dev *mddev, int row)
+static int __check_consistency (mddev_t *mddev, int row)
{
- struct raid1_data *raid_conf = mddev->private;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+ int disks = MD_SB_DISKS;
kdev_t dev;
struct buffer_head *bh = NULL;
int i, rc = 0;
char *buffer = NULL;
- for (i = 0; i < raid_conf->raid_disks; i++) {
- if (!raid_conf->mirrors[i].operational)
+ for (i = 0; i < disks; i++) {
+ printk("(checking disk %d)\n",i);
+ if (!conf->mirrors[i].operational)
continue;
- dev = raid_conf->mirrors[i].dev;
+ printk("(really checking disk %d)\n",i);
+ dev = conf->mirrors[i].dev;
set_blocksize(dev, 4096);
if ((bh = bread(dev, row / 4, 4096)) == NULL)
break;
@@ -682,187 +1199,389 @@ static int __check_consistency (struct md_dev *mddev, int row)
return rc;
}
-static int check_consistency (struct md_dev *mddev)
+static int check_consistency (mddev_t *mddev)
{
- int size = mddev->sb->size;
- int row;
+ if (__check_consistency(mddev, 0))
+/*
+ * we do not do this currently, as it's perfectly possible to
+ * have an inconsistent array when it's freshly created. Only
+ * newly written data has to be consistent.
+ */
+ return 0;
- for (row = 0; row < size; row += size / 8)
- if (__check_consistency(mddev, row))
- return 1;
return 0;
}
-static int raid1_run (int minor, struct md_dev *mddev)
+#define INVALID_LEVEL KERN_WARNING \
+"raid1: md%d: raid level not set to mirroring (%d)\n"
+
+#define NO_SB KERN_ERR \
+"raid1: disabled mirror %s (couldn't access raid superblock)\n"
+
+#define ERRORS KERN_ERR \
+"raid1: disabled mirror %s (errors detected)\n"
+
+#define NOT_IN_SYNC KERN_ERR \
+"raid1: disabled mirror %s (not in sync)\n"
+
+#define INCONSISTENT KERN_ERR \
+"raid1: disabled mirror %s (inconsistent descriptor)\n"
+
+#define ALREADY_RUNNING KERN_ERR \
+"raid1: disabled mirror %s (mirror %d already operational)\n"
+
+#define OPERATIONAL KERN_INFO \
+"raid1: device %s operational as mirror %d\n"
+
+#define MEM_ERROR KERN_ERR \
+"raid1: couldn't allocate memory for md%d\n"
+
+#define SPARE KERN_INFO \
+"raid1: spare disk %s\n"
+
+#define NONE_OPERATIONAL KERN_ERR \
+"raid1: no operational mirrors for md%d\n"
+
+#define RUNNING_CKRAID KERN_ERR \
+"raid1: detected mirror differences -- running resync\n"
+
+#define ARRAY_IS_ACTIVE KERN_INFO \
+"raid1: raid set md%d active with %d out of %d mirrors\n"
+
+#define THREAD_ERROR KERN_ERR \
+"raid1: couldn't allocate thread for md%d\n"
+
+#define START_RESYNC KERN_WARNING \
+"raid1: raid set md%d not clean; reconstructing mirrors\n"
+
+static int raid1_run (mddev_t *mddev)
{
- struct raid1_data *raid_conf;
- int i, j, raid_disk;
- md_superblock_t *sb = mddev->sb;
- md_descriptor_t *descriptor;
- struct real_dev *realdev;
+ raid1_conf_t *conf;
+ int i, j, disk_idx;
+ struct mirror_info *disk;
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *descriptor;
+ mdk_rdev_t *rdev;
+ struct md_list_head *tmp;
+ int start_recovery = 0;
MOD_INC_USE_COUNT;
if (sb->level != 1) {
- printk("raid1: %s: raid level not set to mirroring (%d)\n",
- kdevname(MKDEV(MD_MAJOR, minor)), sb->level);
- MOD_DEC_USE_COUNT;
- return -EIO;
- }
- /****
- * copy the now verified devices into our private RAID1 bookkeeping
- * area. [whatever we allocate in raid1_run(), should be freed in
- * raid1_stop()]
+ printk(INVALID_LEVEL, mdidx(mddev), sb->level);
+ goto out;
+ }
+ /*
+ * copy the already verified devices into our private RAID1
+ * bookkeeping area. [whatever we allocate in raid1_run(),
+ * should be freed in raid1_stop()]
*/
- while (!( /* FIXME: now we are rather fault tolerant than nice */
- mddev->private = kmalloc (sizeof (struct raid1_data), GFP_KERNEL)
- ) )
- {
- printk ("raid1_run(): out of memory\n");
- current->policy |= SCHED_YIELD;
- schedule();
+ conf = raid1_kmalloc(sizeof(raid1_conf_t));
+ mddev->private = conf;
+ if (!conf) {
+ printk(MEM_ERROR, mdidx(mddev));
+ goto out;
}
- raid_conf = mddev->private;
- memset(raid_conf, 0, sizeof(*raid_conf));
- PRINTK(("raid1_run(%d) called.\n", minor));
-
- for (i = 0; i < mddev->nb_dev; i++) {
- realdev = &mddev->devices[i];
- if (!realdev->sb) {
- printk(KERN_ERR "raid1: disabled mirror %s (couldn't access raid superblock)\n", kdevname(realdev->dev));
+ ITERATE_RDEV(mddev,rdev,tmp) {
+ if (rdev->faulty) {
+ printk(ERRORS, partition_name(rdev->dev));
+ } else {
+ if (!rdev->sb) {
+ MD_BUG();
+ continue;
+ }
+ }
+ if (rdev->desc_nr == -1) {
+ MD_BUG();
continue;
}
-
- /*
- * This is important -- we are using the descriptor on
- * the disk only to get a pointer to the descriptor on
- * the main superblock, which might be more recent.
- */
- descriptor = &sb->disks[realdev->sb->descriptor.number];
- if (descriptor->state & (1 << MD_FAULTY_DEVICE)) {
- printk(KERN_ERR "raid1: disabled mirror %s (errors detected)\n", kdevname(realdev->dev));
+ descriptor = &sb->disks[rdev->desc_nr];
+ disk_idx = descriptor->raid_disk;
+ disk = conf->mirrors + disk_idx;
+
+ if (disk_faulty(descriptor)) {
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = rdev->dev;
+ disk->sect_limit = MAX_LINEAR_SECTORS;
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
continue;
}
- if (descriptor->state & (1 << MD_ACTIVE_DEVICE)) {
- if (!(descriptor->state & (1 << MD_SYNC_DEVICE))) {
- printk(KERN_ERR "raid1: disabled mirror %s (not in sync)\n", kdevname(realdev->dev));
+ if (disk_active(descriptor)) {
+ if (!disk_sync(descriptor)) {
+ printk(NOT_IN_SYNC,
+ partition_name(rdev->dev));
continue;
}
- raid_disk = descriptor->raid_disk;
- if (descriptor->number > sb->nr_disks || raid_disk > sb->raid_disks) {
- printk(KERN_ERR "raid1: disabled mirror %s (inconsistent descriptor)\n", kdevname(realdev->dev));
+ if ((descriptor->number > MD_SB_DISKS) ||
+ (disk_idx > sb->raid_disks)) {
+
+ printk(INCONSISTENT,
+ partition_name(rdev->dev));
continue;
}
- if (raid_conf->mirrors[raid_disk].operational) {
- printk(KERN_ERR "raid1: disabled mirror %s (mirror %d already operational)\n", kdevname(realdev->dev), raid_disk);
+ if (disk->operational) {
+ printk(ALREADY_RUNNING,
+ partition_name(rdev->dev),
+ disk_idx);
continue;
}
- printk(KERN_INFO "raid1: device %s operational as mirror %d\n", kdevname(realdev->dev), raid_disk);
- raid_conf->mirrors[raid_disk].number = descriptor->number;
- raid_conf->mirrors[raid_disk].raid_disk = raid_disk;
- raid_conf->mirrors[raid_disk].dev = mddev->devices [i].dev;
- raid_conf->mirrors[raid_disk].operational = 1;
- raid_conf->mirrors[raid_disk].sect_limit = 128;
- raid_conf->working_disks++;
+ printk(OPERATIONAL, partition_name(rdev->dev),
+ disk_idx);
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = rdev->dev;
+ disk->sect_limit = MAX_LINEAR_SECTORS;
+ disk->operational = 1;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ conf->working_disks++;
} else {
/*
* Must be a spare disk ..
*/
- printk(KERN_INFO "raid1: spare disk %s\n", kdevname(realdev->dev));
- raid_disk = descriptor->raid_disk;
- raid_conf->mirrors[raid_disk].number = descriptor->number;
- raid_conf->mirrors[raid_disk].raid_disk = raid_disk;
- raid_conf->mirrors[raid_disk].dev = mddev->devices [i].dev;
- raid_conf->mirrors[raid_disk].sect_limit = 128;
-
- raid_conf->mirrors[raid_disk].operational = 0;
- raid_conf->mirrors[raid_disk].write_only = 0;
- raid_conf->mirrors[raid_disk].spare = 1;
- }
- }
- if (!raid_conf->working_disks) {
- printk(KERN_ERR "raid1: no operational mirrors for %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
- kfree(raid_conf);
- mddev->private = NULL;
- MOD_DEC_USE_COUNT;
- return -EIO;
- }
-
- raid_conf->raid_disks = sb->raid_disks;
- raid_conf->mddev = mddev;
-
- for (j = 0; !raid_conf->mirrors[j].operational; j++);
- raid_conf->last_used = j;
- for (i = raid_conf->raid_disks - 1; i >= 0; i--) {
- if (raid_conf->mirrors[i].operational) {
- PRINTK(("raid_conf->mirrors[%d].next == %d\n", i, j));
- raid_conf->mirrors[i].next = j;
+ printk(SPARE, partition_name(rdev->dev));
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = rdev->dev;
+ disk->sect_limit = MAX_LINEAR_SECTORS;
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 1;
+ disk->used_slot = 1;
+ }
+ }
+ if (!conf->working_disks) {
+ printk(NONE_OPERATIONAL, mdidx(mddev));
+ goto out_free_conf;
+ }
+
+ conf->raid_disks = sb->raid_disks;
+ conf->nr_disks = sb->nr_disks;
+ conf->mddev = mddev;
+ conf->device_lock = MD_SPIN_LOCK_UNLOCKED;
+
+ conf->segment_lock = MD_SPIN_LOCK_UNLOCKED;
+ init_waitqueue_head(&conf->wait_done);
+ init_waitqueue_head(&conf->wait_ready);
+
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+
+ descriptor = sb->disks+i;
+ disk_idx = descriptor->raid_disk;
+ disk = conf->mirrors + disk_idx;
+
+ if (disk_faulty(descriptor) && (disk_idx < conf->raid_disks) &&
+ !disk->used_slot) {
+
+ disk->number = descriptor->number;
+ disk->raid_disk = disk_idx;
+ disk->dev = MKDEV(0,0);
+
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ }
+ }
+
+ /*
+ * find the first working one and use it as a starting point
+ * to read balancing.
+ */
+ for (j = 0; !conf->mirrors[j].operational; j++)
+ /* nothing */;
+ conf->last_used = j;
+
+ /*
+ * initialize the 'working disks' list.
+ */
+ for (i = conf->raid_disks - 1; i >= 0; i--) {
+ if (conf->mirrors[i].operational) {
+ conf->mirrors[i].next = j;
j = i;
}
}
- if (check_consistency(mddev)) {
- printk(KERN_ERR "raid1: detected mirror differences -- run ckraid\n");
- sb->state |= 1 << MD_SB_ERRORS;
- kfree(raid_conf);
- mddev->private = NULL;
- MOD_DEC_USE_COUNT;
- return -EIO;
+ if (conf->working_disks != sb->raid_disks) {
+ printk(KERN_ALERT "raid1: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));
+ start_recovery = 1;
+ }
+
+ if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN))) {
+ /*
+ * we do sanity checks even if the device says
+ * it's clean ...
+ */
+ if (check_consistency(mddev)) {
+ printk(RUNNING_CKRAID);
+ sb->state &= ~(1 << MD_SB_CLEAN);
+ }
+ }
+
+ {
+ const char * name = "raid1d";
+
+ conf->thread = md_register_thread(raid1d, conf, name);
+ if (!conf->thread) {
+ printk(THREAD_ERROR, mdidx(mddev));
+ goto out_free_conf;
+ }
+ }
+
+ if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
+ const char * name = "raid1syncd";
+
+ conf->resync_thread = md_register_thread(raid1syncd, conf,name);
+ if (!conf->resync_thread) {
+ printk(THREAD_ERROR, mdidx(mddev));
+ goto out_free_conf;
+ }
+
+ printk(START_RESYNC, mdidx(mddev));
+ conf->resync_mirrors = 1;
+ md_wakeup_thread(conf->resync_thread);
}
/*
* Regenerate the "device is in sync with the raid set" bit for
* each device.
*/
- for (i = 0; i < sb->nr_disks ; i++) {
- sb->disks[i].state &= ~(1 << MD_SYNC_DEVICE);
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ mark_disk_nonsync(sb->disks+i);
for (j = 0; j < sb->raid_disks; j++) {
- if (!raid_conf->mirrors[j].operational)
+ if (!conf->mirrors[j].operational)
continue;
- if (sb->disks[i].number == raid_conf->mirrors[j].number)
- sb->disks[i].state |= 1 << MD_SYNC_DEVICE;
+ if (sb->disks[i].number == conf->mirrors[j].number)
+ mark_disk_sync(sb->disks+i);
}
}
- sb->active_disks = raid_conf->working_disks;
+ sb->active_disks = conf->working_disks;
- printk("raid1: raid set %s active with %d out of %d mirrors\n", kdevname(MKDEV(MD_MAJOR, minor)), sb->active_disks, sb->raid_disks);
- /* Ok, everything is just fine now */
- return (0);
+ if (start_recovery)
+ md_recover_arrays();
+
+
+ printk(ARRAY_IS_ACTIVE, mdidx(mddev), sb->active_disks, sb->raid_disks);
+ /*
+ * Ok, everything is just fine now
+ */
+ return 0;
+
+out_free_conf:
+ kfree(conf);
+ mddev->private = NULL;
+out:
+ MOD_DEC_USE_COUNT;
+ return -EIO;
+}
+
+#undef INVALID_LEVEL
+#undef NO_SB
+#undef ERRORS
+#undef NOT_IN_SYNC
+#undef INCONSISTENT
+#undef ALREADY_RUNNING
+#undef OPERATIONAL
+#undef SPARE
+#undef NONE_OPERATIONAL
+#undef RUNNING_CKRAID
+#undef ARRAY_IS_ACTIVE
+
+static int raid1_stop_resync (mddev_t *mddev)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+
+ if (conf->resync_thread) {
+ if (conf->resync_mirrors) {
+ conf->resync_mirrors = 2;
+ md_interrupt_thread(conf->resync_thread);
+
+ /* this is really needed when recovery stops too... */
+ spin_lock_irq(&conf->segment_lock);
+ wait_event_lock_irq(conf->wait_done, !conf->cnt_active, conf->segment_lock);
+ conf->start_active = conf->start_ready;
+ conf->start_ready = conf->start_pending;
+ conf->cnt_active = conf->cnt_ready;
+ conf->cnt_ready = 0;
+ wait_event_lock_irq(conf->wait_done, !conf->cnt_active, conf->segment_lock);
+ conf->start_active = conf->start_ready;
+ conf->cnt_ready = 0;
+ wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
+ conf->start_active =conf->start_ready = conf->start_pending = conf->start_future;
+ conf->start_future = mddev->sb->size+1;
+ conf->cnt_pending = conf->cnt_future;
+ conf->cnt_future = 0;
+ conf->phase = conf->phase ^1;
+ wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
+ conf->start_active = conf->start_ready = conf->start_pending = conf->start_future = 0;
+ conf->phase = 0;
+ conf->cnt_done = conf->cnt_future;
+ conf->cnt_future = 0;
+ wake_up(&conf->wait_done);
+
+ printk(KERN_INFO "raid1: mirror resync was not fully finished, restarting next time.\n");
+ return 1;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+static int raid1_restart_resync (mddev_t *mddev)
+{
+ raid1_conf_t *conf = mddev_to_conf(mddev);
+
+ if (conf->resync_mirrors) {
+ if (!conf->resync_thread) {
+ MD_BUG();
+ return 0;
+ }
+ conf->resync_mirrors = 1;
+ md_wakeup_thread(conf->resync_thread);
+ return 1;
+ }
+ return 0;
}
-static int raid1_stop (int minor, struct md_dev *mddev)
+static int raid1_stop (mddev_t *mddev)
{
- struct raid1_data *raid_conf = (struct raid1_data *) mddev->private;
+ raid1_conf_t *conf = mddev_to_conf(mddev);
- kfree (raid_conf);
+ md_unregister_thread(conf->thread);
+ if (conf->resync_thread)
+ md_unregister_thread(conf->resync_thread);
+ kfree(conf);
mddev->private = NULL;
MOD_DEC_USE_COUNT;
return 0;
}
-static struct md_personality raid1_personality=
+static mdk_personality_t raid1_personality=
{
"raid1",
- raid1_map,
raid1_make_request,
raid1_end_request,
raid1_run,
raid1_stop,
raid1_status,
- NULL, /* no ioctls */
0,
raid1_error,
- raid1_hot_add_disk,
- /* raid1_hot_remove_drive */ NULL,
- raid1_mark_spare
+ raid1_diskop,
+ raid1_stop_resync,
+ raid1_restart_resync,
+ raid1_sync_request
};
int raid1_init (void)
{
- if ((raid1_thread = md_register_thread(raid1d, NULL)) == NULL)
- return -EBUSY;
return register_md_personality (RAID1, &raid1_personality);
}
@@ -874,7 +1593,6 @@ int init_module (void)
void cleanup_module (void)
{
- md_unregister_thread (raid1_thread);
unregister_md_personality (RAID1);
}
#endif
diff --git a/drivers/block/raid5.c b/drivers/block/raid5.c
index 83fc26fad..2379ac6a2 100644
--- a/drivers/block/raid5.c
+++ b/drivers/block/raid5.c
@@ -1,6 +1,7 @@
-/*****************************************************************************
+/*
* raid5.c : Multiple Devices driver for Linux
- * Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman
+ * Copyright (C) 1996, 1997 Ingo Molnar, Miguel de Icaza, Gadi Oxman
+ * Copyright (C) 1999, 2000 Ingo Molnar
*
* RAID-5 management functions.
*
@@ -14,130 +15,108 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
#include <linux/module.h>
#include <linux/locks.h>
#include <linux/malloc.h>
-#include <linux/md.h>
-#include <linux/raid5.h>
+#include <linux/raid/raid5.h>
#include <asm/bitops.h>
#include <asm/atomic.h>
-#include <asm/md.h>
-static struct md_personality raid5_personality;
+static mdk_personality_t raid5_personality;
/*
* Stripe cache
*/
+
#define NR_STRIPES 128
#define HASH_PAGES 1
#define HASH_PAGES_ORDER 0
#define NR_HASH (HASH_PAGES * PAGE_SIZE / sizeof(struct stripe_head *))
#define HASH_MASK (NR_HASH - 1)
-#define stripe_hash(raid_conf, sect, size) ((raid_conf)->stripe_hashtbl[((sect) / (size >> 9)) & HASH_MASK])
+#define stripe_hash(conf, sect, size) ((conf)->stripe_hashtbl[((sect) / (size >> 9)) & HASH_MASK])
/*
* The following can be used to debug the driver
*/
#define RAID5_DEBUG 0
+#define RAID5_PARANOIA 1
+#define CHECK_DEVLOCK() if (!spin_is_locked(&conf->device_lock)) BUG()
+#define CHECK_SHLOCK(sh) if (!stripe_locked(sh)) BUG()
#if RAID5_DEBUG
-#define PRINTK(x) do { printk x; } while (0);
+#define PRINTK(x...) printk(x)
+#define inline
+#define __inline__
#else
-#define PRINTK(x) do { ; } while (0)
+#define inline
+#define __inline__
+#define PRINTK(x...) do { } while (0)
#endif
+static void print_raid5_conf (raid5_conf_t *conf);
+
static inline int stripe_locked(struct stripe_head *sh)
{
return test_bit(STRIPE_LOCKED, &sh->state);
}
-static inline int stripe_error(struct stripe_head *sh)
-{
- return test_bit(STRIPE_ERROR, &sh->state);
-}
-
-/*
- * Stripes are locked whenever new buffers can't be added to them.
- */
-static inline void lock_stripe(struct stripe_head *sh)
+static void __unlock_stripe(struct stripe_head *sh)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- if (!test_and_set_bit(STRIPE_LOCKED, &sh->state)) {
- PRINTK(("locking stripe %lu\n", sh->sector));
- raid_conf->nr_locked_stripes++;
- }
+ if (!md_test_and_clear_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ PRINTK("unlocking stripe %lu\n", sh->sector);
+ wake_up(&sh->wait);
}
-static inline void unlock_stripe(struct stripe_head *sh)
+static void finish_unlock_stripe(struct stripe_head *sh)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- if (test_and_clear_bit(STRIPE_LOCKED, &sh->state)) {
- PRINTK(("unlocking stripe %lu\n", sh->sector));
- raid_conf->nr_locked_stripes--;
- wake_up(&sh->wait);
- }
-}
-
-static inline void finish_stripe(struct stripe_head *sh)
-{
- struct raid5_data *raid_conf = sh->raid_conf;
- unlock_stripe(sh);
+ raid5_conf_t *conf = sh->raid_conf;
sh->cmd = STRIPE_NONE;
sh->phase = PHASE_COMPLETE;
- raid_conf->nr_pending_stripes--;
- raid_conf->nr_cached_stripes++;
- wake_up(&raid_conf->wait_for_stripe);
-}
-
-void __wait_on_stripe(struct stripe_head *sh)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- PRINTK(("wait_on_stripe %lu\n", sh->sector));
- sh->count++;
- add_wait_queue(&sh->wait, &wait);
-repeat:
- set_current_state(TASK_UNINTERRUPTIBLE);
- if (stripe_locked(sh)) {
- schedule();
- goto repeat;
- }
- PRINTK(("wait_on_stripe %lu done\n", sh->sector));
- remove_wait_queue(&sh->wait, &wait);
- sh->count--;
- current->state = TASK_RUNNING;
-}
-
-static inline void wait_on_stripe(struct stripe_head *sh)
-{
- if (stripe_locked(sh))
- __wait_on_stripe(sh);
+ atomic_dec(&conf->nr_pending_stripes);
+ atomic_inc(&conf->nr_cached_stripes);
+ __unlock_stripe(sh);
+ atomic_dec(&sh->count);
+ wake_up(&conf->wait_for_stripe);
}
-static inline void remove_hash(struct raid5_data *raid_conf, struct stripe_head *sh)
+static void remove_hash(raid5_conf_t *conf, struct stripe_head *sh)
{
- PRINTK(("remove_hash(), stripe %lu\n", sh->sector));
+ PRINTK("remove_hash(), stripe %lu\n", sh->sector);
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
if (sh->hash_pprev) {
if (sh->hash_next)
sh->hash_next->hash_pprev = sh->hash_pprev;
*sh->hash_pprev = sh->hash_next;
sh->hash_pprev = NULL;
- raid_conf->nr_hashed_stripes--;
+ atomic_dec(&conf->nr_hashed_stripes);
}
}
-static inline void insert_hash(struct raid5_data *raid_conf, struct stripe_head *sh)
+static void lock_get_bh (struct buffer_head *bh)
{
- struct stripe_head **shp = &stripe_hash(raid_conf, sh->sector, sh->size);
+ while (md_test_and_set_bit(BH_Lock, &bh->b_state))
+ __wait_on_buffer(bh);
+ atomic_inc(&bh->b_count);
+}
+
+static __inline__ void insert_hash(raid5_conf_t *conf, struct stripe_head *sh)
+{
+ struct stripe_head **shp = &stripe_hash(conf, sh->sector, sh->size);
- PRINTK(("insert_hash(), stripe %lu, nr_hashed_stripes %d\n", sh->sector, raid_conf->nr_hashed_stripes));
+ PRINTK("insert_hash(), stripe %lu, nr_hashed_stripes %d\n",
+ sh->sector, atomic_read(&conf->nr_hashed_stripes));
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
if ((sh->hash_next = *shp) != NULL)
(*shp)->hash_pprev = &sh->hash_next;
*shp = sh;
sh->hash_pprev = shp;
- raid_conf->nr_hashed_stripes++;
+ atomic_inc(&conf->nr_hashed_stripes);
}
static struct buffer_head *get_free_buffer(struct stripe_head *sh, int b_size)
@@ -145,13 +124,18 @@ static struct buffer_head *get_free_buffer(struct stripe_head *sh, int b_size)
struct buffer_head *bh;
unsigned long flags;
- save_flags(flags);
- cli();
- if ((bh = sh->buffer_pool) == NULL)
- return NULL;
+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ bh = sh->buffer_pool;
+ if (!bh)
+ goto out_unlock;
sh->buffer_pool = bh->b_next;
bh->b_size = b_size;
- restore_flags(flags);
+ if (atomic_read(&bh->b_count))
+ BUG();
+out_unlock:
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
+
return bh;
}
@@ -160,12 +144,17 @@ static struct buffer_head *get_free_bh(struct stripe_head *sh)
struct buffer_head *bh;
unsigned long flags;
- save_flags(flags);
- cli();
- if ((bh = sh->bh_pool) == NULL)
- return NULL;
+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
+ bh = sh->bh_pool;
+ if (!bh)
+ goto out_unlock;
sh->bh_pool = bh->b_next;
- restore_flags(flags);
+ if (atomic_read(&bh->b_count))
+ BUG();
+out_unlock:
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
+
return bh;
}
@@ -173,55 +162,58 @@ static void put_free_buffer(struct stripe_head *sh, struct buffer_head *bh)
{
unsigned long flags;
- save_flags(flags);
- cli();
+ if (atomic_read(&bh->b_count))
+ BUG();
+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
bh->b_next = sh->buffer_pool;
sh->buffer_pool = bh;
- restore_flags(flags);
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
}
static void put_free_bh(struct stripe_head *sh, struct buffer_head *bh)
{
unsigned long flags;
- save_flags(flags);
- cli();
+ if (atomic_read(&bh->b_count))
+ BUG();
+ CHECK_SHLOCK(sh);
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
bh->b_next = sh->bh_pool;
sh->bh_pool = bh;
- restore_flags(flags);
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
}
-static struct stripe_head *get_free_stripe(struct raid5_data *raid_conf)
+static struct stripe_head *get_free_stripe(raid5_conf_t *conf)
{
struct stripe_head *sh;
- unsigned long flags;
- save_flags(flags);
- cli();
- if ((sh = raid_conf->free_sh_list) == NULL) {
- restore_flags(flags);
- return NULL;
- }
- raid_conf->free_sh_list = sh->free_next;
- raid_conf->nr_free_sh--;
- if (!raid_conf->nr_free_sh && raid_conf->free_sh_list)
- printk ("raid5: bug: free_sh_list != NULL, nr_free_sh == 0\n");
- restore_flags(flags);
- if (sh->hash_pprev || sh->nr_pending || sh->count)
- printk("get_free_stripe(): bug\n");
+ md_spin_lock_irq(&conf->device_lock);
+ sh = conf->free_sh_list;
+ if (!sh)
+ goto out;
+ conf->free_sh_list = sh->free_next;
+ atomic_dec(&conf->nr_free_sh);
+ if (!atomic_read(&conf->nr_free_sh) && conf->free_sh_list)
+ BUG();
+ if (sh->hash_pprev || md_atomic_read(&sh->nr_pending) ||
+ atomic_read(&sh->count))
+ BUG();
+out:
+ md_spin_unlock_irq(&conf->device_lock);
return sh;
}
-static void put_free_stripe(struct raid5_data *raid_conf, struct stripe_head *sh)
+static void __put_free_stripe (raid5_conf_t *conf, struct stripe_head *sh)
{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- sh->free_next = raid_conf->free_sh_list;
- raid_conf->free_sh_list = sh;
- raid_conf->nr_free_sh++;
- restore_flags(flags);
+ if (atomic_read(&sh->count) != 0)
+ BUG();
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
+ clear_bit(STRIPE_LOCKED, &sh->state);
+ sh->free_next = conf->free_sh_list;
+ conf->free_sh_list = sh;
+ atomic_inc(&conf->nr_free_sh);
}
static void shrink_buffers(struct stripe_head *sh, int num)
@@ -229,7 +221,8 @@ static void shrink_buffers(struct stripe_head *sh, int num)
struct buffer_head *bh;
while (num--) {
- if ((bh = get_free_buffer(sh, -1)) == NULL)
+ bh = get_free_buffer(sh, -1);
+ if (!bh)
return;
free_page((unsigned long) bh->b_data);
kfree(bh);
@@ -241,26 +234,33 @@ static void shrink_bh(struct stripe_head *sh, int num)
struct buffer_head *bh;
while (num--) {
- if ((bh = get_free_bh(sh)) == NULL)
+ bh = get_free_bh(sh);
+ if (!bh)
return;
kfree(bh);
}
}
-static int grow_buffers(struct stripe_head *sh, int num, int b_size, int priority)
+static int grow_raid5_buffers(struct stripe_head *sh, int num, int b_size, int priority)
{
struct buffer_head *bh;
while (num--) {
- if ((bh = kmalloc(sizeof(struct buffer_head), priority)) == NULL)
+ struct page *page;
+ bh = kmalloc(sizeof(struct buffer_head), priority);
+ if (!bh)
return 1;
memset(bh, 0, sizeof (struct buffer_head));
- bh->b_data = (char *) __get_free_page(priority);
+ init_waitqueue_head(&bh->b_wait);
+ page = alloc_page(priority);
+ bh->b_data = (char *) page_address(page);
if (!bh->b_data) {
kfree(bh);
return 1;
}
bh->b_size = b_size;
+ atomic_set(&bh->b_count, 0);
+ set_bh_page(bh, page, 0);
put_free_buffer(sh, bh);
}
return 0;
@@ -271,259 +271,314 @@ static int grow_bh(struct stripe_head *sh, int num, int priority)
struct buffer_head *bh;
while (num--) {
- if ((bh = kmalloc(sizeof(struct buffer_head), priority)) == NULL)
+ bh = kmalloc(sizeof(struct buffer_head), priority);
+ if (!bh)
return 1;
memset(bh, 0, sizeof (struct buffer_head));
+ init_waitqueue_head(&bh->b_wait);
put_free_bh(sh, bh);
}
return 0;
}
-static void raid5_kfree_buffer(struct stripe_head *sh, struct buffer_head *bh)
+static void raid5_free_buffer(struct stripe_head *sh, struct buffer_head *bh)
{
- unsigned long flags;
-
- save_flags(flags);
- cli();
put_free_buffer(sh, bh);
- restore_flags(flags);
}
-static void raid5_kfree_bh(struct stripe_head *sh, struct buffer_head *bh)
+static void raid5_free_bh(struct stripe_head *sh, struct buffer_head *bh)
{
- unsigned long flags;
-
- save_flags(flags);
- cli();
put_free_bh(sh, bh);
- restore_flags(flags);
}
-static void raid5_kfree_old_bh(struct stripe_head *sh, int i)
+static void raid5_free_old_bh(struct stripe_head *sh, int i)
{
- if (!sh->bh_old[i]) {
- printk("raid5_kfree_old_bh: bug: sector %lu, index %d not present\n", sh->sector, i);
- return;
- }
- raid5_kfree_buffer(sh, sh->bh_old[i]);
+ CHECK_SHLOCK(sh);
+ if (!sh->bh_old[i])
+ BUG();
+ raid5_free_buffer(sh, sh->bh_old[i]);
sh->bh_old[i] = NULL;
}
static void raid5_update_old_bh(struct stripe_head *sh, int i)
{
- PRINTK(("stripe %lu, idx %d, updating cache copy\n", sh->sector, i));
- if (!sh->bh_copy[i]) {
- printk("raid5_update_old_bh: bug: sector %lu, index %d not present\n", sh->sector, i);
- return;
- }
+ CHECK_SHLOCK(sh);
+ PRINTK("stripe %lu, idx %d, updating cache copy\n", sh->sector, i);
+ if (!sh->bh_copy[i])
+ BUG();
if (sh->bh_old[i])
- raid5_kfree_old_bh(sh, i);
+ raid5_free_old_bh(sh, i);
sh->bh_old[i] = sh->bh_copy[i];
sh->bh_copy[i] = NULL;
}
-static void kfree_stripe(struct stripe_head *sh)
+static void free_stripe(struct stripe_head *sh)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- int disks = raid_conf->raid_disks, j;
-
- PRINTK(("kfree_stripe called, stripe %lu\n", sh->sector));
- if (sh->phase != PHASE_COMPLETE || stripe_locked(sh) || sh->count) {
- printk("raid5: kfree_stripe(), sector %lu, phase %d, locked %d, count %d\n", sh->sector, sh->phase, stripe_locked(sh), sh->count);
+ raid5_conf_t *conf = sh->raid_conf;
+ int disks = conf->raid_disks, j;
+
+ if (atomic_read(&sh->count) != 0)
+ BUG();
+ CHECK_DEVLOCK();
+ CHECK_SHLOCK(sh);
+ PRINTK("free_stripe called, stripe %lu\n", sh->sector);
+ if (sh->phase != PHASE_COMPLETE || atomic_read(&sh->count)) {
+ PRINTK("raid5: free_stripe(), sector %lu, phase %d, count %d\n", sh->sector, sh->phase, atomic_read(&sh->count));
return;
}
for (j = 0; j < disks; j++) {
if (sh->bh_old[j])
- raid5_kfree_old_bh(sh, j);
+ raid5_free_old_bh(sh, j);
if (sh->bh_new[j] || sh->bh_copy[j])
- printk("raid5: bug: sector %lu, new %p, copy %p\n", sh->sector, sh->bh_new[j], sh->bh_copy[j]);
+ BUG();
}
- remove_hash(raid_conf, sh);
- put_free_stripe(raid_conf, sh);
+ remove_hash(conf, sh);
+ __put_free_stripe(conf, sh);
}
-static int shrink_stripe_cache(struct raid5_data *raid_conf, int nr)
+static int shrink_stripe_cache(raid5_conf_t *conf, int nr)
{
struct stripe_head *sh;
int i, count = 0;
- PRINTK(("shrink_stripe_cache called, %d/%d, clock %d\n", nr, raid_conf->nr_hashed_stripes, raid_conf->clock));
+ PRINTK("shrink_stripe_cache called, %d/%d, clock %d\n", nr, atomic_read(&conf->nr_hashed_stripes), conf->clock);
+ md_spin_lock_irq(&conf->device_lock);
for (i = 0; i < NR_HASH; i++) {
-repeat:
- sh = raid_conf->stripe_hashtbl[(i + raid_conf->clock) & HASH_MASK];
+ sh = conf->stripe_hashtbl[(i + conf->clock) & HASH_MASK];
for (; sh; sh = sh->hash_next) {
if (sh->phase != PHASE_COMPLETE)
continue;
- if (stripe_locked(sh))
+ if (atomic_read(&sh->count))
continue;
- if (sh->count)
+ /*
+ * Try to lock this stripe:
+ */
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
continue;
- kfree_stripe(sh);
+ free_stripe(sh);
if (++count == nr) {
- PRINTK(("shrink completed, nr_hashed_stripes %d\n", raid_conf->nr_hashed_stripes));
- raid_conf->clock = (i + raid_conf->clock) & HASH_MASK;
- return nr;
+ conf->clock = (i + conf->clock) & HASH_MASK;
+ goto out;
}
- goto repeat;
}
}
- PRINTK(("shrink completed, nr_hashed_stripes %d\n", raid_conf->nr_hashed_stripes));
+out:
+ md_spin_unlock_irq(&conf->device_lock);
+ PRINTK("shrink completed, nr_hashed_stripes %d, nr_pending_strips %d\n",
+ atomic_read(&conf->nr_hashed_stripes),
+ atomic_read(&conf->nr_pending_stripes));
return count;
}
-static struct stripe_head *find_stripe(struct raid5_data *raid_conf, unsigned long sector, int size)
+void __wait_lock_stripe(struct stripe_head *sh)
{
- struct stripe_head *sh;
+ MD_DECLARE_WAITQUEUE(wait, current);
- if (raid_conf->buffer_size != size) {
- PRINTK(("switching size, %d --> %d\n", raid_conf->buffer_size, size));
- shrink_stripe_cache(raid_conf, raid_conf->max_nr_stripes);
- raid_conf->buffer_size = size;
+ PRINTK("wait_lock_stripe %lu\n", sh->sector);
+ if (!atomic_read(&sh->count))
+ BUG();
+ add_wait_queue(&sh->wait, &wait);
+repeat:
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state)) {
+ schedule();
+ goto repeat;
}
+ PRINTK("wait_lock_stripe %lu done\n", sh->sector);
+ remove_wait_queue(&sh->wait, &wait);
+ current->state = TASK_RUNNING;
+}
- PRINTK(("find_stripe, sector %lu\n", sector));
- for (sh = stripe_hash(raid_conf, sector, size); sh; sh = sh->hash_next)
- if (sh->sector == sector && sh->raid_conf == raid_conf) {
- if (sh->size == size) {
- PRINTK(("found stripe %lu\n", sector));
- return sh;
- } else {
- PRINTK(("switching size for %lu, %d --> %d\n", sector, sh->size, size));
- kfree_stripe(sh);
- break;
- }
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, unsigned long sector, int size)
+{
+ struct stripe_head *sh;
+
+ PRINTK("__find_stripe, sector %lu\n", sector);
+ for (sh = stripe_hash(conf, sector, size); sh; sh = sh->hash_next) {
+ if (sh->sector == sector && sh->raid_conf == conf) {
+ if (sh->size != size)
+ BUG();
+ return sh;
}
- PRINTK(("stripe %lu not in cache\n", sector));
+ }
+ PRINTK("__stripe %lu not in cache\n", sector);
return NULL;
}
-static int grow_stripes(struct raid5_data *raid_conf, int num, int priority)
+static inline struct stripe_head *alloc_stripe(raid5_conf_t *conf, unsigned long sector, int size)
+{
+ struct stripe_head *sh;
+ struct buffer_head *buffer_pool, *bh_pool;
+ MD_DECLARE_WAITQUEUE(wait, current);
+
+ PRINTK("alloc_stripe called\n");
+
+
+ while ((sh = get_free_stripe(conf)) == NULL) {
+ int cnt;
+ add_wait_queue(&conf->wait_for_stripe, &wait);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ cnt = shrink_stripe_cache(conf, conf->max_nr_stripes / 8);
+ sh = get_free_stripe(conf);
+ if (!sh && cnt < (conf->max_nr_stripes/8)) {
+ md_wakeup_thread(conf->thread);
+ PRINTK("waiting for some stripes to complete - %d %d\n", cnt, conf->max_nr_stripes/8);
+ schedule();
+ }
+ remove_wait_queue(&conf->wait_for_stripe, &wait);
+ current->state = TASK_RUNNING;
+ if (sh)
+ break;
+ }
+
+ buffer_pool = sh->buffer_pool;
+ bh_pool = sh->bh_pool;
+ memset(sh, 0, sizeof(*sh));
+ sh->stripe_lock = MD_SPIN_LOCK_UNLOCKED;
+ md_init_waitqueue_head(&sh->wait);
+ sh->buffer_pool = buffer_pool;
+ sh->bh_pool = bh_pool;
+ sh->phase = PHASE_COMPLETE;
+ sh->cmd = STRIPE_NONE;
+ sh->raid_conf = conf;
+ sh->sector = sector;
+ sh->size = size;
+ atomic_inc(&conf->nr_cached_stripes);
+
+ return sh;
+}
+
+static struct stripe_head *get_lock_stripe(raid5_conf_t *conf, unsigned long sector, int size)
+{
+ struct stripe_head *sh, *new = NULL;
+
+ PRINTK("get_stripe, sector %lu\n", sector);
+
+ /*
+ * Do this in set_blocksize()!
+ */
+ if (conf->buffer_size != size) {
+ PRINTK("switching size, %d --> %d\n", conf->buffer_size, size);
+ shrink_stripe_cache(conf, conf->max_nr_stripes);
+ conf->buffer_size = size;
+ }
+
+repeat:
+ md_spin_lock_irq(&conf->device_lock);
+ sh = __find_stripe(conf, sector, size);
+ if (!sh) {
+ if (!new) {
+ md_spin_unlock_irq(&conf->device_lock);
+ new = alloc_stripe(conf, sector, size);
+ goto repeat;
+ }
+ sh = new;
+ new = NULL;
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ insert_hash(conf, sh);
+ atomic_inc(&sh->count);
+ md_spin_unlock_irq(&conf->device_lock);
+ } else {
+ atomic_inc(&sh->count);
+ if (new) {
+ if (md_test_and_set_bit(STRIPE_LOCKED, &new->state))
+ BUG();
+ __put_free_stripe(conf, new);
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+ PRINTK("get_stripe, waiting, sector %lu\n", sector);
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ __wait_lock_stripe(sh);
+ }
+ return sh;
+}
+
+static int grow_stripes(raid5_conf_t *conf, int num, int priority)
{
struct stripe_head *sh;
while (num--) {
- if ((sh = kmalloc(sizeof(struct stripe_head), priority)) == NULL)
+ sh = kmalloc(sizeof(struct stripe_head), priority);
+ if (!sh)
return 1;
memset(sh, 0, sizeof(*sh));
- if (grow_buffers(sh, 2 * raid_conf->raid_disks, PAGE_SIZE, priority)) {
- shrink_buffers(sh, 2 * raid_conf->raid_disks);
+ sh->raid_conf = conf;
+ sh->stripe_lock = MD_SPIN_LOCK_UNLOCKED;
+ md_init_waitqueue_head(&sh->wait);
+
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ if (grow_raid5_buffers(sh, 2 * conf->raid_disks, PAGE_SIZE, priority)) {
+ shrink_buffers(sh, 2 * conf->raid_disks);
kfree(sh);
return 1;
}
- if (grow_bh(sh, raid_conf->raid_disks, priority)) {
- shrink_buffers(sh, 2 * raid_conf->raid_disks);
- shrink_bh(sh, raid_conf->raid_disks);
+ if (grow_bh(sh, conf->raid_disks, priority)) {
+ shrink_buffers(sh, 2 * conf->raid_disks);
+ shrink_bh(sh, conf->raid_disks);
kfree(sh);
return 1;
}
- put_free_stripe(raid_conf, sh);
- raid_conf->nr_stripes++;
+ md_spin_lock_irq(&conf->device_lock);
+ __put_free_stripe(conf, sh);
+ atomic_inc(&conf->nr_stripes);
+ md_spin_unlock_irq(&conf->device_lock);
}
return 0;
}
-static void shrink_stripes(struct raid5_data *raid_conf, int num)
+static void shrink_stripes(raid5_conf_t *conf, int num)
{
struct stripe_head *sh;
while (num--) {
- sh = get_free_stripe(raid_conf);
+ sh = get_free_stripe(conf);
if (!sh)
break;
- shrink_buffers(sh, raid_conf->raid_disks * 2);
- shrink_bh(sh, raid_conf->raid_disks);
+ if (md_test_and_set_bit(STRIPE_LOCKED, &sh->state))
+ BUG();
+ shrink_buffers(sh, conf->raid_disks * 2);
+ shrink_bh(sh, conf->raid_disks);
kfree(sh);
- raid_conf->nr_stripes--;
- }
-}
-
-static struct stripe_head *kmalloc_stripe(struct raid5_data *raid_conf, unsigned long sector, int size)
-{
- struct stripe_head *sh = NULL, *tmp;
- struct buffer_head *buffer_pool, *bh_pool;
-
- PRINTK(("kmalloc_stripe called\n"));
-
- while ((sh = get_free_stripe(raid_conf)) == NULL) {
- shrink_stripe_cache(raid_conf, raid_conf->max_nr_stripes / 8);
- if ((sh = get_free_stripe(raid_conf)) != NULL)
- break;
- if (!raid_conf->nr_pending_stripes)
- printk("raid5: bug: nr_free_sh == 0, nr_pending_stripes == 0\n");
- md_wakeup_thread(raid_conf->thread);
- PRINTK(("waiting for some stripes to complete\n"));
- sleep_on(&raid_conf->wait_for_stripe);
+ atomic_dec(&conf->nr_stripes);
}
-
- /*
- * The above might have slept, so perhaps another process
- * already created the stripe for us..
- */
- if ((tmp = find_stripe(raid_conf, sector, size)) != NULL) {
- put_free_stripe(raid_conf, sh);
- wait_on_stripe(tmp);
- return tmp;
- }
- if (sh) {
- buffer_pool = sh->buffer_pool;
- bh_pool = sh->bh_pool;
- memset(sh, 0, sizeof(*sh));
- sh->buffer_pool = buffer_pool;
- sh->bh_pool = bh_pool;
- sh->phase = PHASE_COMPLETE;
- sh->cmd = STRIPE_NONE;
- sh->raid_conf = raid_conf;
- sh->sector = sector;
- sh->size = size;
- raid_conf->nr_cached_stripes++;
- insert_hash(raid_conf, sh);
- } else printk("raid5: bug: kmalloc_stripe() == NULL\n");
- return sh;
-}
-
-static struct stripe_head *get_stripe(struct raid5_data *raid_conf, unsigned long sector, int size)
-{
- struct stripe_head *sh;
-
- PRINTK(("get_stripe, sector %lu\n", sector));
- sh = find_stripe(raid_conf, sector, size);
- if (sh)
- wait_on_stripe(sh);
- else
- sh = kmalloc_stripe(raid_conf, sector, size);
- return sh;
}
-static struct buffer_head *raid5_kmalloc_buffer(struct stripe_head *sh, int b_size)
+static struct buffer_head *raid5_alloc_buffer(struct stripe_head *sh, int b_size)
{
struct buffer_head *bh;
- if ((bh = get_free_buffer(sh, b_size)) == NULL)
- printk("raid5: bug: raid5_kmalloc_buffer() == NULL\n");
+ bh = get_free_buffer(sh, b_size);
+ if (!bh)
+ BUG();
return bh;
}
-static struct buffer_head *raid5_kmalloc_bh(struct stripe_head *sh)
+static struct buffer_head *raid5_alloc_bh(struct stripe_head *sh)
{
struct buffer_head *bh;
- if ((bh = get_free_bh(sh)) == NULL)
- printk("raid5: bug: raid5_kmalloc_bh() == NULL\n");
+ bh = get_free_bh(sh);
+ if (!bh)
+ BUG();
return bh;
}
-static inline void raid5_end_buffer_io (struct stripe_head *sh, int i, int uptodate)
+static void raid5_end_buffer_io (struct stripe_head *sh, int i, int uptodate)
{
struct buffer_head *bh = sh->bh_new[i];
+ PRINTK("raid5_end_buffer_io %lu, uptodate: %d.\n", bh->b_rsector, uptodate);
sh->bh_new[i] = NULL;
- raid5_kfree_bh(sh, sh->bh_req[i]);
+ raid5_free_bh(sh, sh->bh_req[i]);
sh->bh_req[i] = NULL;
+ PRINTK("calling %p->end_io: %p.\n", bh, bh->b_end_io);
bh->b_end_io(bh, uptodate);
if (!uptodate)
printk(KERN_ALERT "raid5: %s: unrecoverable I/O error for "
- "block %lu\n", kdevname(bh->b_dev), bh->b_blocknr);
+ "block %lu\n", partition_name(bh->b_dev), bh->b_blocknr);
}
static inline void raid5_mark_buffer_uptodate (struct buffer_head *bh, int uptodate)
@@ -537,61 +592,55 @@ static inline void raid5_mark_buffer_uptodate (struct buffer_head *bh, int uptod
static void raid5_end_request (struct buffer_head * bh, int uptodate)
{
struct stripe_head *sh = bh->b_dev_id;
- struct raid5_data *raid_conf = sh->raid_conf;
- int disks = raid_conf->raid_disks, i;
+ raid5_conf_t *conf = sh->raid_conf;
+ int disks = conf->raid_disks, i;
unsigned long flags;
- PRINTK(("end_request %lu, nr_pending %d\n", sh->sector, sh->nr_pending));
- save_flags(flags);
- cli();
+ PRINTK("end_request %lu, nr_pending %d, uptodate: %d, (caller: %p,%p,%p,%p).\n", sh->sector, atomic_read(&sh->nr_pending), uptodate, __builtin_return_address(0),__builtin_return_address(1),__builtin_return_address(2), __builtin_return_address(3));
+ md_spin_lock_irqsave(&sh->stripe_lock, flags);
raid5_mark_buffer_uptodate(bh, uptodate);
- --sh->nr_pending;
- if (!sh->nr_pending) {
- md_wakeup_thread(raid_conf->thread);
- atomic_inc(&raid_conf->nr_handle);
- }
if (!uptodate)
md_error(bh->b_dev, bh->b_rdev);
- if (raid_conf->failed_disks) {
+ if (conf->failed_disks) {
for (i = 0; i < disks; i++) {
- if (raid_conf->disks[i].operational)
+ if (conf->disks[i].operational)
continue;
if (bh != sh->bh_old[i] && bh != sh->bh_req[i] && bh != sh->bh_copy[i])
continue;
- if (bh->b_rdev != raid_conf->disks[i].dev)
+ if (bh->b_rdev != conf->disks[i].dev)
continue;
set_bit(STRIPE_ERROR, &sh->state);
}
}
- restore_flags(flags);
-}
+ md_spin_unlock_irqrestore(&sh->stripe_lock, flags);
-static int raid5_map (struct md_dev *mddev, kdev_t *rdev,
- unsigned long *rsector, unsigned long size)
-{
- /* No complex mapping used: the core of the work is done in the
- * request routine
- */
- return 0;
+ if (atomic_dec_and_test(&sh->nr_pending)) {
+ atomic_inc(&conf->nr_handle);
+ md_wakeup_thread(conf->thread);
+ }
}
static void raid5_build_block (struct stripe_head *sh, struct buffer_head *bh, int i)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- struct md_dev *mddev = raid_conf->mddev;
- int minor = (int) (mddev - md_dev);
+ raid5_conf_t *conf = sh->raid_conf;
+ mddev_t *mddev = conf->mddev;
char *b_data;
- kdev_t dev = MKDEV(MD_MAJOR, minor);
+ struct page *b_page;
+ kdev_t dev = mddev_to_kdev(mddev);
int block = sh->sector / (sh->size >> 9);
- b_data = ((volatile struct buffer_head *) bh)->b_data;
+ b_data = bh->b_data;
+ b_page = bh->b_page;
memset (bh, 0, sizeof (struct buffer_head));
+ init_waitqueue_head(&bh->b_wait);
init_buffer(bh, raid5_end_request, sh);
bh->b_dev = dev;
bh->b_blocknr = block;
- ((volatile struct buffer_head *) bh)->b_data = b_data;
- bh->b_rdev = raid_conf->disks[i].dev;
+ bh->b_data = b_data;
+ bh->b_page = b_page;
+
+ bh->b_rdev = conf->disks[i].dev;
bh->b_rsector = sh->sector;
bh->b_state = (1 << BH_Req) | (1 << BH_Mapped);
@@ -599,49 +648,77 @@ static void raid5_build_block (struct stripe_head *sh, struct buffer_head *bh, i
bh->b_list = BUF_LOCKED;
}
-static int raid5_error (struct md_dev *mddev, kdev_t dev)
+static int raid5_error (mddev_t *mddev, kdev_t dev)
{
- struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
- md_superblock_t *sb = mddev->sb;
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+ mdp_super_t *sb = mddev->sb;
struct disk_info *disk;
int i;
- PRINTK(("raid5_error called\n"));
- raid_conf->resync_parity = 0;
- for (i = 0, disk = raid_conf->disks; i < raid_conf->raid_disks; i++, disk++)
+ 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;
- sb->disks[disk->number].state |= (1 << MD_FAULTY_DEVICE);
- sb->disks[disk->number].state &= ~(1 << MD_SYNC_DEVICE);
- sb->disks[disk->number].state &= ~(1 << MD_ACTIVE_DEVICE);
+ mark_disk_faulty(sb->disks+disk->number);
+ mark_disk_nonsync(sb->disks+disk->number);
+ mark_disk_inactive(sb->disks+disk->number);
sb->active_disks--;
sb->working_disks--;
sb->failed_disks++;
mddev->sb_dirty = 1;
- raid_conf->working_disks--;
- raid_conf->failed_disks++;
- md_wakeup_thread(raid_conf->thread);
+ conf->working_disks--;
+ conf->failed_disks++;
+ md_wakeup_thread(conf->thread);
printk (KERN_ALERT
- "RAID5: Disk failure on %s, disabling device."
- "Operation continuing on %d devices\n",
- kdevname (dev), raid_conf->working_disks);
+ "raid5: Disk failure on %s, disabling device."
+ " Operation continuing on %d devices\n",
+ partition_name (dev), conf->working_disks);
+ return 0;
}
- return 0;
+ }
+ /*
+ * handle errors in spares (during reconstruction)
+ */
+ if (conf->spare) {
+ disk = conf->spare;
+ if (disk->dev == dev) {
+ printk (KERN_ALERT
+ "raid5: Disk failure on spare %s\n",
+ partition_name (dev));
+ if (!conf->spare->operational) {
+ MD_BUG();
+ return -EIO;
+ }
+ disk->operational = 0;
+ disk->write_only = 0;
+ conf->spare = NULL;
+ mark_disk_faulty(sb->disks+disk->number);
+ mark_disk_nonsync(sb->disks+disk->number);
+ mark_disk_inactive(sb->disks+disk->number);
+ sb->spare_disks--;
+ sb->working_disks--;
+ sb->failed_disks++;
+
+ return 0;
+ }
+ }
+ MD_BUG();
+ return -EIO;
}
/*
* Input: a 'big' sector number,
* Output: index of the data and parity disk, and the sector # in them.
*/
-static inline unsigned long
-raid5_compute_sector (int r_sector, unsigned int raid_disks, unsigned int data_disks,
- unsigned int * dd_idx, unsigned int * pd_idx,
- struct raid5_data *raid_conf)
+static unsigned long raid5_compute_sector(int r_sector, unsigned int raid_disks,
+ unsigned int data_disks, unsigned int * dd_idx,
+ unsigned int * pd_idx, raid5_conf_t *conf)
{
unsigned int stripe;
int chunk_number, chunk_offset;
unsigned long new_sector;
- int sectors_per_chunk = raid_conf->chunk_size >> 9;
+ int sectors_per_chunk = conf->chunk_size >> 9;
/* First compute the information on this sector */
@@ -664,9 +741,9 @@ raid5_compute_sector (int r_sector, unsigned int raid_disks, unsigned int data_d
/*
* Select the parity disk based on the user selected algorithm.
*/
- if (raid_conf->level == 4)
+ if (conf->level == 4)
*pd_idx = data_disks;
- else switch (raid_conf->algorithm) {
+ else switch (conf->algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
*pd_idx = data_disks - stripe % raid_disks;
if (*dd_idx >= *pd_idx)
@@ -686,7 +763,7 @@ raid5_compute_sector (int r_sector, unsigned int raid_disks, unsigned int data_d
*dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
break;
default:
- printk ("raid5: unsupported algorithm %d\n", raid_conf->algorithm);
+ printk ("raid5: unsupported algorithm %d\n", conf->algorithm);
}
/*
@@ -707,16 +784,16 @@ raid5_compute_sector (int r_sector, unsigned int raid_disks, unsigned int data_d
static unsigned long compute_blocknr(struct stripe_head *sh, int i)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- int raid_disks = raid_conf->raid_disks, data_disks = raid_disks - 1;
+ raid5_conf_t *conf = sh->raid_conf;
+ int raid_disks = conf->raid_disks, data_disks = raid_disks - 1;
unsigned long new_sector = sh->sector, check;
- int sectors_per_chunk = raid_conf->chunk_size >> 9;
+ int sectors_per_chunk = conf->chunk_size >> 9;
unsigned long stripe = new_sector / sectors_per_chunk;
int chunk_offset = new_sector % sectors_per_chunk;
int chunk_number, dummy1, dummy2, dd_idx = i;
unsigned long r_sector, blocknr;
- switch (raid_conf->algorithm) {
+ switch (conf->algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
if (i > sh->pd_idx)
@@ -729,14 +806,14 @@ static unsigned long compute_blocknr(struct stripe_head *sh, int i)
i -= (sh->pd_idx + 1);
break;
default:
- printk ("raid5: unsupported algorithm %d\n", raid_conf->algorithm);
+ printk ("raid5: unsupported algorithm %d\n", conf->algorithm);
}
chunk_number = stripe * data_disks + i;
r_sector = chunk_number * sectors_per_chunk + chunk_offset;
blocknr = r_sector / (sh->size >> 9);
- check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, raid_conf);
+ check = raid5_compute_sector (r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
printk("compute_blocknr: map not correct\n");
return 0;
@@ -744,144 +821,153 @@ static unsigned long compute_blocknr(struct stripe_head *sh, int i)
return blocknr;
}
-#ifdef HAVE_ARCH_XORBLOCK
-static void xor_block(struct buffer_head *dest, struct buffer_head *source)
-{
- __xor_block((char *) dest->b_data, (char *) source->b_data, dest->b_size);
-}
-#else
-static void xor_block(struct buffer_head *dest, struct buffer_head *source)
-{
- long lines = dest->b_size / (sizeof (long)) / 8, i;
- long *destp = (long *) dest->b_data, *sourcep = (long *) source->b_data;
-
- for (i = lines; i > 0; i--) {
- *(destp + 0) ^= *(sourcep + 0);
- *(destp + 1) ^= *(sourcep + 1);
- *(destp + 2) ^= *(sourcep + 2);
- *(destp + 3) ^= *(sourcep + 3);
- *(destp + 4) ^= *(sourcep + 4);
- *(destp + 5) ^= *(sourcep + 5);
- *(destp + 6) ^= *(sourcep + 6);
- *(destp + 7) ^= *(sourcep + 7);
- destp += 8;
- sourcep += 8;
- }
-}
-#endif
-
static void compute_block(struct stripe_head *sh, int dd_idx)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- int i, disks = raid_conf->raid_disks;
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, count, disks = conf->raid_disks;
+ struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
- PRINTK(("compute_block, stripe %lu, idx %d\n", sh->sector, dd_idx));
+ PRINTK("compute_block, stripe %lu, idx %d\n", sh->sector, dd_idx);
if (sh->bh_old[dd_idx] == NULL)
- sh->bh_old[dd_idx] = raid5_kmalloc_buffer(sh, sh->size);
+ sh->bh_old[dd_idx] = raid5_alloc_buffer(sh, sh->size);
raid5_build_block(sh, sh->bh_old[dd_idx], dd_idx);
memset(sh->bh_old[dd_idx]->b_data, 0, sh->size);
+ bh_ptr[0] = sh->bh_old[dd_idx];
+ count = 1;
for (i = 0; i < disks; i++) {
if (i == dd_idx)
continue;
if (sh->bh_old[i]) {
- xor_block(sh->bh_old[dd_idx], sh->bh_old[i]);
- continue;
- } else
+ bh_ptr[count++] = sh->bh_old[i];
+ } else {
printk("compute_block() %d, stripe %lu, %d not present\n", dd_idx, sh->sector, i);
+ }
+ if (count == MAX_XOR_BLOCKS) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
+ }
+ }
+ if(count != 1) {
+ xor_block(count, &bh_ptr[0]);
}
raid5_mark_buffer_uptodate(sh->bh_old[dd_idx], 1);
}
static void compute_parity(struct stripe_head *sh, int method)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- int i, pd_idx = sh->pd_idx, disks = raid_conf->raid_disks;
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, pd_idx = sh->pd_idx, disks = conf->raid_disks, count;
+ struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
- PRINTK(("compute_parity, stripe %lu, method %d\n", sh->sector, method));
+ PRINTK("compute_parity, stripe %lu, method %d\n", sh->sector, method);
for (i = 0; i < disks; i++) {
if (i == pd_idx || !sh->bh_new[i])
continue;
if (!sh->bh_copy[i])
- sh->bh_copy[i] = raid5_kmalloc_buffer(sh, sh->size);
+ sh->bh_copy[i] = raid5_alloc_buffer(sh, sh->size);
raid5_build_block(sh, sh->bh_copy[i], i);
- mark_buffer_clean(sh->bh_new[i]);
+ if (atomic_set_buffer_clean(sh->bh_new[i]))
+ atomic_set_buffer_dirty(sh->bh_copy[i]);
memcpy(sh->bh_copy[i]->b_data, sh->bh_new[i]->b_data, sh->size);
}
- if (sh->bh_copy[pd_idx] == NULL)
- sh->bh_copy[pd_idx] = raid5_kmalloc_buffer(sh, sh->size);
+ if (sh->bh_copy[pd_idx] == NULL) {
+ sh->bh_copy[pd_idx] = raid5_alloc_buffer(sh, sh->size);
+ atomic_set_buffer_dirty(sh->bh_copy[pd_idx]);
+ }
raid5_build_block(sh, sh->bh_copy[pd_idx], sh->pd_idx);
if (method == RECONSTRUCT_WRITE) {
memset(sh->bh_copy[pd_idx]->b_data, 0, sh->size);
+ bh_ptr[0] = sh->bh_copy[pd_idx];
+ count = 1;
for (i = 0; i < disks; i++) {
if (i == sh->pd_idx)
continue;
if (sh->bh_new[i]) {
- xor_block(sh->bh_copy[pd_idx], sh->bh_copy[i]);
- continue;
+ bh_ptr[count++] = sh->bh_copy[i];
+ } else if (sh->bh_old[i]) {
+ bh_ptr[count++] = sh->bh_old[i];
}
- if (sh->bh_old[i]) {
- xor_block(sh->bh_copy[pd_idx], sh->bh_old[i]);
- continue;
+ if (count == MAX_XOR_BLOCKS) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
}
}
+ if (count != 1) {
+ xor_block(count, &bh_ptr[0]);
+ }
} else if (method == READ_MODIFY_WRITE) {
memcpy(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size);
+ bh_ptr[0] = sh->bh_copy[pd_idx];
+ count = 1;
for (i = 0; i < disks; i++) {
if (i == sh->pd_idx)
continue;
if (sh->bh_new[i] && sh->bh_old[i]) {
- xor_block(sh->bh_copy[pd_idx], sh->bh_copy[i]);
- xor_block(sh->bh_copy[pd_idx], sh->bh_old[i]);
- continue;
+ bh_ptr[count++] = sh->bh_copy[i];
+ bh_ptr[count++] = sh->bh_old[i];
+ }
+ if (count >= (MAX_XOR_BLOCKS - 1)) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
}
}
+ if (count != 1) {
+ xor_block(count, &bh_ptr[0]);
+ }
}
raid5_mark_buffer_uptodate(sh->bh_copy[pd_idx], 1);
}
static void add_stripe_bh (struct stripe_head *sh, struct buffer_head *bh, int dd_idx, int rw)
{
- struct raid5_data *raid_conf = sh->raid_conf;
+ raid5_conf_t *conf = sh->raid_conf;
struct buffer_head *bh_req;
- if (sh->bh_new[dd_idx]) {
- printk("raid5: bug: stripe->bh_new[%d], sector %lu exists\n", dd_idx, sh->sector);
- printk("forcing oops.\n");
- *(int*)0=0;
- }
-
- set_bit(BH_Lock, &bh->b_state);
+ PRINTK("adding bh b#%lu to stripe s#%lu\n", bh->b_blocknr, sh->sector);
+ CHECK_SHLOCK(sh);
+ if (sh->bh_new[dd_idx])
+ BUG();
- bh_req = raid5_kmalloc_bh(sh);
+ bh_req = raid5_alloc_bh(sh);
raid5_build_block(sh, bh_req, dd_idx);
bh_req->b_data = bh->b_data;
+ bh_req->b_page = bh->b_page;
+ md_spin_lock_irq(&conf->device_lock);
if (sh->phase == PHASE_COMPLETE && sh->cmd == STRIPE_NONE) {
+ PRINTK("stripe s#%lu => PHASE_BEGIN (%s)\n", sh->sector, rw == READ ? "read" : "write");
sh->phase = PHASE_BEGIN;
sh->cmd = (rw == READ) ? STRIPE_READ : STRIPE_WRITE;
- raid_conf->nr_pending_stripes++;
- atomic_inc(&raid_conf->nr_handle);
+ atomic_inc(&conf->nr_pending_stripes);
+ atomic_inc(&conf->nr_handle);
+ PRINTK("# of pending stripes: %u, # of handle: %u\n", atomic_read(&conf->nr_pending_stripes), atomic_read(&conf->nr_handle));
}
sh->bh_new[dd_idx] = bh;
sh->bh_req[dd_idx] = bh_req;
sh->cmd_new[dd_idx] = rw;
sh->new[dd_idx] = 1;
+ md_spin_unlock_irq(&conf->device_lock);
+
+ PRINTK("added bh b#%lu to stripe s#%lu, disk %d.\n", bh->b_blocknr, sh->sector, dd_idx);
}
static void complete_stripe(struct stripe_head *sh)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- int disks = raid_conf->raid_disks;
+ raid5_conf_t *conf = sh->raid_conf;
+ int disks = conf->raid_disks;
int i, new = 0;
- PRINTK(("complete_stripe %lu\n", sh->sector));
+ PRINTK("complete_stripe %lu\n", sh->sector);
for (i = 0; i < disks; i++) {
+ if (sh->cmd == STRIPE_SYNC && sh->bh_copy[i])
+ raid5_update_old_bh(sh, i);
if (sh->cmd == STRIPE_WRITE && i == sh->pd_idx)
raid5_update_old_bh(sh, i);
if (sh->bh_new[i]) {
+ PRINTK("stripe %lu finishes new bh, sh->new == %d\n", sh->sector, sh->new[i]);
if (!sh->new[i]) {
#if 0
if (sh->cmd == STRIPE_WRITE) {
@@ -903,14 +989,351 @@ static void complete_stripe(struct stripe_head *sh)
if (new && sh->cmd == STRIPE_WRITE)
printk("raid5: bug, completed STRIPE_WRITE with new == %d\n", new);
}
+ if (sh->cmd == STRIPE_SYNC)
+ md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
if (!new)
- finish_stripe(sh);
+ finish_unlock_stripe(sh);
else {
- PRINTK(("stripe %lu, new == %d\n", sh->sector, new));
+ PRINTK("stripe %lu, new == %d\n", sh->sector, new);
sh->phase = PHASE_BEGIN;
}
}
+
+static int is_stripe_allclean(struct stripe_head *sh, int disks)
+{
+ int i;
+
+ return 0;
+ for (i = 0; i < disks; i++) {
+ if (sh->bh_new[i])
+ if (test_bit(BH_Dirty, &sh->bh_new[i]))
+ return 0;
+ if (sh->bh_old[i])
+ if (test_bit(BH_Dirty, &sh->bh_old[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static void handle_stripe_write (mddev_t *mddev , raid5_conf_t *conf,
+ struct stripe_head *sh, int nr_write, int * operational, int disks,
+ int parity, int parity_failed, int nr_cache, int nr_cache_other,
+ int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
+{
+ int i, allclean;
+ request_queue_t *q;
+ unsigned int block;
+ struct buffer_head *bh;
+ int method1 = INT_MAX, method2 = INT_MAX;
+
+ /*
+ * Attempt to add entries :-)
+ */
+ if (nr_write != disks - 1) {
+ for (i = 0; i < disks; i++) {
+ if (i == sh->pd_idx)
+ continue;
+ if (sh->bh_new[i])
+ continue;
+ block = (int) compute_blocknr(sh, i);
+ bh = get_hash_table(mddev_to_kdev(mddev), block, sh->size);
+ if (!bh)
+ continue;
+ if (buffer_dirty(bh) && !md_test_and_set_bit(BH_Lock, &bh->b_state)) {
+ PRINTK("Whee.. sector %lu, index %d (%d) found in the buffer cache!\n", sh->sector, i, block);
+ add_stripe_bh(sh, bh, i, WRITE);
+ sh->new[i] = 0;
+ nr_write++;
+ if (sh->bh_old[i]) {
+ nr_cache_overwrite++;
+ nr_cache_other--;
+ } else
+ if (!operational[i]) {
+ nr_failed_overwrite++;
+ nr_failed_other--;
+ }
+ }
+ atomic_dec(&bh->b_count);
+ }
+ }
+ PRINTK("handle_stripe() -- begin writing, stripe %lu\n", sh->sector);
+ /*
+ * Writing, need to update parity buffer.
+ *
+ * Compute the number of I/O requests in the "reconstruct
+ * write" and "read modify write" methods.
+ */
+ if (!nr_failed_other)
+ method1 = (disks - 1) - (nr_write + nr_cache_other);
+ if (!nr_failed_overwrite && !parity_failed)
+ method2 = nr_write - nr_cache_overwrite + (1 - parity);
+
+ if (method1 == INT_MAX && method2 == INT_MAX)
+ BUG();
+ PRINTK("handle_stripe(), sector %lu, nr_write %d, method1 %d, method2 %d\n", sh->sector, nr_write, method1, method2);
+
+ if (!method1 || !method2) {
+ allclean = is_stripe_allclean(sh, disks);
+ sh->phase = PHASE_WRITE;
+ compute_parity(sh, method1 <= method2 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);
+
+ for (i = 0; i < disks; i++) {
+ if (!operational[i] && !conf->spare && !conf->resync_parity)
+ continue;
+ bh = sh->bh_copy[i];
+ if (i != sh->pd_idx && ((bh == NULL) ^ (sh->bh_new[i] == NULL)))
+ printk("raid5: bug: bh == %p, bh_new[%d] == %p\n", bh, i, sh->bh_new[i]);
+ if (i == sh->pd_idx && !bh)
+ printk("raid5: bug: bh == NULL, i == pd_idx == %d\n", i);
+ if (bh) {
+ PRINTK("making request for buffer %d\n", i);
+ lock_get_bh(bh);
+ if (!operational[i] && !conf->resync_parity) {
+ PRINTK("writing spare %d\n", i);
+ atomic_inc(&sh->nr_pending);
+ bh->b_rdev = conf->spare->dev;
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, WRITERAW, bh);
+ } else {
+#if 0
+ atomic_inc(&sh->nr_pending);
+ bh->b_rdev = conf->disks[i].dev;
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, WRITERAW, bh);
+#else
+ if (!allclean || (i==sh->pd_idx)) {
+ PRINTK("writing dirty %d\n", i);
+ atomic_inc(&sh->nr_pending);
+ bh->b_rdev = conf->disks[i].dev;
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, WRITERAW, bh);
+ } else {
+ PRINTK("not writing clean %d\n", i);
+ raid5_end_request(bh, 1);
+ sh->new[i] = 0;
+ }
+#endif
+ }
+ atomic_dec(&bh->b_count);
+ }
+ }
+ PRINTK("handle_stripe() %lu, writing back %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+ return;
+ }
+
+ if (method1 < method2) {
+ sh->write_method = RECONSTRUCT_WRITE;
+ for (i = 0; i < disks; i++) {
+ if (i == sh->pd_idx)
+ continue;
+ if (sh->bh_new[i] || sh->bh_old[i])
+ continue;
+ sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[i], i);
+ }
+ } else {
+ sh->write_method = READ_MODIFY_WRITE;
+ for (i = 0; i < disks; i++) {
+ if (sh->bh_old[i])
+ continue;
+ if (!sh->bh_new[i] && i != sh->pd_idx)
+ continue;
+ sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[i], i);
+ }
+ }
+ sh->phase = PHASE_READ_OLD;
+ for (i = 0; i < disks; i++) {
+ if (!sh->bh_old[i])
+ continue;
+ if (test_bit(BH_Uptodate, &sh->bh_old[i]->b_state))
+ continue;
+ lock_get_bh(sh->bh_old[i]);
+ atomic_inc(&sh->nr_pending);
+ sh->bh_old[i]->b_rdev = conf->disks[i].dev;
+ q = blk_get_queue(sh->bh_old[i]->b_rdev);
+ generic_make_request(q, READ, sh->bh_old[i]);
+ atomic_dec(&sh->bh_old[i]->b_count);
+ }
+ PRINTK("handle_stripe() %lu, reading %d old buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+}
+
+/*
+ * Reading
+ */
+static void handle_stripe_read (mddev_t *mddev , raid5_conf_t *conf,
+ struct stripe_head *sh, int nr_read, int * operational, int disks,
+ int parity, int parity_failed, int nr_cache, int nr_cache_other,
+ int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
+{
+ int i;
+ request_queue_t *q;
+ int method1 = INT_MAX;
+
+ method1 = nr_read - nr_cache_overwrite;
+
+ PRINTK("handle_stripe(), sector %lu, nr_read %d, nr_cache %d, method1 %d\n", sh->sector, nr_read, nr_cache, method1);
+
+ if (!method1 || (method1 == 1 && nr_cache == disks - 1)) {
+ PRINTK("read %lu completed from cache\n", sh->sector);
+ for (i = 0; i < disks; i++) {
+ if (!sh->bh_new[i])
+ continue;
+ if (!sh->bh_old[i])
+ compute_block(sh, i);
+ memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
+ }
+ complete_stripe(sh);
+ return;
+ }
+ if (nr_failed_overwrite) {
+ sh->phase = PHASE_READ_OLD;
+ for (i = 0; i < disks; i++) {
+ if (sh->bh_old[i])
+ continue;
+ if (!operational[i])
+ continue;
+ sh->bh_old[i] = raid5_alloc_buffer(sh, sh->size);
+ raid5_build_block(sh, sh->bh_old[i], i);
+ lock_get_bh(sh->bh_old[i]);
+ atomic_inc(&sh->nr_pending);
+ sh->bh_old[i]->b_rdev = conf->disks[i].dev;
+ q = blk_get_queue(sh->bh_old[i]->b_rdev);
+ generic_make_request(q, READ, sh->bh_old[i]);
+ atomic_dec(&sh->bh_old[i]->b_count);
+ }
+ PRINTK("handle_stripe() %lu, phase READ_OLD, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+ return;
+ }
+ sh->phase = PHASE_READ;
+ for (i = 0; i < disks; i++) {
+ if (!sh->bh_new[i])
+ continue;
+ if (sh->bh_old[i]) {
+ memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
+ continue;
+ }
+#if RAID5_PARANOIA
+ if (sh->bh_req[i] == NULL || test_bit(BH_Lock, &sh->bh_req[i]->b_state)) {
+ int j;
+ printk("req %d is NULL! or locked \n", i);
+ for (j=0; j<disks; j++) {
+ printk("%d: new=%p old=%p req=%p new=%d cmd=%d\n",
+ j, sh->bh_new[j], sh->bh_old[j], sh->bh_req[j],
+ sh->new[j], sh->cmd_new[j]);
+ }
+
+ }
+#endif
+ lock_get_bh(sh->bh_req[i]);
+ atomic_inc(&sh->nr_pending);
+ sh->bh_req[i]->b_rdev = conf->disks[i].dev;
+ q = blk_get_queue(sh->bh_req[i]->b_rdev);
+ generic_make_request(q, READ, sh->bh_req[i]);
+ atomic_dec(&sh->bh_req[i]->b_count);
+ }
+ PRINTK("handle_stripe() %lu, phase READ, pending %d\n", sh->sector, md_atomic_read(&sh->nr_pending));
+}
+
+/*
+ * Syncing
+ */
+static void handle_stripe_sync (mddev_t *mddev , raid5_conf_t *conf,
+ struct stripe_head *sh, int * operational, int disks,
+ int parity, int parity_failed, int nr_cache, int nr_cache_other,
+ int nr_failed_other, int nr_cache_overwrite, int nr_failed_overwrite)
+{
+ request_queue_t *q;
+ struct buffer_head *bh;
+ int i, pd_idx;
+
+ /* firstly, we want to have data from all non-failed drives
+ * in bh_old
+ */
+ PRINTK("handle_stripe_sync: sec=%lu disks=%d nr_cache=%d\n", sh->sector, disks, nr_cache);
+ if (nr_cache < disks-1
+ || (nr_cache==disks-1 && !(parity_failed+nr_failed_other+nr_failed_overwrite))
+ ) {
+ sh->phase = PHASE_READ_OLD;
+ for (i = 0; i < disks; i++) {
+ if (sh->bh_old[i])
+ continue;
+ if (!conf->disks[i].operational)
+ continue;
+
+ bh = raid5_alloc_buffer(sh, sh->size);
+ sh->bh_old[i] = bh;
+ raid5_build_block(sh, bh, i);
+ lock_get_bh(bh);
+ atomic_inc(&sh->nr_pending);
+ bh->b_rdev = conf->disks[i].dev;
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, READ, bh);
+ drive_stat_acct(bh->b_rdev, READ, -bh->b_size/512, 0);
+ atomic_dec(&sh->bh_old[i]->b_count);
+ }
+ PRINTK("handle_stripe_sync() %lu, phase READ_OLD, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+
+ return;
+ }
+ /* now, if there is a failed drive, rebuild and write to spare */
+ if (nr_cache == disks-1) {
+ sh->phase = PHASE_WRITE;
+ /* we can generate the missing block, which will be on the failed drive */
+ for (i=0; i<disks; i++) {
+ if (operational[i])
+ continue;
+ compute_block(sh, i);
+ if (conf->spare) {
+ bh = sh->bh_copy[i];
+ if (bh) {
+ memcpy(bh->b_data, sh->bh_old[i]->b_data, sh->size);
+ set_bit(BH_Uptodate, &bh->b_state);
+ } else {
+ bh = sh->bh_old[i];
+ sh->bh_old[i] = NULL;
+ sh->bh_copy[i] = bh;
+ }
+ atomic_inc(&sh->nr_pending);
+ lock_get_bh(bh);
+ bh->b_rdev = conf->spare->dev;
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, WRITERAW, bh);
+ drive_stat_acct(bh->b_rdev, WRITE, -bh->b_size/512, 0);
+ atomic_dec(&bh->b_count);
+ PRINTK("handle_stripe_sync() %lu, phase WRITE, pending %d buffers\n", sh->sector, md_atomic_read(&sh->nr_pending));
+ }
+ break;
+ }
+ return;
+ }
+
+ /* nr_cache == disks:
+ * check parity and compute/write if needed
+ */
+
+ compute_parity(sh, RECONSTRUCT_WRITE);
+ pd_idx = sh->pd_idx;
+ if (!memcmp(sh->bh_copy[pd_idx]->b_data, sh->bh_old[pd_idx]->b_data, sh->size)) {
+ /* the parity is correct - Yay! */
+ complete_stripe(sh);
+ } else {
+ sh->phase = PHASE_WRITE;
+ bh = sh->bh_copy[pd_idx];
+ atomic_set_buffer_dirty(bh);
+ lock_get_bh(bh);
+ atomic_inc(&sh->nr_pending);
+ bh->b_rdev = conf->disks[pd_idx].dev;
+ q = blk_get_queue(bh->b_rdev);
+ generic_make_request(q, WRITERAW, bh);
+ drive_stat_acct(bh->b_rdev, WRITE, -bh->b_size/512, 0);
+ atomic_dec(&bh->b_count);
+ PRINTK("handle_stripe_sync() %lu phase WRITE, pending %d buffers\n",
+ sh->sector, md_atomic_read(&sh->nr_pending));
+ }
+}
+
/*
* handle_stripe() is our main logic routine. Note that:
*
@@ -921,45 +1344,39 @@ static void complete_stripe(struct stripe_head *sh)
* 2. We should be careful to set sh->nr_pending whenever we sleep,
* to prevent re-entry of handle_stripe() for the same sh.
*
- * 3. raid_conf->failed_disks and disk->operational can be changed
+ * 3. conf->failed_disks and disk->operational can be changed
* from an interrupt. This complicates things a bit, but it allows
* us to stop issuing requests for a failed drive as soon as possible.
*/
static void handle_stripe(struct stripe_head *sh)
{
- struct raid5_data *raid_conf = sh->raid_conf;
- struct md_dev *mddev = raid_conf->mddev;
- int minor = (int) (mddev - md_dev);
- struct buffer_head *bh;
- int disks = raid_conf->raid_disks;
- int i, nr = 0, nr_read = 0, nr_write = 0;
- int nr_cache = 0, nr_cache_other = 0, nr_cache_overwrite = 0, parity = 0;
+ raid5_conf_t *conf = sh->raid_conf;
+ mddev_t *mddev = conf->mddev;
+ int disks = conf->raid_disks;
+ int i, nr_read = 0, nr_write = 0, parity = 0;
+ int nr_cache = 0, nr_cache_other = 0, nr_cache_overwrite = 0;
int nr_failed_other = 0, nr_failed_overwrite = 0, parity_failed = 0;
- int reading = 0, nr_writing = 0;
- int method1 = INT_MAX, method2 = INT_MAX;
- int block;
- unsigned long flags;
- int operational[MD_SB_DISKS], failed_disks = raid_conf->failed_disks;
+ int operational[MD_SB_DISKS], failed_disks = conf->failed_disks;
- PRINTK(("handle_stripe(), stripe %lu\n", sh->sector));
- if (sh->nr_pending) {
- printk("handle_stripe(), stripe %lu, io still pending\n", sh->sector);
- return;
- }
- if (sh->phase == PHASE_COMPLETE) {
- printk("handle_stripe(), stripe %lu, already complete\n", sh->sector);
- return;
- }
+ PRINTK("handle_stripe(), stripe %lu\n", sh->sector);
+ if (!stripe_locked(sh))
+ BUG();
+ if (md_atomic_read(&sh->nr_pending))
+ BUG();
+ if (sh->phase == PHASE_COMPLETE)
+ BUG();
- atomic_dec(&raid_conf->nr_handle);
+ atomic_dec(&conf->nr_handle);
- if (test_and_clear_bit(STRIPE_ERROR, &sh->state)) {
+ if (md_test_and_clear_bit(STRIPE_ERROR, &sh->state)) {
printk("raid5: restarting stripe %lu\n", sh->sector);
sh->phase = PHASE_BEGIN;
}
if ((sh->cmd == STRIPE_WRITE && sh->phase == PHASE_WRITE) ||
- (sh->cmd == STRIPE_READ && sh->phase == PHASE_READ)) {
+ (sh->cmd == STRIPE_READ && sh->phase == PHASE_READ) ||
+ (sh->cmd == STRIPE_SYNC && sh->phase == PHASE_WRITE)
+ ) {
/*
* Completed
*/
@@ -968,16 +1385,18 @@ static void handle_stripe(struct stripe_head *sh)
return;
}
- save_flags(flags);
- cli();
+ md_spin_lock_irq(&conf->device_lock);
for (i = 0; i < disks; i++) {
- operational[i] = raid_conf->disks[i].operational;
- if (i == sh->pd_idx && raid_conf->resync_parity)
+ operational[i] = conf->disks[i].operational;
+ if (i == sh->pd_idx && conf->resync_parity)
operational[i] = 0;
}
- failed_disks = raid_conf->failed_disks;
- restore_flags(flags);
+ failed_disks = conf->failed_disks;
+ md_spin_unlock_irq(&conf->device_lock);
+ /*
+ * Make this one more graceful?
+ */
if (failed_disks > 1) {
for (i = 0; i < disks; i++) {
if (sh->bh_new[i]) {
@@ -985,267 +1404,184 @@ static void handle_stripe(struct stripe_head *sh)
continue;
}
}
- finish_stripe(sh);
+ if (sh->cmd == STRIPE_SYNC)
+ md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
+ finish_unlock_stripe(sh);
return;
}
+ PRINTK("=== stripe index START ===\n");
for (i = 0; i < disks; i++) {
- if (sh->bh_old[i])
+ PRINTK("disk %d, ", i);
+ if (sh->bh_old[i]) {
nr_cache++;
+ PRINTK(" (old cached, %d)", nr_cache);
+ }
if (i == sh->pd_idx) {
- if (sh->bh_old[i])
+ PRINTK(" PARITY.");
+ if (sh->bh_old[i]) {
+ PRINTK(" CACHED.");
parity = 1;
- else if(!operational[i])
- parity_failed = 1;
+ } else {
+ PRINTK(" UNCACHED.");
+ if (!operational[i]) {
+ PRINTK(" FAILED.");
+ parity_failed = 1;
+ }
+ }
+ PRINTK("\n");
continue;
}
if (!sh->bh_new[i]) {
- if (sh->bh_old[i])
+ PRINTK(" (no new data block) ");
+ if (sh->bh_old[i]) {
+ PRINTK(" (but old block cached) ");
nr_cache_other++;
- else if (!operational[i])
- nr_failed_other++;
+ } else {
+ if (!operational[i]) {
+ PRINTK(" (because failed disk) ");
+ nr_failed_other++;
+ } else
+ PRINTK(" (no old block either) ");
+ }
+ PRINTK("\n");
continue;
}
sh->new[i] = 0;
- nr++;
- if (sh->cmd_new[i] == READ)
+ if (sh->cmd_new[i] == READ) {
nr_read++;
- if (sh->cmd_new[i] == WRITE)
- nr_write++;
- if (sh->bh_old[i])
- nr_cache_overwrite++;
- else if (!operational[i])
- nr_failed_overwrite++;
- }
-
- if (nr_write && nr_read)
- printk("raid5: bug, nr_write == %d, nr_read == %d, sh->cmd == %d\n", nr_write, nr_read, sh->cmd);
-
- if (nr_write) {
- /*
- * Attempt to add entries :-)
- */
- if (nr_write != disks - 1) {
- for (i = 0; i < disks; i++) {
- if (i == sh->pd_idx)
- continue;
- if (sh->bh_new[i])
- continue;
- block = (int) compute_blocknr(sh, i);
- bh = get_hash_table(MKDEV(MD_MAJOR, minor), block, sh->size);
- if (bh) {
- if (atomic_read(&bh->b_count) == 1 &&
- buffer_dirty(bh) &&
- !buffer_locked(bh)) {
- PRINTK(("Whee.. sector %lu, index %d (%d) found in the buffer cache!\n", sh->sector, i, block));
- add_stripe_bh(sh, bh, i, WRITE);
- sh->new[i] = 0;
- nr++; nr_write++;
- if (sh->bh_old[i]) {
- nr_cache_overwrite++;
- nr_cache_other--;
- } else if (!operational[i]) {
- nr_failed_overwrite++;
- nr_failed_other--;
- }
- }
- atomic_dec(&bh->b_count);
- }
- }
+ PRINTK(" (new READ %d)", nr_read);
}
- PRINTK(("handle_stripe() -- begin writing, stripe %lu\n", sh->sector));
- /*
- * Writing, need to update parity buffer.
- *
- * Compute the number of I/O requests in the "reconstruct
- * write" and "read modify write" methods.
- */
- if (!nr_failed_other)
- method1 = (disks - 1) - (nr_write + nr_cache_other);
- if (!nr_failed_overwrite && !parity_failed)
- method2 = nr_write - nr_cache_overwrite + (1 - parity);
-
- if (method1 == INT_MAX && method2 == INT_MAX)
- printk("raid5: bug: method1 == method2 == INT_MAX\n");
- PRINTK(("handle_stripe(), sector %lu, nr_write %d, method1 %d, method2 %d\n", sh->sector, nr_write, method1, method2));
-
- if (!method1 || !method2) {
- lock_stripe(sh);
- sh->nr_pending++;
- sh->phase = PHASE_WRITE;
- compute_parity(sh, method1 <= method2 ? RECONSTRUCT_WRITE : READ_MODIFY_WRITE);
- for (i = 0; i < disks; i++) {
- if (!operational[i] && !raid_conf->spare && !raid_conf->resync_parity)
- continue;
- if (i == sh->pd_idx || sh->bh_new[i])
- nr_writing++;
- }
-
- sh->nr_pending = nr_writing;
- PRINTK(("handle_stripe() %lu, writing back %d\n", sh->sector, sh->nr_pending));
-
- for (i = 0; i < disks; i++) {
- if (!operational[i] && !raid_conf->spare && !raid_conf->resync_parity)
- continue;
- bh = sh->bh_copy[i];
- if (i != sh->pd_idx && ((bh == NULL) ^ (sh->bh_new[i] == NULL)))
- printk("raid5: bug: bh == %p, bh_new[%d] == %p\n", bh, i, sh->bh_new[i]);
- if (i == sh->pd_idx && !bh)
- printk("raid5: bug: bh == NULL, i == pd_idx == %d\n", i);
- if (bh) {
- bh->b_state |= (1<<BH_Dirty);
- PRINTK(("making request for buffer %d\n", i));
- clear_bit(BH_Lock, &bh->b_state);
- if (!operational[i] && !raid_conf->resync_parity) {
- bh->b_rdev = raid_conf->spare->dev;
- make_request(MAJOR(raid_conf->spare->dev), WRITE, bh);
- } else
- make_request(MAJOR(raid_conf->disks[i].dev), WRITE, bh);
- }
- }
- return;
- }
-
- lock_stripe(sh);
- sh->nr_pending++;
- if (method1 < method2) {
- sh->write_method = RECONSTRUCT_WRITE;
- for (i = 0; i < disks; i++) {
- if (i == sh->pd_idx)
- continue;
- if (sh->bh_new[i] || sh->bh_old[i])
- continue;
- sh->bh_old[i] = raid5_kmalloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[i], i);
- reading++;
- }
- } else {
- sh->write_method = READ_MODIFY_WRITE;
- for (i = 0; i < disks; i++) {
- if (sh->bh_old[i])
- continue;
- if (!sh->bh_new[i] && i != sh->pd_idx)
- continue;
- sh->bh_old[i] = raid5_kmalloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[i], i);
- reading++;
- }
- }
- sh->phase = PHASE_READ_OLD;
- sh->nr_pending = reading;
- PRINTK(("handle_stripe() %lu, reading %d old buffers\n", sh->sector, sh->nr_pending));
- for (i = 0; i < disks; i++) {
- if (!sh->bh_old[i])
- continue;
- if (buffer_uptodate(sh->bh_old[i]))
- continue;
- clear_bit(BH_Lock, &sh->bh_old[i]->b_state);
- make_request(MAJOR(raid_conf->disks[i].dev), READ, sh->bh_old[i]);
- }
- } else {
- /*
- * Reading
- */
- method1 = nr_read - nr_cache_overwrite;
- lock_stripe(sh);
- sh->nr_pending++;
-
- PRINTK(("handle_stripe(), sector %lu, nr_read %d, nr_cache %d, method1 %d\n", sh->sector, nr_read, nr_cache, method1));
- if (!method1 || (method1 == 1 && nr_cache == disks - 1)) {
- PRINTK(("read %lu completed from cache\n", sh->sector));
- for (i = 0; i < disks; i++) {
- if (!sh->bh_new[i])
- continue;
- if (!sh->bh_old[i])
- compute_block(sh, i);
- memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
- }
- sh->nr_pending--;
- complete_stripe(sh);
- return;
+ if (sh->cmd_new[i] == WRITE) {
+ nr_write++;
+ PRINTK(" (new WRITE %d)", nr_write);
}
- if (nr_failed_overwrite) {
- sh->phase = PHASE_READ_OLD;
- sh->nr_pending = (disks - 1) - nr_cache;
- PRINTK(("handle_stripe() %lu, phase READ_OLD, pending %d\n", sh->sector, sh->nr_pending));
- for (i = 0; i < disks; i++) {
- if (sh->bh_old[i])
- continue;
- if (!operational[i])
- continue;
- sh->bh_old[i] = raid5_kmalloc_buffer(sh, sh->size);
- raid5_build_block(sh, sh->bh_old[i], i);
- clear_bit(BH_Lock, &sh->bh_old[i]->b_state);
- make_request(MAJOR(raid_conf->disks[i].dev), READ, sh->bh_old[i]);
- }
+ if (sh->bh_old[i]) {
+ nr_cache_overwrite++;
+ PRINTK(" (overwriting old %d)", nr_cache_overwrite);
} else {
- sh->phase = PHASE_READ;
- sh->nr_pending = nr_read - nr_cache_overwrite;
- PRINTK(("handle_stripe() %lu, phase READ, pending %d\n", sh->sector, sh->nr_pending));
- for (i = 0; i < disks; i++) {
- if (!sh->bh_new[i])
- continue;
- if (sh->bh_old[i]) {
- memcpy(sh->bh_new[i]->b_data, sh->bh_old[i]->b_data, sh->size);
- continue;
- }
- make_request(MAJOR(raid_conf->disks[i].dev), READ, sh->bh_req[i]);
+ if (!operational[i]) {
+ nr_failed_overwrite++;
+ PRINTK(" (overwriting failed %d)", nr_failed_overwrite);
}
}
+ PRINTK("\n");
}
+ PRINTK("=== stripe index END ===\n");
+
+ if (nr_write && nr_read)
+ BUG();
+
+ if (nr_write)
+ handle_stripe_write(
+ mddev, conf, sh, nr_write, operational, disks,
+ parity, parity_failed, nr_cache, nr_cache_other,
+ nr_failed_other, nr_cache_overwrite,
+ nr_failed_overwrite
+ );
+ else if (nr_read)
+ handle_stripe_read(
+ mddev, conf, sh, nr_read, operational, disks,
+ parity, parity_failed, nr_cache, nr_cache_other,
+ nr_failed_other, nr_cache_overwrite,
+ nr_failed_overwrite
+ );
+ else if (sh->cmd == STRIPE_SYNC)
+ handle_stripe_sync(
+ mddev, conf, sh, operational, disks,
+ parity, parity_failed, nr_cache, nr_cache_other,
+ nr_failed_other, nr_cache_overwrite, nr_failed_overwrite
+ );
}
-static int raid5_make_request (struct md_dev *mddev, int rw, struct buffer_head * bh)
+
+static int raid5_make_request (request_queue_t *q, mddev_t *mddev, int rw, struct buffer_head * bh)
{
- struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
- const unsigned int raid_disks = raid_conf->raid_disks;
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+ const unsigned int raid_disks = conf->raid_disks;
const unsigned int data_disks = raid_disks - 1;
unsigned int dd_idx, pd_idx;
unsigned long new_sector;
struct stripe_head *sh;
- if (rw == READA) rw = READ;
+ if (rw == READA)
+ rw = READ;
- new_sector = raid5_compute_sector(bh->b_rsector, raid_disks, data_disks,
- &dd_idx, &pd_idx, raid_conf);
+ new_sector = raid5_compute_sector(bh->b_blocknr*(bh->b_size>>9),
+ raid_disks, data_disks, &dd_idx, &pd_idx, conf);
- PRINTK(("raid5_make_request, sector %lu\n", new_sector));
-repeat:
- sh = get_stripe(raid_conf, new_sector, bh->b_size);
+ PRINTK("raid5_make_request, sector %lu\n", new_sector);
+ sh = get_lock_stripe(conf, new_sector, bh->b_size);
+#if 0
if ((rw == READ && sh->cmd == STRIPE_WRITE) || (rw == WRITE && sh->cmd == STRIPE_READ)) {
- PRINTK(("raid5: lock contention, rw == %d, sh->cmd == %d\n", rw, sh->cmd));
+ PRINTK("raid5: lock contention, rw == %d, sh->cmd == %d\n", rw, sh->cmd);
lock_stripe(sh);
- if (!sh->nr_pending)
+ if (!md_atomic_read(&sh->nr_pending))
handle_stripe(sh);
goto repeat;
}
+#endif
sh->pd_idx = pd_idx;
if (sh->phase != PHASE_COMPLETE && sh->phase != PHASE_BEGIN)
- PRINTK(("stripe %lu catching the bus!\n", sh->sector));
- if (sh->bh_new[dd_idx]) {
- printk("raid5: bug: stripe->bh_new[%d], sector %lu exists\n", dd_idx, sh->sector);
- printk("raid5: bh %p, bh_new %p\n", bh, sh->bh_new[dd_idx]);
- lock_stripe(sh);
- md_wakeup_thread(raid_conf->thread);
- wait_on_stripe(sh);
- goto repeat;
- }
+ PRINTK("stripe %lu catching the bus!\n", sh->sector);
+ if (sh->bh_new[dd_idx])
+ BUG();
add_stripe_bh(sh, bh, dd_idx, rw);
- md_wakeup_thread(raid_conf->thread);
+ md_wakeup_thread(conf->thread);
return 0;
}
-static void unplug_devices(struct stripe_head *sh)
+/*
+ * Determine correct block size for this device.
+ */
+unsigned int device_bsize (kdev_t dev)
{
-#if 0
- struct raid5_data *raid_conf = sh->raid_conf;
- int i;
+ unsigned int i, correct_size;
- for (i = 0; i < raid_conf->raid_disks; i++)
- unplug_device(blk_dev + MAJOR(raid_conf->disks[i].dev));
-#endif
+ correct_size = BLOCK_SIZE;
+ if (blksize_size[MAJOR(dev)]) {
+ i = blksize_size[MAJOR(dev)][MINOR(dev)];
+ if (i)
+ correct_size = i;
+ }
+
+ return correct_size;
+}
+
+static int raid5_sync_request (mddev_t *mddev, unsigned long block_nr)
+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+ struct stripe_head *sh;
+ int sectors_per_chunk = conf->chunk_size >> 9;
+ unsigned long stripe = (block_nr<<2)/sectors_per_chunk;
+ int chunk_offset = (block_nr<<2) % sectors_per_chunk;
+ int dd_idx, pd_idx;
+ unsigned long first_sector;
+ int raid_disks = conf->raid_disks;
+ int data_disks = raid_disks-1;
+ int redone = 0;
+ int bufsize;
+
+ if (!conf->buffer_size)
+ conf->buffer_size = /* device_bsize(mddev_to_kdev(mddev))*/ PAGE_SIZE;
+ bufsize = conf->buffer_size;
+ /* Hmm... race on buffer_size ?? */
+ redone = block_nr% (bufsize>>10);
+ block_nr -= redone;
+ sh = get_lock_stripe(conf, block_nr<<1, bufsize);
+ first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk+chunk_offset,
+ raid_disks, data_disks,
+ &dd_idx, &pd_idx, conf);
+ sh->pd_idx = pd_idx;
+ sh->cmd = STRIPE_SYNC;
+ sh->phase = PHASE_BEGIN;
+ sh->sync_redone = redone;
+ atomic_inc(&conf->nr_pending_stripes);
+ atomic_inc(&conf->nr_handle);
+ md_wakeup_thread(conf->thread);
+ return (bufsize>>10)-redone;
}
/*
@@ -1258,56 +1594,53 @@ static void unplug_devices(struct stripe_head *sh)
static void raid5d (void *data)
{
struct stripe_head *sh;
- struct raid5_data *raid_conf = data;
- struct md_dev *mddev = raid_conf->mddev;
- int i, handled = 0, unplug = 0;
- unsigned long flags;
+ raid5_conf_t *conf = data;
+ mddev_t *mddev = conf->mddev;
+ int i, handled;
- PRINTK(("+++ raid5d active\n"));
+ PRINTK("+++ raid5d active\n");
+ handled = 0;
+ md_spin_lock_irq(&conf->device_lock);
+ clear_bit(THREAD_WAKEUP, &conf->thread->flags);
+repeat_pass:
if (mddev->sb_dirty) {
+ md_spin_unlock_irq(&conf->device_lock);
mddev->sb_dirty = 0;
- md_update_sb((int) (mddev - md_dev));
+ md_update_sb(mddev);
+ md_spin_lock_irq(&conf->device_lock);
}
for (i = 0; i < NR_HASH; i++) {
repeat:
- sh = raid_conf->stripe_hashtbl[i];
+ sh = conf->stripe_hashtbl[i];
for (; sh; sh = sh->hash_next) {
- if (sh->raid_conf != raid_conf)
+ if (sh->raid_conf != conf)
continue;
if (sh->phase == PHASE_COMPLETE)
continue;
- if (sh->nr_pending)
+ if (md_atomic_read(&sh->nr_pending))
continue;
- if (sh->sector == raid_conf->next_sector) {
- raid_conf->sector_count += (sh->size >> 9);
- if (raid_conf->sector_count >= 128)
- unplug = 1;
- } else
- unplug = 1;
- if (unplug) {
- PRINTK(("unplugging devices, sector == %lu, count == %d\n", sh->sector, raid_conf->sector_count));
- unplug_devices(sh);
- unplug = 0;
- raid_conf->sector_count = 0;
- }
- raid_conf->next_sector = sh->sector + (sh->size >> 9);
+ md_spin_unlock_irq(&conf->device_lock);
+ if (!atomic_read(&sh->count))
+ BUG();
+
handled++;
handle_stripe(sh);
+ md_spin_lock_irq(&conf->device_lock);
goto repeat;
}
}
- if (raid_conf) {
- PRINTK(("%d stripes handled, nr_handle %d\n", handled, atomic_read(&raid_conf->nr_handle)));
- save_flags(flags);
- cli();
- if (!atomic_read(&raid_conf->nr_handle))
- clear_bit(THREAD_WAKEUP, &raid_conf->thread->flags);
+ if (conf) {
+ PRINTK("%d stripes handled, nr_handle %d\n", handled, md_atomic_read(&conf->nr_handle));
+ if (test_and_clear_bit(THREAD_WAKEUP, &conf->thread->flags) &&
+ md_atomic_read(&conf->nr_handle))
+ goto repeat_pass;
}
- PRINTK(("--- raid5d inactive\n"));
+ md_spin_unlock_irq(&conf->device_lock);
+
+ PRINTK("--- raid5d inactive\n");
}
-#if SUPPORT_RECONSTRUCTION
/*
* Private kernel thread for parity reconstruction after an unclean
* shutdown. Reconstruction on spare drives in case of a failed drive
@@ -1315,44 +1648,68 @@ repeat:
*/
static void raid5syncd (void *data)
{
- struct raid5_data *raid_conf = data;
- struct md_dev *mddev = raid_conf->mddev;
+ raid5_conf_t *conf = data;
+ mddev_t *mddev = conf->mddev;
- if (!raid_conf->resync_parity)
+ if (!conf->resync_parity)
+ return;
+ if (conf->resync_parity == 2)
return;
- md_do_sync(mddev);
- raid_conf->resync_parity = 0;
+ down(&mddev->recovery_sem);
+ if (md_do_sync(mddev,NULL)) {
+ up(&mddev->recovery_sem);
+ printk("raid5: resync aborted!\n");
+ return;
+ }
+ conf->resync_parity = 0;
+ up(&mddev->recovery_sem);
+ printk("raid5: resync finished.\n");
}
-#endif /* SUPPORT_RECONSTRUCTION */
-static int __check_consistency (struct md_dev *mddev, int row)
+static int __check_consistency (mddev_t *mddev, int row)
{
- struct raid5_data *raid_conf = mddev->private;
+ raid5_conf_t *conf = mddev->private;
kdev_t dev;
- struct buffer_head *bh[MD_SB_DISKS], tmp;
- int i, rc = 0, nr = 0;
-
- if (raid_conf->working_disks != raid_conf->raid_disks)
- return 0;
- tmp.b_size = 4096;
- if ((tmp.b_data = (char *) get_free_page(GFP_KERNEL)) == NULL)
- return 0;
+ struct buffer_head *bh[MD_SB_DISKS], *tmp = NULL;
+ int i, ret = 0, nr = 0, count;
+ struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
+
+ if (conf->working_disks != conf->raid_disks)
+ goto out;
+ tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
+ tmp->b_size = 4096;
+ tmp->b_page = alloc_page(GFP_KERNEL);
+ tmp->b_data = (char *)page_address(tmp->b_page);
+ if (!tmp->b_data)
+ goto out;
+ md_clear_page((unsigned long)tmp->b_data);
memset(bh, 0, MD_SB_DISKS * sizeof(struct buffer_head *));
- for (i = 0; i < raid_conf->raid_disks; i++) {
- dev = raid_conf->disks[i].dev;
+ for (i = 0; i < conf->raid_disks; i++) {
+ dev = conf->disks[i].dev;
set_blocksize(dev, 4096);
- if ((bh[i] = bread(dev, row / 4, 4096)) == NULL)
+ bh[i] = bread(dev, row / 4, 4096);
+ if (!bh[i])
break;
nr++;
}
- if (nr == raid_conf->raid_disks) {
- for (i = 1; i < nr; i++)
- xor_block(&tmp, bh[i]);
- if (memcmp(tmp.b_data, bh[0]->b_data, 4096))
- rc = 1;
+ if (nr == conf->raid_disks) {
+ bh_ptr[0] = tmp;
+ count = 1;
+ for (i = 1; i < nr; i++) {
+ bh_ptr[count++] = bh[i];
+ if (count == MAX_XOR_BLOCKS) {
+ xor_block(count, &bh_ptr[0]);
+ count = 1;
+ }
+ }
+ if (count != 1) {
+ xor_block(count, &bh_ptr[0]);
+ }
+ if (memcmp(tmp->b_data, bh[0]->b_data, 4096))
+ ret = 1;
}
- for (i = 0; i < raid_conf->raid_disks; i++) {
- dev = raid_conf->disks[i].dev;
+ for (i = 0; i < conf->raid_disks; i++) {
+ dev = conf->disks[i].dev;
if (bh[i]) {
bforget(bh[i]);
bh[i] = NULL;
@@ -1360,308 +1717,691 @@ static int __check_consistency (struct md_dev *mddev, int row)
fsync_dev(dev);
invalidate_buffers(dev);
}
- free_page((unsigned long) tmp.b_data);
- return rc;
+ free_page((unsigned long) tmp->b_data);
+out:
+ if (tmp)
+ kfree(tmp);
+ return ret;
}
-static int check_consistency (struct md_dev *mddev)
+static int check_consistency (mddev_t *mddev)
{
- int size = mddev->sb->size;
- int row;
+ if (__check_consistency(mddev, 0))
+/*
+ * We are not checking this currently, as it's legitimate to have
+ * an inconsistent array, at creation time.
+ */
+ return 0;
- for (row = 0; row < size; row += size / 8)
- if (__check_consistency(mddev, row))
- return 1;
return 0;
}
-static int raid5_run (int minor, struct md_dev *mddev)
+static int raid5_run (mddev_t *mddev)
{
- struct raid5_data *raid_conf;
+ raid5_conf_t *conf;
int i, j, raid_disk, memory;
- md_superblock_t *sb = mddev->sb;
- md_descriptor_t *descriptor;
- struct real_dev *realdev;
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *desc;
+ mdk_rdev_t *rdev;
+ struct disk_info *disk;
+ struct md_list_head *tmp;
+ int start_recovery = 0;
MOD_INC_USE_COUNT;
if (sb->level != 5 && sb->level != 4) {
- printk("raid5: %s: raid level not set to 4/5 (%d)\n", kdevname(MKDEV(MD_MAJOR, minor)), sb->level);
+ printk("raid5: md%d: raid level not set to 4/5 (%d)\n", mdidx(mddev), sb->level);
MOD_DEC_USE_COUNT;
return -EIO;
}
- mddev->private = kmalloc (sizeof (struct raid5_data), GFP_KERNEL);
- if ((raid_conf = mddev->private) == NULL)
+ mddev->private = kmalloc (sizeof (raid5_conf_t), GFP_KERNEL);
+ if ((conf = mddev->private) == NULL)
goto abort;
- memset (raid_conf, 0, sizeof (*raid_conf));
- raid_conf->mddev = mddev;
+ memset (conf, 0, sizeof (*conf));
+ conf->mddev = mddev;
- if ((raid_conf->stripe_hashtbl = (struct stripe_head **) __get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
+ if ((conf->stripe_hashtbl = (struct stripe_head **) md__get_free_pages(GFP_ATOMIC, HASH_PAGES_ORDER)) == NULL)
goto abort;
- memset(raid_conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
+ memset(conf->stripe_hashtbl, 0, HASH_PAGES * PAGE_SIZE);
- init_waitqueue_head(&raid_conf->wait_for_stripe);
- PRINTK(("raid5_run(%d) called.\n", minor));
-
- for (i = 0; i < mddev->nb_dev; i++) {
- realdev = &mddev->devices[i];
- if (!realdev->sb) {
- printk(KERN_ERR "raid5: disabled device %s (couldn't access raid superblock)\n", kdevname(realdev->dev));
- continue;
- }
+ conf->device_lock = MD_SPIN_LOCK_UNLOCKED;
+ md_init_waitqueue_head(&conf->wait_for_stripe);
+ PRINTK("raid5_run(md%d) called.\n", mdidx(mddev));
+ ITERATE_RDEV(mddev,rdev,tmp) {
/*
* This is important -- we are using the descriptor on
* the disk only to get a pointer to the descriptor on
* the main superblock, which might be more recent.
*/
- descriptor = &sb->disks[realdev->sb->descriptor.number];
- if (descriptor->state & (1 << MD_FAULTY_DEVICE)) {
- printk(KERN_ERR "raid5: disabled device %s (errors detected)\n", kdevname(realdev->dev));
+ desc = sb->disks + rdev->desc_nr;
+ raid_disk = desc->raid_disk;
+ disk = conf->disks + raid_disk;
+
+ if (disk_faulty(desc)) {
+ printk(KERN_ERR "raid5: disabled device %s (errors detected)\n", partition_name(rdev->dev));
+ if (!rdev->faulty) {
+ MD_BUG();
+ goto abort;
+ }
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;
+ disk->dev = rdev->dev;
+
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
continue;
}
- if (descriptor->state & (1 << MD_ACTIVE_DEVICE)) {
- if (!(descriptor->state & (1 << MD_SYNC_DEVICE))) {
- printk(KERN_ERR "raid5: disabled device %s (not in sync)\n", kdevname(realdev->dev));
- continue;
+ if (disk_active(desc)) {
+ if (!disk_sync(desc)) {
+ printk(KERN_ERR "raid5: disabled device %s (not in sync)\n", partition_name(rdev->dev));
+ MD_BUG();
+ goto abort;
}
- raid_disk = descriptor->raid_disk;
- if (descriptor->number > sb->nr_disks || raid_disk > sb->raid_disks) {
- printk(KERN_ERR "raid5: disabled device %s (inconsistent descriptor)\n", kdevname(realdev->dev));
+ if (raid_disk > sb->raid_disks) {
+ printk(KERN_ERR "raid5: disabled device %s (inconsistent descriptor)\n", partition_name(rdev->dev));
continue;
}
- if (raid_conf->disks[raid_disk].operational) {
- printk(KERN_ERR "raid5: disabled device %s (device %d already operational)\n", kdevname(realdev->dev), raid_disk);
+ if (disk->operational) {
+ printk(KERN_ERR "raid5: disabled device %s (device %d already operational)\n", partition_name(rdev->dev), raid_disk);
continue;
}
- printk(KERN_INFO "raid5: device %s operational as raid disk %d\n", kdevname(realdev->dev), raid_disk);
+ printk(KERN_INFO "raid5: device %s operational as raid disk %d\n", partition_name(rdev->dev), raid_disk);
- raid_conf->disks[raid_disk].number = descriptor->number;
- raid_conf->disks[raid_disk].raid_disk = raid_disk;
- raid_conf->disks[raid_disk].dev = mddev->devices[i].dev;
- raid_conf->disks[raid_disk].operational = 1;
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;
+ disk->dev = rdev->dev;
+ disk->operational = 1;
+ disk->used_slot = 1;
- raid_conf->working_disks++;
+ conf->working_disks++;
} else {
/*
* Must be a spare disk ..
*/
- printk(KERN_INFO "raid5: spare disk %s\n", kdevname(realdev->dev));
- raid_disk = descriptor->raid_disk;
- raid_conf->disks[raid_disk].number = descriptor->number;
- raid_conf->disks[raid_disk].raid_disk = raid_disk;
- raid_conf->disks[raid_disk].dev = mddev->devices [i].dev;
-
- raid_conf->disks[raid_disk].operational = 0;
- raid_conf->disks[raid_disk].write_only = 0;
- raid_conf->disks[raid_disk].spare = 1;
- }
- }
- raid_conf->raid_disks = sb->raid_disks;
- raid_conf->failed_disks = raid_conf->raid_disks - raid_conf->working_disks;
- raid_conf->mddev = mddev;
- raid_conf->chunk_size = sb->chunk_size;
- raid_conf->level = sb->level;
- raid_conf->algorithm = sb->parity_algorithm;
- raid_conf->max_nr_stripes = NR_STRIPES;
-
- if (raid_conf->working_disks != sb->raid_disks && sb->state != (1 << MD_SB_CLEAN)) {
- printk(KERN_ALERT "raid5: raid set %s not clean and not all disks are operational -- run ckraid\n", kdevname(MKDEV(MD_MAJOR, minor)));
- goto abort;
+ printk(KERN_INFO "raid5: spare disk %s\n", partition_name(rdev->dev));
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;
+ disk->dev = rdev->dev;
+
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 1;
+ disk->used_slot = 1;
+ }
}
- if (!raid_conf->chunk_size || raid_conf->chunk_size % 4) {
- printk(KERN_ERR "raid5: invalid chunk size %d for %s\n", raid_conf->chunk_size, kdevname(MKDEV(MD_MAJOR, minor)));
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ desc = sb->disks + i;
+ raid_disk = desc->raid_disk;
+ disk = conf->disks + raid_disk;
+
+ if (disk_faulty(desc) && (raid_disk < sb->raid_disks) &&
+ !conf->disks[raid_disk].used_slot) {
+
+ disk->number = desc->number;
+ disk->raid_disk = raid_disk;
+ disk->dev = MKDEV(0,0);
+
+ disk->operational = 0;
+ disk->write_only = 0;
+ disk->spare = 0;
+ disk->used_slot = 1;
+ }
+ }
+
+ conf->raid_disks = sb->raid_disks;
+ /*
+ * 0 for a fully functional array, 1 for a degraded array.
+ */
+ conf->failed_disks = conf->raid_disks - conf->working_disks;
+ conf->mddev = mddev;
+ conf->chunk_size = sb->chunk_size;
+ conf->level = sb->level;
+ conf->algorithm = sb->layout;
+ conf->max_nr_stripes = NR_STRIPES;
+
+#if 0
+ for (i = 0; i < conf->raid_disks; i++) {
+ if (!conf->disks[i].used_slot) {
+ MD_BUG();
+ goto abort;
+ }
+ }
+#endif
+ if (!conf->chunk_size || conf->chunk_size % 4) {
+ printk(KERN_ERR "raid5: invalid chunk size %d for md%d\n", conf->chunk_size, mdidx(mddev));
goto abort;
}
- if (raid_conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
- printk(KERN_ERR "raid5: unsupported parity algorithm %d for %s\n", raid_conf->algorithm, kdevname(MKDEV(MD_MAJOR, minor)));
+ if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
+ printk(KERN_ERR "raid5: unsupported parity algorithm %d for md%d\n", conf->algorithm, mdidx(mddev));
goto abort;
}
- if (raid_conf->failed_disks > 1) {
- printk(KERN_ERR "raid5: not enough operational devices for %s (%d/%d failed)\n", kdevname(MKDEV(MD_MAJOR, minor)), raid_conf->failed_disks, raid_conf->raid_disks);
+ if (conf->failed_disks > 1) {
+ printk(KERN_ERR "raid5: not enough operational devices for md%d (%d/%d failed)\n", mdidx(mddev), conf->failed_disks, conf->raid_disks);
goto abort;
}
- if ((sb->state & (1 << MD_SB_CLEAN)) && check_consistency(mddev)) {
- printk(KERN_ERR "raid5: detected raid-5 xor inconsistenty -- run ckraid\n");
- sb->state |= 1 << MD_SB_ERRORS;
- goto abort;
+ if (conf->working_disks != sb->raid_disks) {
+ printk(KERN_ALERT "raid5: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));
+ start_recovery = 1;
}
- if ((raid_conf->thread = md_register_thread(raid5d, raid_conf)) == NULL) {
- printk(KERN_ERR "raid5: couldn't allocate thread for %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
- goto abort;
+ if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN)) &&
+ check_consistency(mddev)) {
+ printk(KERN_ERR "raid5: detected raid-5 superblock xor inconsistency -- running resync\n");
+ sb->state &= ~(1 << MD_SB_CLEAN);
}
-#if SUPPORT_RECONSTRUCTION
- if ((raid_conf->resync_thread = md_register_thread(raid5syncd, raid_conf)) == NULL) {
- printk(KERN_ERR "raid5: couldn't allocate thread for %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
- goto abort;
+ {
+ const char * name = "raid5d";
+
+ conf->thread = md_register_thread(raid5d, conf, name);
+ if (!conf->thread) {
+ printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));
+ goto abort;
+ }
}
-#endif /* SUPPORT_RECONSTRUCTION */
- memory = raid_conf->max_nr_stripes * (sizeof(struct stripe_head) +
- raid_conf->raid_disks * (sizeof(struct buffer_head) +
+ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+ conf->raid_disks * (sizeof(struct buffer_head) +
2 * (sizeof(struct buffer_head) + PAGE_SIZE))) / 1024;
- if (grow_stripes(raid_conf, raid_conf->max_nr_stripes, GFP_KERNEL)) {
+ if (grow_stripes(conf, conf->max_nr_stripes, GFP_KERNEL)) {
printk(KERN_ERR "raid5: couldn't allocate %dkB for buffers\n", memory);
- shrink_stripes(raid_conf, raid_conf->max_nr_stripes);
+ shrink_stripes(conf, conf->max_nr_stripes);
goto abort;
} else
- printk(KERN_INFO "raid5: allocated %dkB for %s\n", memory, kdevname(MKDEV(MD_MAJOR, minor)));
+ printk(KERN_INFO "raid5: allocated %dkB for md%d\n", memory, mdidx(mddev));
/*
* Regenerate the "device is in sync with the raid set" bit for
* each device.
*/
- for (i = 0; i < sb->nr_disks ; i++) {
- sb->disks[i].state &= ~(1 << MD_SYNC_DEVICE);
+ for (i = 0; i < MD_SB_DISKS ; i++) {
+ mark_disk_nonsync(sb->disks + i);
for (j = 0; j < sb->raid_disks; j++) {
- if (!raid_conf->disks[j].operational)
+ if (!conf->disks[j].operational)
continue;
- if (sb->disks[i].number == raid_conf->disks[j].number)
- sb->disks[i].state |= 1 << MD_SYNC_DEVICE;
+ if (sb->disks[i].number == conf->disks[j].number)
+ mark_disk_sync(sb->disks + i);
}
}
- sb->active_disks = raid_conf->working_disks;
+ sb->active_disks = conf->working_disks;
if (sb->active_disks == sb->raid_disks)
- printk("raid5: raid level %d set %s active with %d out of %d devices, algorithm %d\n", raid_conf->level, kdevname(MKDEV(MD_MAJOR, minor)), sb->active_disks, sb->raid_disks, raid_conf->algorithm);
+ printk("raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), sb->active_disks, sb->raid_disks, conf->algorithm);
else
- printk(KERN_ALERT "raid5: raid level %d set %s active with %d out of %d devices, algorithm %d\n", raid_conf->level, kdevname(MKDEV(MD_MAJOR, minor)), sb->active_disks, sb->raid_disks, raid_conf->algorithm);
+ printk(KERN_ALERT "raid5: raid level %d set md%d active with %d out of %d devices, algorithm %d\n", conf->level, mdidx(mddev), sb->active_disks, sb->raid_disks, conf->algorithm);
+
+ if (!start_recovery && !(sb->state & (1 << MD_SB_CLEAN))) {
+ const char * name = "raid5syncd";
+
+ conf->resync_thread = md_register_thread(raid5syncd, conf,name);
+ if (!conf->resync_thread) {
+ printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev));
+ goto abort;
+ }
- if ((sb->state & (1 << MD_SB_CLEAN)) == 0) {
- printk("raid5: raid set %s not clean; re-constructing parity\n", kdevname(MKDEV(MD_MAJOR, minor)));
- raid_conf->resync_parity = 1;
-#if SUPPORT_RECONSTRUCTION
- md_wakeup_thread(raid_conf->resync_thread);
-#endif /* SUPPORT_RECONSTRUCTION */
+ printk("raid5: raid set md%d not clean; reconstructing parity\n", mdidx(mddev));
+ conf->resync_parity = 1;
+ md_wakeup_thread(conf->resync_thread);
}
+ print_raid5_conf(conf);
+ if (start_recovery)
+ md_recover_arrays();
+ print_raid5_conf(conf);
+
/* Ok, everything is just fine now */
return (0);
abort:
- if (raid_conf) {
- if (raid_conf->stripe_hashtbl)
- free_pages((unsigned long) raid_conf->stripe_hashtbl, HASH_PAGES_ORDER);
- kfree(raid_conf);
+ if (conf) {
+ print_raid5_conf(conf);
+ if (conf->stripe_hashtbl)
+ free_pages((unsigned long) conf->stripe_hashtbl,
+ HASH_PAGES_ORDER);
+ kfree(conf);
}
mddev->private = NULL;
- printk(KERN_ALERT "raid5: failed to run raid set %s\n", kdevname(MKDEV(MD_MAJOR, minor)));
+ printk(KERN_ALERT "raid5: failed to run raid set md%d\n", mdidx(mddev));
MOD_DEC_USE_COUNT;
return -EIO;
}
-static int raid5_stop (int minor, struct md_dev *mddev)
+static int raid5_stop_resync (mddev_t *mddev)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+ mdk_thread_t *thread = conf->resync_thread;
+
+ if (thread) {
+ if (conf->resync_parity) {
+ conf->resync_parity = 2;
+ md_interrupt_thread(thread);
+ printk(KERN_INFO "raid5: parity resync was not fully finished, restarting next time.\n");
+ return 1;
+ }
+ return 0;
+ }
+ return 0;
+}
+
+static int raid5_restart_resync (mddev_t *mddev)
{
- struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
+ raid5_conf_t *conf = mddev_to_conf(mddev);
- shrink_stripe_cache(raid_conf, raid_conf->max_nr_stripes);
- shrink_stripes(raid_conf, raid_conf->max_nr_stripes);
- md_unregister_thread(raid_conf->thread);
-#if SUPPORT_RECONSTRUCTION
- md_unregister_thread(raid_conf->resync_thread);
-#endif /* SUPPORT_RECONSTRUCTION */
- free_pages((unsigned long) raid_conf->stripe_hashtbl, HASH_PAGES_ORDER);
- kfree(raid_conf);
+ if (conf->resync_parity) {
+ if (!conf->resync_thread) {
+ MD_BUG();
+ return 0;
+ }
+ printk("raid5: waking up raid5resync.\n");
+ conf->resync_parity = 1;
+ md_wakeup_thread(conf->resync_thread);
+ return 1;
+ } else
+ printk("raid5: no restart-resync needed.\n");
+ return 0;
+}
+
+
+static int raid5_stop (mddev_t *mddev)
+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+
+ shrink_stripe_cache(conf, conf->max_nr_stripes);
+ shrink_stripes(conf, conf->max_nr_stripes);
+ md_unregister_thread(conf->thread);
+ if (conf->resync_thread)
+ md_unregister_thread(conf->resync_thread);
+ free_pages((unsigned long) conf->stripe_hashtbl, HASH_PAGES_ORDER);
+ kfree(conf);
mddev->private = NULL;
MOD_DEC_USE_COUNT;
return 0;
}
-static int raid5_status (char *page, int minor, struct md_dev *mddev)
+#if RAID5_DEBUG
+static void print_sh (struct stripe_head *sh)
+{
+ int i;
+
+ printk("sh %lu, phase %d, size %d, pd_idx %d, state %ld, cmd %d.\n", sh->sector, sh->phase, sh->size, sh->pd_idx, sh->state, sh->cmd);
+ printk("sh %lu, write_method %d, nr_pending %d, count %d.\n", sh->sector, sh->write_method, atomic_read(&sh->nr_pending), atomic_read(&sh->count));
+ printk("sh %lu, ", sh->sector);
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ if (sh->bh_old[i])
+ printk("(old%d: %p) ", i, sh->bh_old[i]);
+ if (sh->bh_new[i])
+ printk("(new%d: %p) ", i, sh->bh_new[i]);
+ if (sh->bh_copy[i])
+ printk("(copy%d: %p) ", i, sh->bh_copy[i]);
+ if (sh->bh_req[i])
+ printk("(req%d: %p) ", i, sh->bh_req[i]);
+ }
+ printk("\n");
+ for (i = 0; i < MD_SB_DISKS; i++)
+ printk("%d(%d/%d) ", i, sh->cmd_new[i], sh->new[i]);
+ printk("\n");
+}
+
+static void printall (raid5_conf_t *conf)
{
- struct raid5_data *raid_conf = (struct raid5_data *) mddev->private;
- md_superblock_t *sb = mddev->sb;
+ struct stripe_head *sh;
+ int i;
+
+ md_spin_lock_irq(&conf->device_lock);
+ for (i = 0; i < NR_HASH; i++) {
+ sh = conf->stripe_hashtbl[i];
+ for (; sh; sh = sh->hash_next) {
+ if (sh->raid_conf != conf)
+ continue;
+ print_sh(sh);
+ }
+ }
+ md_spin_unlock_irq(&conf->device_lock);
+
+ PRINTK("--- raid5d inactive\n");
+}
+#endif
+
+static int raid5_status (char *page, mddev_t *mddev)
+{
+ raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
+ mdp_super_t *sb = mddev->sb;
int sz = 0, i;
- sz += sprintf (page+sz, " level %d, %dk chunk, algorithm %d", sb->level, sb->chunk_size >> 10, sb->parity_algorithm);
- sz += sprintf (page+sz, " [%d/%d] [", raid_conf->raid_disks, raid_conf->working_disks);
- for (i = 0; i < raid_conf->raid_disks; i++)
- sz += sprintf (page+sz, "%s", raid_conf->disks[i].operational ? "U" : "_");
+ sz += sprintf (page+sz, " level %d, %dk chunk, algorithm %d", sb->level, sb->chunk_size >> 10, sb->layout);
+ sz += sprintf (page+sz, " [%d/%d] [", conf->raid_disks, conf->working_disks);
+ for (i = 0; i < conf->raid_disks; i++)
+ sz += sprintf (page+sz, "%s", conf->disks[i].operational ? "U" : "_");
sz += sprintf (page+sz, "]");
+#if RAID5_DEBUG
+#define D(x) \
+ sz += sprintf (page+sz, "<"#x":%d>", atomic_read(&conf->x))
+ D(nr_handle);
+ D(nr_stripes);
+ D(nr_hashed_stripes);
+ D(nr_locked_stripes);
+ D(nr_pending_stripes);
+ D(nr_cached_stripes);
+ D(nr_free_sh);
+ printall(conf);
+#endif
return sz;
}
-static int raid5_mark_spare(struct md_dev *mddev, md_descriptor_t *spare, int state)
+static void print_raid5_conf (raid5_conf_t *conf)
{
- int i = 0, failed_disk = -1;
- struct raid5_data *raid_conf = mddev->private;
- struct disk_info *disk = raid_conf->disks;
- unsigned long flags;
- md_superblock_t *sb = mddev->sb;
- md_descriptor_t *descriptor;
+ int i;
+ struct disk_info *tmp;
- for (i = 0; i < MD_SB_DISKS; i++, disk++) {
- if (disk->spare && disk->number == spare->number)
- goto found;
+ printk("RAID5 conf printout:\n");
+ if (!conf) {
+ printk("(conf==NULL)\n");
+ return;
}
- return 1;
-found:
- for (i = 0, disk = raid_conf->disks; i < raid_conf->raid_disks; i++, disk++)
- if (!disk->operational)
- failed_disk = i;
- if (failed_disk == -1)
- return 1;
- save_flags(flags);
- cli();
+ printk(" --- rd:%d wd:%d fd:%d\n", conf->raid_disks,
+ conf->working_disks, conf->failed_disks);
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ tmp = conf->disks + i;
+ printk(" disk %d, s:%d, o:%d, n:%d rd:%d us:%d dev:%s\n",
+ i, tmp->spare,tmp->operational,
+ tmp->number,tmp->raid_disk,tmp->used_slot,
+ partition_name(tmp->dev));
+ }
+}
+
+static int raid5_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
+{
+ int err = 0;
+ int i, failed_disk=-1, spare_disk=-1, removed_disk=-1, added_disk=-1;
+ raid5_conf_t *conf = mddev->private;
+ struct disk_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
+ mdp_super_t *sb = mddev->sb;
+ mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+
+ print_raid5_conf(conf);
+ md_spin_lock_irq(&conf->device_lock);
+ /*
+ * find the disk ...
+ */
switch (state) {
- case SPARE_WRITE:
- disk->operational = 1;
- disk->write_only = 1;
- raid_conf->spare = disk;
- break;
- case SPARE_INACTIVE:
- disk->operational = 0;
- disk->write_only = 0;
- raid_conf->spare = NULL;
- break;
- case SPARE_ACTIVE:
- disk->spare = 0;
- disk->write_only = 0;
- descriptor = &sb->disks[raid_conf->disks[failed_disk].number];
- i = spare->raid_disk;
- disk->raid_disk = spare->raid_disk = descriptor->raid_disk;
- if (disk->raid_disk != failed_disk)
- printk("raid5: disk->raid_disk != failed_disk");
- descriptor->raid_disk = i;
-
- raid_conf->spare = NULL;
- raid_conf->working_disks++;
- raid_conf->failed_disks--;
- raid_conf->disks[failed_disk] = *disk;
- break;
- default:
- printk("raid5_mark_spare: bug: state == %d\n", state);
- restore_flags(flags);
- return 1;
+ case DISKOP_SPARE_ACTIVE:
+
+ /*
+ * Find the failed disk within the RAID5 configuration ...
+ * (this can only be in the first conf->raid_disks part)
+ */
+ for (i = 0; i < conf->raid_disks; i++) {
+ tmp = conf->disks + i;
+ if ((!tmp->operational && !tmp->spare) ||
+ !tmp->used_slot) {
+ failed_disk = i;
+ break;
+ }
+ }
+ /*
+ * When we activate a spare disk we _must_ have a disk in
+ * the lower (active) part of the array to replace.
+ */
+ if ((failed_disk == -1) || (failed_disk >= conf->raid_disks)) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ /* fall through */
+
+ case DISKOP_SPARE_WRITE:
+ case DISKOP_SPARE_INACTIVE:
+
+ /*
+ * Find the spare disk ... (can only be in the 'high'
+ * area of the array)
+ */
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->disks + i;
+ if (tmp->spare && tmp->number == (*d)->number) {
+ spare_disk = i;
+ break;
+ }
+ }
+ if (spare_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+
+ for (i = 0; i < MD_SB_DISKS; i++) {
+ tmp = conf->disks + i;
+ if (tmp->used_slot && (tmp->number == (*d)->number)) {
+ if (tmp->operational) {
+ err = -EBUSY;
+ goto abort;
+ }
+ removed_disk = i;
+ break;
+ }
+ }
+ if (removed_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+
+ for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
+ tmp = conf->disks + i;
+ if (!tmp->used_slot) {
+ added_disk = i;
+ break;
+ }
+ }
+ if (added_disk == -1) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ break;
}
- restore_flags(flags);
- return 0;
+
+ switch (state) {
+ /*
+ * Switch the spare disk to write-only mode:
+ */
+ case DISKOP_SPARE_WRITE:
+ if (conf->spare) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ sdisk = conf->disks + spare_disk;
+ sdisk->operational = 1;
+ sdisk->write_only = 1;
+ conf->spare = sdisk;
+ break;
+ /*
+ * Deactivate a spare disk:
+ */
+ case DISKOP_SPARE_INACTIVE:
+ sdisk = conf->disks + spare_disk;
+ sdisk->operational = 0;
+ sdisk->write_only = 0;
+ /*
+ * Was the spare being resynced?
+ */
+ if (conf->spare == sdisk)
+ conf->spare = NULL;
+ break;
+ /*
+ * Activate (mark read-write) the (now sync) spare disk,
+ * which means we switch it's 'raid position' (->raid_disk)
+ * with the failed disk. (only the first 'conf->raid_disks'
+ * slots are used for 'real' disks and we must preserve this
+ * property)
+ */
+ case DISKOP_SPARE_ACTIVE:
+ if (!conf->spare) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ sdisk = conf->disks + spare_disk;
+ fdisk = conf->disks + failed_disk;
+
+ spare_desc = &sb->disks[sdisk->number];
+ failed_desc = &sb->disks[fdisk->number];
+
+ if (spare_desc != *d) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (spare_desc->raid_disk != sdisk->raid_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (sdisk->raid_disk != spare_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (failed_desc->raid_disk != fdisk->raid_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ if (fdisk->raid_disk != failed_disk) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ /*
+ * do the switch finally
+ */
+ xchg_values(*spare_desc, *failed_desc);
+ xchg_values(*fdisk, *sdisk);
+
+ /*
+ * (careful, 'failed' and 'spare' are switched from now on)
+ *
+ * we want to preserve linear numbering and we want to
+ * give the proper raid_disk number to the now activated
+ * disk. (this means we switch back these values)
+ */
+
+ xchg_values(spare_desc->raid_disk, failed_desc->raid_disk);
+ xchg_values(sdisk->raid_disk, fdisk->raid_disk);
+ xchg_values(spare_desc->number, failed_desc->number);
+ xchg_values(sdisk->number, fdisk->number);
+
+ *d = failed_desc;
+
+ if (sdisk->dev == MKDEV(0,0))
+ sdisk->used_slot = 0;
+
+ /*
+ * this really activates the spare.
+ */
+ fdisk->spare = 0;
+ fdisk->write_only = 0;
+
+ /*
+ * if we activate a spare, we definitely replace a
+ * non-operational disk slot in the 'low' area of
+ * the disk array.
+ */
+ conf->failed_disks--;
+ conf->working_disks++;
+ conf->spare = NULL;
+
+ break;
+
+ case DISKOP_HOT_REMOVE_DISK:
+ rdisk = conf->disks + removed_disk;
+
+ if (rdisk->spare && (removed_disk < conf->raid_disks)) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+ rdisk->dev = MKDEV(0,0);
+ rdisk->used_slot = 0;
+
+ break;
+
+ case DISKOP_HOT_ADD_DISK:
+ adisk = conf->disks + added_disk;
+ added_desc = *d;
+
+ if (added_disk != added_desc->number) {
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+
+ adisk->number = added_desc->number;
+ adisk->raid_disk = added_desc->raid_disk;
+ adisk->dev = MKDEV(added_desc->major,added_desc->minor);
+
+ adisk->operational = 0;
+ adisk->write_only = 0;
+ adisk->spare = 1;
+ adisk->used_slot = 1;
+
+
+ break;
+
+ default:
+ MD_BUG();
+ err = 1;
+ goto abort;
+ }
+abort:
+ md_spin_unlock_irq(&conf->device_lock);
+ print_raid5_conf(conf);
+ return err;
}
-static struct md_personality raid5_personality=
+static mdk_personality_t raid5_personality=
{
"raid5",
- raid5_map,
raid5_make_request,
raid5_end_request,
raid5_run,
raid5_stop,
raid5_status,
- NULL, /* no ioctls */
0,
raid5_error,
- /* raid5_hot_add_disk, */ NULL,
- /* raid1_hot_remove_drive */ NULL,
- raid5_mark_spare
+ raid5_diskop,
+ raid5_stop_resync,
+ raid5_restart_resync,
+ raid5_sync_request
};
int raid5_init (void)
{
- return register_md_personality (RAID5, &raid5_personality);
+ int err;
+
+ err = register_md_personality (RAID5, &raid5_personality);
+ if (err)
+ return err;
+ return 0;
}
#ifdef MODULE
diff --git a/drivers/block/xor.c b/drivers/block/xor.c
new file mode 100644
index 000000000..ca1bb1564
--- /dev/null
+++ b/drivers/block/xor.c
@@ -0,0 +1,1894 @@
+/*
+ * xor.c : Multiple Devices driver for Linux
+ *
+ * Copyright (C) 1996, 1997, 1998, 1999 Ingo Molnar, Matti Aarnio, Jakub Jelinek
+ *
+ *
+ * optimized RAID-5 checksumming functions.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#define BH_TRACE 0
+#include <linux/module.h>
+#include <linux/raid/md.h>
+#ifdef __sparc_v9__
+#include <asm/head.h>
+#include <asm/asi.h>
+#include <asm/visasm.h>
+#endif
+
+/*
+ * we use the 'XOR function template' to register multiple xor
+ * functions runtime. The kernel measures their speed upon bootup
+ * and decides which one to use. (compile-time registration is
+ * not enough as certain CPU features like MMX can only be detected
+ * runtime)
+ *
+ * this architecture makes it pretty easy to add new routines
+ * that are faster on certain CPUs, without killing other CPU's
+ * 'native' routine. Although the current routines are belived
+ * to be the physically fastest ones on all CPUs tested, but
+ * feel free to prove me wrong and add yet another routine =B-)
+ * --mingo
+ */
+
+#define MAX_XOR_BLOCKS 5
+
+#define XOR_ARGS (unsigned int count, struct buffer_head **bh_ptr)
+
+typedef void (*xor_block_t) XOR_ARGS;
+xor_block_t xor_block = NULL;
+
+#ifndef __sparc_v9__
+
+struct xor_block_template;
+
+struct xor_block_template {
+ char * name;
+ xor_block_t xor_block;
+ int speed;
+ struct xor_block_template * next;
+};
+
+struct xor_block_template * xor_functions = NULL;
+
+#define XORBLOCK_TEMPLATE(x) \
+static void xor_block_##x XOR_ARGS; \
+static struct xor_block_template t_xor_block_##x = \
+ { #x, xor_block_##x, 0, NULL }; \
+static void xor_block_##x XOR_ARGS
+
+#ifdef __i386__
+
+#ifdef CONFIG_X86_XMM
+/*
+ * Cache avoiding checksumming functions utilizing KNI instructions
+ * Copyright (C) 1999 Zach Brown (with obvious credit due Ingo)
+ */
+
+XORBLOCK_TEMPLATE(pIII_kni)
+{
+ char xmm_save[16*4];
+ int cr0;
+ int lines = (bh_ptr[0]->b_size>>8);
+
+ __asm__ __volatile__ (
+ "movl %%cr0,%0 ;\n\t"
+ "clts ;\n\t"
+ "movups %%xmm0,(%1) ;\n\t"
+ "movups %%xmm1,0x10(%1) ;\n\t"
+ "movups %%xmm2,0x20(%1) ;\n\t"
+ "movups %%xmm3,0x30(%1) ;\n\t"
+ : "=r" (cr0)
+ : "r" (xmm_save)
+ : "memory" );
+
+#define OFFS(x) "8*("#x"*2)"
+#define PF0(x) \
+ " prefetcht0 "OFFS(x)"(%1) ;\n"
+#define LD(x,y) \
+ " movaps "OFFS(x)"(%1), %%xmm"#y" ;\n"
+#define ST(x,y) \
+ " movaps %%xmm"#y", "OFFS(x)"(%1) ;\n"
+#define PF1(x) \
+ " prefetchnta "OFFS(x)"(%2) ;\n"
+#define PF2(x) \
+ " prefetchnta "OFFS(x)"(%3) ;\n"
+#define PF3(x) \
+ " prefetchnta "OFFS(x)"(%4) ;\n"
+#define PF4(x) \
+ " prefetchnta "OFFS(x)"(%5) ;\n"
+#define PF5(x) \
+ " prefetchnta "OFFS(x)"(%6) ;\n"
+#define XO1(x,y) \
+ " xorps "OFFS(x)"(%2), %%xmm"#y" ;\n"
+#define XO2(x,y) \
+ " xorps "OFFS(x)"(%3), %%xmm"#y" ;\n"
+#define XO3(x,y) \
+ " xorps "OFFS(x)"(%4), %%xmm"#y" ;\n"
+#define XO4(x,y) \
+ " xorps "OFFS(x)"(%5), %%xmm"#y" ;\n"
+#define XO5(x,y) \
+ " xorps "OFFS(x)"(%6), %%xmm"#y" ;\n"
+
+ switch(count) {
+ case 2:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data)
+ : "memory" );
+ break;
+ case 3:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF2(i) \
+ PF2(i+2) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " addl $256, %3 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data)
+ : "memory" );
+ break;
+ case 4:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF2(i) \
+ PF2(i+2) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ PF3(i) \
+ PF3(i+2) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ XO3(i,0) \
+ XO3(i+1,1) \
+ XO3(i+2,2) \
+ XO3(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " addl $256, %3 ;\n"
+ " addl $256, %4 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data)
+ : "memory" );
+ break;
+ case 5:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ PF1(i) \
+ PF1(i+2) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ PF2(i) \
+ PF2(i+2) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ PF3(i) \
+ PF3(i+2) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ PF4(i) \
+ PF4(i+2) \
+ PF0(i+4) \
+ PF0(i+6) \
+ XO3(i,0) \
+ XO3(i+1,1) \
+ XO3(i+2,2) \
+ XO3(i+3,3) \
+ XO4(i,0) \
+ XO4(i+1,1) \
+ XO4(i+2,2) \
+ XO4(i+3,3) \
+ ST(i,0) \
+ ST(i+1,1) \
+ ST(i+2,2) \
+ ST(i+3,3) \
+
+
+ PF0(0)
+ PF0(2)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $256, %1 ;\n"
+ " addl $256, %2 ;\n"
+ " addl $256, %3 ;\n"
+ " addl $256, %4 ;\n"
+ " addl $256, %5 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data),
+ "r" (bh_ptr[4]->b_data)
+ : "memory");
+ break;
+ }
+
+ __asm__ __volatile__ (
+ "sfence ;\n\t"
+ "movups (%1),%%xmm0 ;\n\t"
+ "movups 0x10(%1),%%xmm1 ;\n\t"
+ "movups 0x20(%1),%%xmm2 ;\n\t"
+ "movups 0x30(%1),%%xmm3 ;\n\t"
+ "movl %0,%%cr0 ;\n\t"
+ :
+ : "r" (cr0), "r" (xmm_save)
+ : "memory" );
+}
+
+#undef OFFS
+#undef LD
+#undef ST
+#undef PF0
+#undef PF1
+#undef PF2
+#undef PF3
+#undef PF4
+#undef PF5
+#undef XO1
+#undef XO2
+#undef XO3
+#undef XO4
+#undef XO5
+#undef BLOCK
+
+#endif /* CONFIG_X86_XMM */
+
+/*
+ * high-speed RAID5 checksumming functions utilizing MMX instructions
+ * Copyright (C) 1998 Ingo Molnar
+ */
+XORBLOCK_TEMPLATE(pII_mmx)
+{
+ char fpu_save[108];
+ int lines = (bh_ptr[0]->b_size>>7);
+
+ if (!(current->flags & PF_USEDFPU))
+ __asm__ __volatile__ ( " clts;\n");
+
+ __asm__ __volatile__ ( " fsave %0; fwait\n"::"m"(fpu_save[0]) );
+
+#define LD(x,y) \
+ " movq 8*("#x")(%1), %%mm"#y" ;\n"
+#define ST(x,y) \
+ " movq %%mm"#y", 8*("#x")(%1) ;\n"
+#define XO1(x,y) \
+ " pxor 8*("#x")(%2), %%mm"#y" ;\n"
+#define XO2(x,y) \
+ " pxor 8*("#x")(%3), %%mm"#y" ;\n"
+#define XO3(x,y) \
+ " pxor 8*("#x")(%4), %%mm"#y" ;\n"
+#define XO4(x,y) \
+ " pxor 8*("#x")(%5), %%mm"#y" ;\n"
+
+ switch(count) {
+ case 2:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ ST(i,0) \
+ XO1(i+1,1) \
+ ST(i+1,1) \
+ XO1(i+2,2) \
+ ST(i+2,2) \
+ XO1(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data)
+ : "memory");
+ break;
+ case 3:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ ST(i,0) \
+ XO2(i+1,1) \
+ ST(i+1,1) \
+ XO2(i+2,2) \
+ ST(i+2,2) \
+ XO2(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " addl $128, %3 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data)
+ : "memory");
+ break;
+ case 4:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ XO3(i,0) \
+ ST(i,0) \
+ XO3(i+1,1) \
+ ST(i+1,1) \
+ XO3(i+2,2) \
+ ST(i+2,2) \
+ XO3(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " addl $128, %3 ;\n"
+ " addl $128, %4 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data)
+ : "memory");
+ break;
+ case 5:
+ __asm__ __volatile__ (
+#undef BLOCK
+#define BLOCK(i) \
+ LD(i,0) \
+ LD(i+1,1) \
+ LD(i+2,2) \
+ LD(i+3,3) \
+ XO1(i,0) \
+ XO1(i+1,1) \
+ XO1(i+2,2) \
+ XO1(i+3,3) \
+ XO2(i,0) \
+ XO2(i+1,1) \
+ XO2(i+2,2) \
+ XO2(i+3,3) \
+ XO3(i,0) \
+ XO3(i+1,1) \
+ XO3(i+2,2) \
+ XO3(i+3,3) \
+ XO4(i,0) \
+ ST(i,0) \
+ XO4(i+1,1) \
+ ST(i+1,1) \
+ XO4(i+2,2) \
+ ST(i+2,2) \
+ XO4(i+3,3) \
+ ST(i+3,3)
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+
+ BLOCK(0)
+ BLOCK(4)
+ BLOCK(8)
+ BLOCK(12)
+
+ " addl $128, %1 ;\n"
+ " addl $128, %2 ;\n"
+ " addl $128, %3 ;\n"
+ " addl $128, %4 ;\n"
+ " addl $128, %5 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+ :
+ : "g" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data),
+ "r" (bh_ptr[4]->b_data)
+ : "memory");
+ break;
+ }
+
+ __asm__ __volatile__ ( " frstor %0;\n"::"m"(fpu_save[0]) );
+
+ if (!(current->flags & PF_USEDFPU))
+ stts();
+}
+
+#undef LD
+#undef XO1
+#undef XO2
+#undef XO3
+#undef XO4
+#undef ST
+#undef BLOCK
+
+XORBLOCK_TEMPLATE(p5_mmx)
+{
+ char fpu_save[108];
+ int lines = (bh_ptr[0]->b_size>>6);
+
+ if (!(current->flags & PF_USEDFPU))
+ __asm__ __volatile__ ( " clts;\n");
+
+ __asm__ __volatile__ ( " fsave %0; fwait\n"::"m"(fpu_save[0]) );
+
+ switch(count) {
+ case 2:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " movq %%mm1, 8(%1) ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 24(%2), %%mm3 ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data)
+ : "memory" );
+ break;
+ case 3:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " pxor (%3), %%mm0 ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " pxor 8(%3), %%mm1 ;\n"
+ " pxor 16(%3), %%mm2 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " movq %%mm1, 8(%1) ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " pxor 24(%2), %%mm3 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " pxor 24(%3), %%mm3 ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " pxor 32(%3), %%mm4 ;\n"
+ " pxor 40(%3), %%mm5 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " pxor 48(%3), %%mm6 ;\n"
+ " pxor 56(%3), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " addl $64, %3 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data)
+ : "memory" );
+ break;
+ case 4:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " pxor (%3), %%mm0 ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " pxor 8(%3), %%mm1 ;\n"
+ " pxor (%4), %%mm0 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " pxor 16(%3), %%mm2 ;\n"
+ " pxor 8(%4), %%mm1 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " pxor 24(%2), %%mm3 ;\n"
+ " pxor 16(%4), %%mm2 ;\n"
+ " movq %%mm1, 8(%1) ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " pxor 24(%3), %%mm3 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " pxor 32(%3), %%mm4 ;\n"
+ " pxor 24(%4), %%mm3 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " pxor 40(%3), %%mm5 ;\n"
+ " pxor 32(%4), %%mm4 ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " pxor 40(%4), %%mm5 ;\n"
+ " pxor 48(%3), %%mm6 ;\n"
+ " pxor 56(%3), %%mm7 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 48(%4), %%mm6 ;\n"
+ " pxor 56(%4), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " addl $64, %3 ;\n"
+ " addl $64, %4 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "r" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data)
+ : "memory" );
+ break;
+ case 5:
+ __asm__ __volatile__ (
+
+ " .align 32,0x90 ;\n"
+ " 1: ;\n"
+ " movq (%1), %%mm0 ;\n"
+ " movq 8(%1), %%mm1 ;\n"
+ " pxor (%2), %%mm0 ;\n"
+ " pxor 8(%2), %%mm1 ;\n"
+ " movq 16(%1), %%mm2 ;\n"
+ " pxor (%3), %%mm0 ;\n"
+ " pxor 8(%3), %%mm1 ;\n"
+ " pxor 16(%2), %%mm2 ;\n"
+ " pxor (%4), %%mm0 ;\n"
+ " pxor 8(%4), %%mm1 ;\n"
+ " pxor 16(%3), %%mm2 ;\n"
+ " movq 24(%1), %%mm3 ;\n"
+ " pxor (%5), %%mm0 ;\n"
+ " pxor 8(%5), %%mm1 ;\n"
+ " movq %%mm0, (%1) ;\n"
+ " pxor 16(%4), %%mm2 ;\n"
+ " pxor 24(%2), %%mm3 ;\n"
+ " movq %%mm1, 8(%1) ;\n"
+ " pxor 16(%5), %%mm2 ;\n"
+ " pxor 24(%3), %%mm3 ;\n"
+ " movq 32(%1), %%mm4 ;\n"
+ " movq %%mm2, 16(%1) ;\n"
+ " pxor 24(%4), %%mm3 ;\n"
+ " pxor 32(%2), %%mm4 ;\n"
+ " movq 40(%1), %%mm5 ;\n"
+ " pxor 24(%5), %%mm3 ;\n"
+ " pxor 32(%3), %%mm4 ;\n"
+ " pxor 40(%2), %%mm5 ;\n"
+ " movq %%mm3, 24(%1) ;\n"
+ " pxor 32(%4), %%mm4 ;\n"
+ " pxor 40(%3), %%mm5 ;\n"
+ " movq 48(%1), %%mm6 ;\n"
+ " movq 56(%1), %%mm7 ;\n"
+ " pxor 32(%5), %%mm4 ;\n"
+ " pxor 40(%4), %%mm5 ;\n"
+ " pxor 48(%2), %%mm6 ;\n"
+ " pxor 56(%2), %%mm7 ;\n"
+ " movq %%mm4, 32(%1) ;\n"
+ " pxor 48(%3), %%mm6 ;\n"
+ " pxor 56(%3), %%mm7 ;\n"
+ " pxor 40(%5), %%mm5 ;\n"
+ " pxor 48(%4), %%mm6 ;\n"
+ " pxor 56(%4), %%mm7 ;\n"
+ " movq %%mm5, 40(%1) ;\n"
+ " pxor 48(%5), %%mm6 ;\n"
+ " pxor 56(%5), %%mm7 ;\n"
+ " movq %%mm6, 48(%1) ;\n"
+ " movq %%mm7, 56(%1) ;\n"
+
+ " addl $64, %1 ;\n"
+ " addl $64, %2 ;\n"
+ " addl $64, %3 ;\n"
+ " addl $64, %4 ;\n"
+ " addl $64, %5 ;\n"
+ " decl %0 ;\n"
+ " jnz 1b ;\n"
+
+ :
+ : "g" (lines),
+ "r" (bh_ptr[0]->b_data),
+ "r" (bh_ptr[1]->b_data),
+ "r" (bh_ptr[2]->b_data),
+ "r" (bh_ptr[3]->b_data),
+ "r" (bh_ptr[4]->b_data)
+ : "memory" );
+ break;
+ }
+
+ __asm__ __volatile__ ( " frstor %0;\n"::"m"(fpu_save[0]) );
+
+ if (!(current->flags & PF_USEDFPU))
+ stts();
+}
+#endif /* __i386__ */
+#endif /* !__sparc_v9__ */
+
+#ifdef __sparc_v9__
+/*
+ * High speed xor_block operation for RAID4/5 utilizing the
+ * UltraSparc Visual Instruction Set.
+ *
+ * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ * Requirements:
+ * !(((long)dest | (long)sourceN) & (64 - 1)) &&
+ * !(len & 127) && len >= 256
+ *
+ * It is done in pure assembly, as otherwise gcc makes it
+ * a non-leaf function, which is not what we want.
+ * Also, we don't measure the speeds as on other architectures,
+ * as the measuring routine does not take into account cold caches
+ * and the fact that xor_block_VIS bypasses the caches.
+ * xor_block_32regs might be 5% faster for count 2 if caches are hot
+ * and things just right (for count 3 VIS is about as fast as 32regs for
+ * hot caches and for count 4 and 5 VIS is faster by good margin always),
+ * but I think it is better not to pollute the caches.
+ * Actually, if I'd just fight for speed for hot caches, I could
+ * write a hybrid VIS/integer routine, which would do always two
+ * 64B blocks in VIS and two in IEUs, but I really care more about
+ * caches.
+ */
+extern void *VISenter(void);
+extern void xor_block_VIS XOR_ARGS;
+
+void __xor_block_VIS(void)
+{
+__asm__ ("
+ .globl xor_block_VIS
+xor_block_VIS:
+ ldx [%%o1 + 0], %%o4
+ ldx [%%o1 + 8], %%o3
+ ldx [%%o4 + %1], %%g5
+ ldx [%%o4 + %0], %%o4
+ ldx [%%o3 + %0], %%o3
+ rd %%fprs, %%o5
+ andcc %%o5, %2, %%g0
+ be,pt %%icc, 297f
+ sethi %%hi(%5), %%g1
+ jmpl %%g1 + %%lo(%5), %%g7
+ add %%g7, 8, %%g7
+297: wr %%g0, %4, %%fprs
+ membar #LoadStore|#StoreLoad|#StoreStore
+ sub %%g5, 64, %%g5
+ ldda [%%o4] %3, %%f0
+ ldda [%%o3] %3, %%f16
+ cmp %%o0, 4
+ bgeu,pt %%xcc, 10f
+ cmp %%o0, 3
+ be,pn %%xcc, 13f
+ mov -64, %%g1
+ sub %%g5, 64, %%g5
+ rd %%asi, %%g1
+ wr %%g0, %3, %%asi
+
+2: ldda [%%o4 + 64] %%asi, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ stda %%f16, [%%o4] %3
+ ldda [%%o3 + 64] %%asi, %%f48
+ ldda [%%o4 + 128] %%asi, %%f0
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ add %%o4, 128, %%o4
+ fxor %%f36, %%f52, %%f52
+ add %%o3, 128, %%o3
+ fxor %%f38, %%f54, %%f54
+ subcc %%g5, 128, %%g5
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4 - 64] %%asi
+ bne,pt %%xcc, 2b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o4 + 64] %%asi, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ stda %%f16, [%%o4] %3
+ ldda [%%o3 + 64] %%asi, %%f48
+ membar #Sync
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ fxor %%f36, %%f52, %%f52
+ fxor %%f38, %%f54, %%f54
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4 + 64] %%asi
+ membar #Sync|#StoreStore|#StoreLoad
+ wr %%g0, 0, %%fprs
+ retl
+ wr %%g1, %%g0, %%asi
+
+13: ldx [%%o1 + 16], %%o2
+ ldx [%%o2 + %0], %%o2
+
+3: ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ add %%o4, 64, %%o4
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ add %%o3, 64, %%o3
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ ldda [%%o4] %3, %%f0
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ add %%o2, 64, %%o2
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ subcc %%g5, 64, %%g5
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4 + %%g1] %3
+ bne,pt %%xcc, 3b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ membar #Sync
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4] %3
+ membar #Sync|#StoreStore|#StoreLoad
+ retl
+ wr %%g0, 0, %%fprs
+
+10: cmp %%o0, 5
+ be,pt %%xcc, 15f
+ mov -64, %%g1
+
+14: ldx [%%o1 + 16], %%o2
+ ldx [%%o1 + 24], %%o0
+ ldx [%%o2 + %0], %%o2
+ ldx [%%o0 + %0], %%o0
+
+4: ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ add %%o4, 64, %%o4
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ add %%o3, 64, %%o3
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ ldda [%%o0] %3, %%f48
+ fxor %%f16, %%f32, %%f32
+ fxor %%f18, %%f34, %%f34
+ fxor %%f20, %%f36, %%f36
+ fxor %%f22, %%f38, %%f38
+ add %%o2, 64, %%o2
+ fxor %%f24, %%f40, %%f40
+ fxor %%f26, %%f42, %%f42
+ fxor %%f28, %%f44, %%f44
+ fxor %%f30, %%f46, %%f46
+ ldda [%%o4] %3, %%f0
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ fxor %%f36, %%f52, %%f52
+ add %%o0, 64, %%o0
+ fxor %%f38, %%f54, %%f54
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ subcc %%g5, 64, %%g5
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4 + %%g1] %3
+ bne,pt %%xcc, 4b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f16
+ fxor %%f2, %%f18, %%f18
+ fxor %%f4, %%f20, %%f20
+ fxor %%f6, %%f22, %%f22
+ fxor %%f8, %%f24, %%f24
+ fxor %%f10, %%f26, %%f26
+ fxor %%f12, %%f28, %%f28
+ fxor %%f14, %%f30, %%f30
+ ldda [%%o0] %3, %%f48
+ fxor %%f16, %%f32, %%f32
+ fxor %%f18, %%f34, %%f34
+ fxor %%f20, %%f36, %%f36
+ fxor %%f22, %%f38, %%f38
+ fxor %%f24, %%f40, %%f40
+ fxor %%f26, %%f42, %%f42
+ fxor %%f28, %%f44, %%f44
+ fxor %%f30, %%f46, %%f46
+ membar #Sync
+ fxor %%f32, %%f48, %%f48
+ fxor %%f34, %%f50, %%f50
+ fxor %%f36, %%f52, %%f52
+ fxor %%f38, %%f54, %%f54
+ fxor %%f40, %%f56, %%f56
+ fxor %%f42, %%f58, %%f58
+ fxor %%f44, %%f60, %%f60
+ fxor %%f46, %%f62, %%f62
+ stda %%f48, [%%o4] %3
+ membar #Sync|#StoreStore|#StoreLoad
+ retl
+ wr %%g0, 0, %%fprs
+
+15: ldx [%%o1 + 16], %%o2
+ ldx [%%o1 + 24], %%o0
+ ldx [%%o1 + 32], %%o1
+ ldx [%%o2 + %0], %%o2
+ ldx [%%o0 + %0], %%o0
+ ldx [%%o1 + %0], %%o1
+
+5: ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ add %%o4, 64, %%o4
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ add %%o3, 64, %%o3
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ ldda [%%o0] %3, %%f16
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ add %%o2, 64, %%o2
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ ldda [%%o1] %3, %%f32
+ fxor %%f48, %%f16, %%f48
+ fxor %%f50, %%f18, %%f50
+ add %%o0, 64, %%o0
+ fxor %%f52, %%f20, %%f52
+ fxor %%f54, %%f22, %%f54
+ add %%o1, 64, %%o1
+ fxor %%f56, %%f24, %%f56
+ fxor %%f58, %%f26, %%f58
+ fxor %%f60, %%f28, %%f60
+ fxor %%f62, %%f30, %%f62
+ ldda [%%o4] %3, %%f0
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ subcc %%g5, 64, %%g5
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4 + %%g1] %3
+ bne,pt %%xcc, 5b
+ ldda [%%o3] %3, %%f16
+
+ ldda [%%o2] %3, %%f32
+ fxor %%f0, %%f16, %%f48
+ fxor %%f2, %%f18, %%f50
+ fxor %%f4, %%f20, %%f52
+ fxor %%f6, %%f22, %%f54
+ fxor %%f8, %%f24, %%f56
+ fxor %%f10, %%f26, %%f58
+ fxor %%f12, %%f28, %%f60
+ fxor %%f14, %%f30, %%f62
+ ldda [%%o0] %3, %%f16
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ ldda [%%o1] %3, %%f32
+ fxor %%f48, %%f16, %%f48
+ fxor %%f50, %%f18, %%f50
+ fxor %%f52, %%f20, %%f52
+ fxor %%f54, %%f22, %%f54
+ fxor %%f56, %%f24, %%f56
+ fxor %%f58, %%f26, %%f58
+ fxor %%f60, %%f28, %%f60
+ fxor %%f62, %%f30, %%f62
+ membar #Sync
+ fxor %%f48, %%f32, %%f48
+ fxor %%f50, %%f34, %%f50
+ fxor %%f52, %%f36, %%f52
+ fxor %%f54, %%f38, %%f54
+ fxor %%f56, %%f40, %%f56
+ fxor %%f58, %%f42, %%f58
+ fxor %%f60, %%f44, %%f60
+ fxor %%f62, %%f46, %%f62
+ stda %%f48, [%%o4] %3
+ membar #Sync|#StoreStore|#StoreLoad
+ retl
+ wr %%g0, 0, %%fprs
+ " : :
+ "i" (&((struct buffer_head *)0)->b_data),
+ "i" (&((struct buffer_head *)0)->b_data),
+ "i" (FPRS_FEF|FPRS_DU), "i" (ASI_BLK_P),
+ "i" (FPRS_FEF), "i" (VISenter));
+}
+#endif /* __sparc_v9__ */
+
+#if defined(__sparc__) && !defined(__sparc_v9__)
+/*
+ * High speed xor_block operation for RAID4/5 utilizing the
+ * ldd/std SPARC instructions.
+ *
+ * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
+ *
+ */
+
+XORBLOCK_TEMPLATE(SPARC)
+{
+ int size = bh_ptr[0]->b_size;
+ int lines = size / (sizeof (long)) / 8, i;
+ long *destp = (long *) bh_ptr[0]->b_data;
+ long *source1 = (long *) bh_ptr[1]->b_data;
+ long *source2, *source3, *source4;
+
+ switch (count) {
+ case 2:
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]
+ " : : "r" (destp), "r" (source1) : "g2", "g3", "g4", "g5", "o0",
+ "o1", "o2", "o3", "o4", "o5", "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ }
+ break;
+ case 3:
+ source2 = (long *) bh_ptr[2]->b_data;
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%2 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%2 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%2 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%2 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]
+ " : : "r" (destp), "r" (source1), "r" (source2)
+ : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+ "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ source2 += 8;
+ }
+ break;
+ case 4:
+ source2 = (long *) bh_ptr[2]->b_data;
+ source3 = (long *) bh_ptr[3]->b_data;
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%2 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%2 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%2 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%2 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%3 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%3 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%3 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%3 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]
+ " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3)
+ : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+ "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ source2 += 8;
+ source3 += 8;
+ }
+ break;
+ case 5:
+ source2 = (long *) bh_ptr[2]->b_data;
+ source3 = (long *) bh_ptr[3]->b_data;
+ source4 = (long *) bh_ptr[4]->b_data;
+ for (i = lines; i > 0; i--) {
+ __asm__ __volatile__("
+ ldd [%0 + 0x00], %%g2
+ ldd [%0 + 0x08], %%g4
+ ldd [%0 + 0x10], %%o0
+ ldd [%0 + 0x18], %%o2
+ ldd [%1 + 0x00], %%o4
+ ldd [%1 + 0x08], %%l0
+ ldd [%1 + 0x10], %%l2
+ ldd [%1 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%2 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%2 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%2 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%2 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%3 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%3 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%3 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%3 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ ldd [%4 + 0x00], %%o4
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ ldd [%4 + 0x08], %%l0
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ ldd [%4 + 0x10], %%l2
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ ldd [%4 + 0x18], %%l4
+ xor %%g2, %%o4, %%g2
+ xor %%g3, %%o5, %%g3
+ xor %%g4, %%l0, %%g4
+ xor %%g5, %%l1, %%g5
+ xor %%o0, %%l2, %%o0
+ xor %%o1, %%l3, %%o1
+ xor %%o2, %%l4, %%o2
+ xor %%o3, %%l5, %%o3
+ std %%g2, [%0 + 0x00]
+ std %%g4, [%0 + 0x08]
+ std %%o0, [%0 + 0x10]
+ std %%o2, [%0 + 0x18]
+ " : : "r" (destp), "r" (source1), "r" (source2), "r" (source3), "r" (source4)
+ : "g2", "g3", "g4", "g5", "o0", "o1", "o2", "o3", "o4", "o5",
+ "l0", "l1", "l2", "l3", "l4", "l5");
+ destp += 8;
+ source1 += 8;
+ source2 += 8;
+ source3 += 8;
+ source4 += 8;
+ }
+ break;
+ }
+}
+#endif /* __sparc_v[78]__ */
+
+#ifndef __sparc_v9__
+
+/*
+ * this one works reasonably on any x86 CPU
+ * (send me an assembly version for inclusion if you can make it faster)
+ *
+ * this one is just as fast as written in pure assembly on x86.
+ * the reason for this separate version is that the
+ * fast open-coded xor routine "32reg" produces suboptimal code
+ * on x86, due to lack of registers.
+ */
+XORBLOCK_TEMPLATE(8regs)
+{
+ int len = bh_ptr[0]->b_size;
+ long *destp = (long *) bh_ptr[0]->b_data;
+ long *source1, *source2, *source3, *source4;
+ long lines = len / (sizeof (long)) / 8, i;
+
+ switch(count) {
+ case 2:
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ source1 += 8;
+ destp += 8;
+ }
+ break;
+ case 3:
+ source2 = (long *) bh_ptr[2]->b_data;
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 0) ^= *(source2 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 1) ^= *(source2 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 2) ^= *(source2 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 3) ^= *(source2 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 4) ^= *(source2 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 5) ^= *(source2 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 6) ^= *(source2 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ *(destp + 7) ^= *(source2 + 7);
+ source1 += 8;
+ source2 += 8;
+ destp += 8;
+ }
+ break;
+ case 4:
+ source3 = (long *) bh_ptr[3]->b_data;
+ source2 = (long *) bh_ptr[2]->b_data;
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 0) ^= *(source2 + 0);
+ *(destp + 0) ^= *(source3 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 1) ^= *(source2 + 1);
+ *(destp + 1) ^= *(source3 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 2) ^= *(source2 + 2);
+ *(destp + 2) ^= *(source3 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 3) ^= *(source2 + 3);
+ *(destp + 3) ^= *(source3 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 4) ^= *(source2 + 4);
+ *(destp + 4) ^= *(source3 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 5) ^= *(source2 + 5);
+ *(destp + 5) ^= *(source3 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 6) ^= *(source2 + 6);
+ *(destp + 6) ^= *(source3 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ *(destp + 7) ^= *(source2 + 7);
+ *(destp + 7) ^= *(source3 + 7);
+ source1 += 8;
+ source2 += 8;
+ source3 += 8;
+ destp += 8;
+ }
+ break;
+ case 5:
+ source4 = (long *) bh_ptr[4]->b_data;
+ source3 = (long *) bh_ptr[3]->b_data;
+ source2 = (long *) bh_ptr[2]->b_data;
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ *(destp + 0) ^= *(source1 + 0);
+ *(destp + 0) ^= *(source2 + 0);
+ *(destp + 0) ^= *(source3 + 0);
+ *(destp + 0) ^= *(source4 + 0);
+ *(destp + 1) ^= *(source1 + 1);
+ *(destp + 1) ^= *(source2 + 1);
+ *(destp + 1) ^= *(source3 + 1);
+ *(destp + 1) ^= *(source4 + 1);
+ *(destp + 2) ^= *(source1 + 2);
+ *(destp + 2) ^= *(source2 + 2);
+ *(destp + 2) ^= *(source3 + 2);
+ *(destp + 2) ^= *(source4 + 2);
+ *(destp + 3) ^= *(source1 + 3);
+ *(destp + 3) ^= *(source2 + 3);
+ *(destp + 3) ^= *(source3 + 3);
+ *(destp + 3) ^= *(source4 + 3);
+ *(destp + 4) ^= *(source1 + 4);
+ *(destp + 4) ^= *(source2 + 4);
+ *(destp + 4) ^= *(source3 + 4);
+ *(destp + 4) ^= *(source4 + 4);
+ *(destp + 5) ^= *(source1 + 5);
+ *(destp + 5) ^= *(source2 + 5);
+ *(destp + 5) ^= *(source3 + 5);
+ *(destp + 5) ^= *(source4 + 5);
+ *(destp + 6) ^= *(source1 + 6);
+ *(destp + 6) ^= *(source2 + 6);
+ *(destp + 6) ^= *(source3 + 6);
+ *(destp + 6) ^= *(source4 + 6);
+ *(destp + 7) ^= *(source1 + 7);
+ *(destp + 7) ^= *(source2 + 7);
+ *(destp + 7) ^= *(source3 + 7);
+ *(destp + 7) ^= *(source4 + 7);
+ source1 += 8;
+ source2 += 8;
+ source3 += 8;
+ source4 += 8;
+ destp += 8;
+ }
+ break;
+ }
+}
+
+/*
+ * platform independent RAID5 checksum calculation, this should
+ * be very fast on any platform that has a decent amount of
+ * registers. (32 or more)
+ */
+XORBLOCK_TEMPLATE(32regs)
+{
+ int size = bh_ptr[0]->b_size;
+ int lines = size / (sizeof (long)) / 8, i;
+ long *destp = (long *) bh_ptr[0]->b_data;
+ long *source1, *source2, *source3, *source4;
+
+ /* LOTS of registers available...
+ We do explicite loop-unrolling here for code which
+ favours RISC machines. In fact this is almoast direct
+ RISC assembly on Alpha and SPARC :-) */
+
+
+ switch(count) {
+ case 2:
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;
+ source1 += 8;
+ destp += 8;
+ }
+ break;
+ case 3:
+ source2 = (long *) bh_ptr[2]->b_data;
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ d0 ^= source2[0];
+ d1 ^= source2[1];
+ d2 ^= source2[2];
+ d3 ^= source2[3];
+ d4 ^= source2[4];
+ d5 ^= source2[5];
+ d6 ^= source2[6];
+ d7 ^= source2[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;
+ source1 += 8;
+ source2 += 8;
+ destp += 8;
+ }
+ break;
+ case 4:
+ source3 = (long *) bh_ptr[3]->b_data;
+ source2 = (long *) bh_ptr[2]->b_data;
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ d0 ^= source2[0];
+ d1 ^= source2[1];
+ d2 ^= source2[2];
+ d3 ^= source2[3];
+ d4 ^= source2[4];
+ d5 ^= source2[5];
+ d6 ^= source2[6];
+ d7 ^= source2[7];
+ d0 ^= source3[0];
+ d1 ^= source3[1];
+ d2 ^= source3[2];
+ d3 ^= source3[3];
+ d4 ^= source3[4];
+ d5 ^= source3[5];
+ d6 ^= source3[6];
+ d7 ^= source3[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;
+ source1 += 8;
+ source2 += 8;
+ source3 += 8;
+ destp += 8;
+ }
+ break;
+ case 5:
+ source4 = (long *) bh_ptr[4]->b_data;
+ source3 = (long *) bh_ptr[3]->b_data;
+ source2 = (long *) bh_ptr[2]->b_data;
+ source1 = (long *) bh_ptr[1]->b_data;
+ for (i = lines; i > 0; i--) {
+ register long d0, d1, d2, d3, d4, d5, d6, d7;
+ d0 = destp[0]; /* Pull the stuff into registers */
+ d1 = destp[1]; /* ... in bursts, if possible. */
+ d2 = destp[2];
+ d3 = destp[3];
+ d4 = destp[4];
+ d5 = destp[5];
+ d6 = destp[6];
+ d7 = destp[7];
+ d0 ^= source1[0];
+ d1 ^= source1[1];
+ d2 ^= source1[2];
+ d3 ^= source1[3];
+ d4 ^= source1[4];
+ d5 ^= source1[5];
+ d6 ^= source1[6];
+ d7 ^= source1[7];
+ d0 ^= source2[0];
+ d1 ^= source2[1];
+ d2 ^= source2[2];
+ d3 ^= source2[3];
+ d4 ^= source2[4];
+ d5 ^= source2[5];
+ d6 ^= source2[6];
+ d7 ^= source2[7];
+ d0 ^= source3[0];
+ d1 ^= source3[1];
+ d2 ^= source3[2];
+ d3 ^= source3[3];
+ d4 ^= source3[4];
+ d5 ^= source3[5];
+ d6 ^= source3[6];
+ d7 ^= source3[7];
+ d0 ^= source4[0];
+ d1 ^= source4[1];
+ d2 ^= source4[2];
+ d3 ^= source4[3];
+ d4 ^= source4[4];
+ d5 ^= source4[5];
+ d6 ^= source4[6];
+ d7 ^= source4[7];
+ destp[0] = d0; /* Store the result (in burts) */
+ destp[1] = d1;
+ destp[2] = d2;
+ destp[3] = d3;
+ destp[4] = d4; /* Store the result (in burts) */
+ destp[5] = d5;
+ destp[6] = d6;
+ destp[7] = d7;
+ source1 += 8;
+ source2 += 8;
+ source3 += 8;
+ source4 += 8;
+ destp += 8;
+ }
+ break;
+ }
+}
+
+/*
+ * (the -6*32 shift factor colors the cache)
+ */
+#define SIZE (PAGE_SIZE-6*32)
+
+static void xor_speed ( struct xor_block_template * func,
+ struct buffer_head *b1, struct buffer_head *b2)
+{
+ int speed;
+ unsigned long now;
+ int i, count, max;
+ struct buffer_head *bh_ptr[6];
+
+ func->next = xor_functions;
+ xor_functions = func;
+ bh_ptr[0] = b1;
+ bh_ptr[1] = b2;
+
+ /*
+ * count the number of XORs done during a whole jiffy.
+ * calculate the speed of checksumming from this.
+ * (we use a 2-page allocation to have guaranteed
+ * color L1-cache layout)
+ */
+ max = 0;
+ for (i = 0; i < 5; i++) {
+ now = jiffies;
+ count = 0;
+ while (jiffies == now) {
+ mb();
+ func->xor_block(2,bh_ptr);
+ mb();
+ count++;
+ mb();
+ }
+ if (count > max)
+ max = count;
+ }
+
+ speed = max * (HZ*SIZE/1024);
+ func->speed = speed;
+
+ printk( " %-10s: %5d.%03d MB/sec\n", func->name,
+ speed / 1000, speed % 1000);
+}
+
+static inline void pick_fastest_function(void)
+{
+ struct xor_block_template *f, *fastest;
+
+ fastest = xor_functions;
+ for (f = fastest; f; f = f->next) {
+ if (f->speed > fastest->speed)
+ fastest = f;
+ }
+#ifdef CONFIG_X86_XMM
+ if (boot_cpu_data.mmu_cr4_features & X86_CR4_OSXMMEXCPT) {
+ fastest = &t_xor_block_pIII_kni;
+ }
+#endif
+ xor_block = fastest->xor_block;
+ printk( "using fastest function: %s (%d.%03d MB/sec)\n", fastest->name,
+ fastest->speed / 1000, fastest->speed % 1000);
+}
+
+static struct buffer_head b1, b2;
+
+void calibrate_xor_block(void)
+{
+ memset(&b1,0,sizeof(b1));
+ b2 = b1;
+
+ b1.b_data = (char *) md__get_free_pages(GFP_KERNEL,2);
+ if (!b1.b_data) {
+ pick_fastest_function();
+ return;
+ }
+ b2.b_data = b1.b_data + 2*PAGE_SIZE + SIZE;
+
+ b1.b_size = SIZE;
+
+ printk(KERN_INFO "raid5: measuring checksumming speed\n");
+
+ sti(); /* should be safe */
+
+#if defined(__sparc__) && !defined(__sparc_v9__)
+ printk(KERN_INFO "raid5: trying high-speed SPARC checksum routine\n");
+ xor_speed(&t_xor_block_SPARC,&b1,&b2);
+#endif
+
+#ifdef CONFIG_X86_XMM
+ if (boot_cpu_data.mmu_cr4_features & X86_CR4_OSXMMEXCPT) {
+ printk(KERN_INFO
+ "raid5: KNI detected, trying cache-avoiding KNI checksum routine\n");
+ /* we force the use of the KNI xor block because it
+ can write around l2. we may also be able
+ to load into the l1 only depending on how
+ the cpu deals with a load to a line that is
+ being prefetched.
+ */
+ xor_speed(&t_xor_block_pIII_kni,&b1,&b2);
+ }
+#endif /* CONFIG_X86_XMM */
+
+#ifdef __i386__
+
+ if (md_cpu_has_mmx()) {
+ printk(KERN_INFO
+ "raid5: MMX detected, trying high-speed MMX checksum routines\n");
+ xor_speed(&t_xor_block_pII_mmx,&b1,&b2);
+ xor_speed(&t_xor_block_p5_mmx,&b1,&b2);
+ }
+
+#endif /* __i386__ */
+
+
+ xor_speed(&t_xor_block_8regs,&b1,&b2);
+ xor_speed(&t_xor_block_32regs,&b1,&b2);
+
+ free_pages((unsigned long)b1.b_data,2);
+ pick_fastest_function();
+}
+
+#else /* __sparc_v9__ */
+
+void calibrate_xor_block(void)
+{
+ printk(KERN_INFO "raid5: using high-speed VIS checksum routine\n");
+ xor_block = xor_block_VIS;
+}
+
+#endif /* __sparc_v9__ */
+
+MD_EXPORT_SYMBOL(xor_block);
+
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index d2aa95921..48047a637 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -1,12 +1,12 @@
#undef BLOCKMOVE
#define Z_WAKE
static char rcsid[] =
-"$Revision: 2.3.2.4 $$Date: 2000/01/17 09:19:40 $";
+"$Revision: 2.3.2.6 $$Date: 2000/05/05 13:56:05 $";
/*
* linux/drivers/char/cyclades.c
*
- * This file contains the driver for the Cyclades Cyclom-Y multiport
+ * This file contains the driver for the Cyclades async multiport
* serial boards.
*
* Initially written by Randolph Bentson <bentson@grieg.seaslug.org>.
@@ -23,14 +23,22 @@ static char rcsid[] =
*
* This version supports shared IRQ's (only for PCI boards).
*
- * This module exports the following rs232 io functions:
- * int cy_init(void);
- * int cy_open(struct tty_struct *tty, struct file *filp);
- * and the following functions for modularization.
- * int init_module(void);
- * void cleanup_module(void);
- *
* $Log: cyclades.c,v $
+ * Revision 2.3.2.6 2000/05/05 13:56:05 ivan
+ * Driver now reports physical instead of virtual memory addresses.
+ * Masks were added to some Cyclades-Z read accesses.
+ * Implemented workaround for PLX9050 bug that would cause a system lockup
+ * in certain systems, depending on the MMIO addresses allocated to the
+ * board.
+ * Changed the Tx interrupt programming in the CD1400 chips to boost up
+ * performance (Cyclom-Y only).
+ * Code is now compliant with the new module interface (module_[init|exit]).
+ * Make use of the PCI helper functions to access PCI resources.
+ * Did some code "housekeeping".
+ *
+ * Revision 2.3.2.5 2000/01/19 14:35:33 ivan
+ * Fixed bug in cy_set_termios on CRTSCTS flag turnoff.
+ *
* Revision 2.3.2.4 2000/01/17 09:19:40 ivan
* Fixed SMP locking in Cyclom-Y interrupt handler.
*
@@ -695,7 +703,7 @@ cy_get_user(unsigned long *addr)
#ifndef SERIAL_XMIT_SIZE
#define SERIAL_XMIT_SIZE (MIN(PAGE_SIZE, 4096))
#endif
-#define WAKEUP_CHARS (SERIAL_XMIT_SIZE-256)
+#define WAKEUP_CHARS 256
#define STD_COM_FLAGS (0)
@@ -706,7 +714,7 @@ static DECLARE_TASK_QUEUE(tq_cyclades);
static struct tty_driver cy_serial_driver, cy_callout_driver;
static int serial_refcount;
-#ifndef CONFIG_COBALT_27
+#ifdef CONFIG_ISA
/* This is the address lookup table. The driver will probe for
Cyclom-Y/ISA boards at all addresses in here. If you want the
driver to probe addresses at a different address, add it to
@@ -737,7 +745,7 @@ MODULE_PARM(maddr, "1-" __MODULE_STRING(NR_CARDS) "l");
MODULE_PARM(irq, "1-" __MODULE_STRING(NR_CARDS) "i");
#endif
-#endif /* CONFIG_COBALT_27 */
+#endif /* CONFIG_ISA */
/* This is the per-card data structure containing address, irq, number of
channels, etc. This driver supports a maximum of NR_CARDS cards.
@@ -861,12 +869,9 @@ static unsigned short cy_pci_dev_id[] = {
static void cy_start(struct tty_struct *);
static void set_line_char(struct cyclades_port *);
static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong);
-#ifndef CONFIG_COBALT_27
+#ifdef CONFIG_ISA
static unsigned detect_isa_irq (volatile ucchar *);
-#endif /* CONFIG_COBALT_27 */
-#ifdef CYCLOM_SHOW_STATUS
-static void show_status(int);
-#endif
+#endif /* CONFIG_ISA */
static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *);
@@ -877,23 +882,15 @@ static void cyz_poll(unsigned long);
static long cyz_polling_cycle = CZ_DEF_POLL;
static int cyz_timeron = 0;
-static struct timer_list cyz_timerlist = {
- function: cyz_poll
+static struct timer_list
+cyz_timerlist = {
+ NULL, NULL, 0, 0, cyz_poll
};
#else /* CONFIG_CYZ_INTR */
static void cyz_rx_restart(unsigned long);
static struct timer_list cyz_rx_full_timer[NR_PORTS];
#endif /* CONFIG_CYZ_INTR */
-/**************************************************
-error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(unsigned long));
-copy_to_user (to, from, count);
-***************************************************************
-error = verify_area(VERIFY_READ, (void *) arg, sizeof(unsigned long *));
-copy_from_user(to, from, count);
-**************************************************/
-
-
static inline int
serial_paranoia_check(struct cyclades_port *info,
kdev_t device, const char *routine)
@@ -1047,7 +1044,8 @@ cyy_issue_cmd(volatile ucchar *base_addr, u_char cmd, int index)
return(0);
} /* cyy_issue_cmd */
-#ifndef CONFIG_COBALT_27 /* ISA interrupt detection code */
+#ifdef CONFIG_ISA
+/* ISA interrupt detection code */
static unsigned
detect_isa_irq (volatile ucchar *address)
{
@@ -1074,7 +1072,7 @@ detect_isa_irq (volatile ucchar *address)
cy_writeb((u_long)address + (CyCAR<<index), 0);
cy_writeb((u_long)address + (CySRER<<index),
- cy_readb(address + (CySRER<<index)) | CyTxMpty);
+ cy_readb(address + (CySRER<<index)) | CyTxRdy);
restore_flags(flags);
/* Wait ... */
@@ -1088,7 +1086,7 @@ detect_isa_irq (volatile ucchar *address)
save_car = cy_readb(address + (CyCAR<<index));
cy_writeb((u_long)address + (CyCAR<<index), (save_xir & 0x3));
cy_writeb((u_long)address + (CySRER<<index),
- cy_readb(address + (CySRER<<index)) & ~CyTxMpty);
+ cy_readb(address + (CySRER<<index)) & ~CyTxRdy);
cy_writeb((u_long)address + (CyTIR<<index), (save_xir & 0x3f));
cy_writeb((u_long)address + (CyCAR<<index), (save_car));
cy_writeb((u_long)address + (Cy_ClrIntr<<index), 0);
@@ -1096,7 +1094,7 @@ detect_isa_irq (volatile ucchar *address)
return (irq > 0)? irq : 0;
}
-#endif /* CONFIG_COBALT_27 */
+#endif /* CONFIG_ISA */
/* The real interrupt service routine is called
whenever the card wants its hand held--chars
@@ -1319,14 +1317,14 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* validate the port# (as configured and open) */
if( (i < 0) || (NR_PORTS <= i) ){
cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
+ cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
goto txend;
}
info = &cy_port[i];
info->last_active = jiffies;
if(info->tty == 0){
cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
+ cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
goto txdone;
}
@@ -1360,19 +1358,19 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (!info->xmit_cnt){
cy_writeb((u_long)base_addr+(CySRER<<index),
cy_readb(base_addr+(CySRER<<index)) &
- ~CyTxMpty);
+ ~CyTxRdy);
goto txdone;
}
if (info->xmit_buf == 0){
cy_writeb((u_long)base_addr+(CySRER<<index),
cy_readb(base_addr+(CySRER<<index)) &
- ~CyTxMpty);
+ ~CyTxRdy);
goto txdone;
}
if (info->tty->stopped || info->tty->hw_stopped){
cy_writeb((u_long)base_addr+(CySRER<<index),
cy_readb(base_addr+(CySRER<<index)) &
- ~CyTxMpty);
+ ~CyTxRdy);
goto txdone;
}
/* Because the Embedded Transmit Commands have
@@ -1470,7 +1468,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
info->tty->hw_stopped = 0;
cy_writeb((u_long)base_addr+(CySRER<<index),
cy_readb(base_addr+(CySRER<<index)) |
- CyTxMpty);
+ CyTxRdy);
cy_sched_event(info,
Cy_EVENT_WRITE_WAKEUP);
}
@@ -1481,7 +1479,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
info->tty->hw_stopped = 1;
cy_writeb((u_long)base_addr+(CySRER<<index),
cy_readb(base_addr+(CySRER<<index)) &
- ~CyTxMpty);
+ ~CyTxRdy);
}
}
}
@@ -1526,7 +1524,8 @@ cyz_fetch_msg( struct cyclades_card *cinfo,
return (-1);
}
zfw_ctrl = (struct ZFW_CTRL *)
- (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cinfo->base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
loc_doorbell = cy_readl(&((struct RUNTIME_9060 *)
@@ -1557,7 +1556,8 @@ cyz_issue_cmd( struct cyclades_card *cinfo,
return (-1);
}
zfw_ctrl = (struct ZFW_CTRL *)
- (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cinfo->base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
index = 0;
@@ -1774,7 +1774,8 @@ cyz_handle_cmd(struct cyclades_card *cinfo)
firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
zfw_ctrl = (struct ZFW_CTRL *)
- (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cinfo->base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &(zfw_ctrl->board_ctrl);
fw_ver = cy_readl(&board_ctrl->fw_version);
hw_ver = cy_readl(&((struct RUNTIME_9060 *)(cinfo->ctl_addr))->mail_box_0);
@@ -1951,7 +1952,8 @@ cyz_poll(unsigned long arg)
firm_id = (struct FIRM_ID *)(cinfo->base_addr + ID_ADDRESS);
zfw_ctrl = (struct ZFW_CTRL *)
- (cinfo->base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cinfo->base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &(zfw_ctrl->board_ctrl);
/* Skip first polling cycle to avoid racing conditions with the FW */
@@ -2091,9 +2093,9 @@ startup(struct cyclades_port * info)
return -ENODEV;
}
- zfw_ctrl =
- (struct ZFW_CTRL *)
- (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ zfw_ctrl = (struct ZFW_CTRL *)
+ (cy_card[card].base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
@@ -2201,7 +2203,7 @@ start_xmit( struct cyclades_port *info )
CY_LOCK(info, flags);
cy_writeb((u_long)base_addr+(CyCAR<<index), channel);
cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
+ cy_readb(base_addr+(CySRER<<index)) | CyTxRdy);
CY_UNLOCK(info, flags);
} else {
#ifdef CONFIG_CYZ_INTR
@@ -2299,9 +2301,9 @@ shutdown(struct cyclades_port * info)
return;
}
- zfw_ctrl =
- (struct ZFW_CTRL *)
- (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ zfw_ctrl = (struct ZFW_CTRL *)
+ (cy_card[card].base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &(zfw_ctrl->board_ctrl);
ch_ctrl = zfw_ctrl->ch_ctrl;
@@ -2499,9 +2501,8 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
return -EINVAL;
}
- zfw_ctrl =
- (struct ZFW_CTRL *)
- (base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ zfw_ctrl = (struct ZFW_CTRL *)
+ (base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
@@ -2758,7 +2759,7 @@ cy_wait_until_sent(struct tty_struct *tty, int timeout)
index = cy_card[card].bus_index;
base_addr = (unsigned char *)
(cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
- while (cy_readb(base_addr+(CySRER<<index)) & CyTxMpty) {
+ while (cy_readb(base_addr+(CySRER<<index)) & CyTxRdy) {
#ifdef CY_DEBUG_WAIT_UNTIL_SENT
printk("Not clean (jiff=%lu)...", jiffies);
#endif
@@ -2882,8 +2883,8 @@ cy_close(struct tty_struct *tty, struct file *filp)
unsigned char *base_addr = (unsigned char *)
cy_card[info->card].base_addr;
struct FIRM_ID *firm_id = (struct FIRM_ID *) (base_addr + ID_ADDRESS);
- struct ZFW_CTRL *zfw_ctrl =
- (struct ZFW_CTRL *) (base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ struct ZFW_CTRL *zfw_ctrl = (struct ZFW_CTRL *)
+ (base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
struct CH_CTRL *ch_ctrl = zfw_ctrl->ch_ctrl;
int channel = info->line - cy_card[info->card].first_line;
int retval;
@@ -3136,8 +3137,9 @@ cy_chars_in_buffer(struct tty_struct *tty)
volatile uclong tx_put, tx_get, tx_bufsize;
firm_id = (struct FIRM_ID *)(cy_card[card].base_addr + ID_ADDRESS);
- zfw_ctrl = (struct ZFW_CTRL *) (cy_card[card].base_addr +
- cy_readl(&firm_id->zfwctrl_addr));
+ zfw_ctrl = (struct ZFW_CTRL *)
+ (cy_card[card].base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]);
@@ -3427,7 +3429,8 @@ set_line_char(struct cyclades_port * info)
}
zfw_ctrl = (struct ZFW_CTRL *)
- (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cy_card[card].base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]);
buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
@@ -3660,7 +3663,8 @@ get_modem_info(struct cyclades_port * info, unsigned int *value)
(cy_card[card].base_addr + ID_ADDRESS);
if (ISZLOADED(cy_card[card])) {
zfw_ctrl = (struct ZFW_CTRL *)
- (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cy_card[card].base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
lstatus = cy_readl(&ch_ctrl[channel].rs_status);
@@ -3825,7 +3829,8 @@ set_modem_info(struct cyclades_port * info, unsigned int cmd,
(cy_card[card].base_addr + ID_ADDRESS);
if (ISZLOADED(cy_card[card])) {
zfw_ctrl = (struct ZFW_CTRL *)
- (cy_card[card].base_addr + cy_readl(&firm_id->zfwctrl_addr));
+ (cy_card[card].base_addr +
+ (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff));
board_ctrl = &zfw_ctrl->board_ctrl;
ch_ctrl = zfw_ctrl->ch_ctrl;
@@ -4337,7 +4342,7 @@ cy_set_termios(struct tty_struct *tty, struct termios * old_termios)
if ((old_termios->c_cflag & CRTSCTS) &&
!(tty->termios->c_cflag & CRTSCTS)) {
- tty->stopped = 0;
+ tty->hw_stopped = 0;
cy_start(tty);
}
#if 0
@@ -4502,7 +4507,7 @@ cy_stop(struct tty_struct *tty)
cy_writeb((u_long)base_addr+(CyCAR<<index),
(u_char)(channel & 0x0003)); /* index channel */
cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) & ~CyTxMpty);
+ cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy);
CY_UNLOCK(info, flags);
} else {
// Nothing to do!
@@ -4542,7 +4547,7 @@ cy_start(struct tty_struct *tty)
cy_writeb((u_long)base_addr+(CyCAR<<index),
(u_char)(channel & 0x0003)); /* index channel */
cy_writeb((u_long)base_addr+(CySRER<<index),
- cy_readb(base_addr+(CySRER<<index)) | CyTxMpty);
+ cy_readb(base_addr+(CySRER<<index)) | CyTxRdy);
CY_UNLOCK(info, flags);
} else {
// Nothing to do!
@@ -4707,7 +4712,6 @@ cyy_init_card(volatile ucchar *true_base_addr,int index)
return chip_number;
} /* cyy_init_card */
-#ifndef CONFIG_COBALT_27
/*
* ---------------------------------------------------------------------
* cy_detect_isa() - Probe for Cyclom-Y/ISA boards.
@@ -4717,6 +4721,7 @@ cyy_init_card(volatile ucchar *true_base_addr,int index)
static int __init
cy_detect_isa(void)
{
+#ifdef CONFIG_ISA
unsigned short cy_isa_irq,nboard;
volatile ucchar *cy_isa_address;
unsigned short i,j,cy_isa_nchan;
@@ -4746,7 +4751,6 @@ cy_detect_isa(void)
}
/* probe for CD1400... */
-
#if !defined(__alpha__)
cy_isa_address = ioremap((ulong)cy_isa_address, CyISA_Ywin);
#endif
@@ -4819,9 +4823,10 @@ cy_detect_isa(void)
cy_next_channel += cy_isa_nchan;
}
return(nboard);
-
+#else
+ return(0);
+#endif /* CONFIG_ISA */
} /* cy_detect_isa */
-#endif /* CONFIG_COBALT_27 */
static void
plx_init(uclong addr, uclong initctl)
@@ -4851,11 +4856,13 @@ cy_detect_pci(void)
struct pci_dev *pdev = NULL;
unsigned char cyy_rev_id;
unsigned char cy_pci_irq = 0;
- uclong cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
+ uclong cy_pci_phys0, cy_pci_phys2;
+ uclong cy_pci_addr0, cy_pci_addr2;
unsigned short i,j,cy_pci_nchan, plx_ver;
unsigned short device_id,dev_index = 0;
uclong mailbox;
uclong Ze_addr0[NR_CARDS], Ze_addr2[NR_CARDS], ZeIndex = 0;
+ uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS];
unsigned char Ze_irq[NR_CARDS];
for (i = 0; i < NR_CARDS; i++) {
@@ -4877,10 +4884,9 @@ cy_detect_pci(void)
/* read PCI configuration area */
cy_pci_irq = pdev->irq;
- cy_pci_addr0 = pci_resource_start(pdev, 0);
- cy_pci_addr1 = pci_resource_start(pdev, 1);
- cy_pci_addr2 = pci_resource_start(pdev, 2);
- pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
+ cy_pci_phys0 = pci_resource_start(pdev, 0);
+ cy_pci_phys2 = pci_resource_start(pdev, 2);
+ pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
device_id &= ~PCI_DEVICE_ID_MASK;
@@ -4892,13 +4898,13 @@ cy_detect_pci(void)
printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq);
printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
+ (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
#endif
- if (pdev->resource[2].flags & ~PCI_BASE_ADDRESS_IO_MASK) {
+ if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
printk(" Warning: PCI I/O bit incorrectly set. "
"Ignoring it...\n");
- pdev->resource[2].flags &= PCI_BASE_ADDRESS_IO_MASK;
+ pdev->resource[2].flags &= ~IORESOURCE_IO;
}
#if defined(__alpha__)
@@ -4908,15 +4914,15 @@ cy_detect_pci(void)
printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq);
printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
+ (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
printk("Cyclom-Y/PCI not supported for low addresses in "
"Alpha systems.\n");
i--;
continue;
}
#else
- cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Yctl);
- cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ywin);
+ cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Yctl);
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ywin);
#endif
#ifdef CY_PCI_DEBUG
@@ -4928,13 +4934,13 @@ cy_detect_pci(void)
if(cy_pci_nchan == 0) {
printk("Cyclom-Y PCI host card with ");
printk("no Serial-Modules at 0x%lx.\n",
- (ulong) cy_pci_addr2);
+ (ulong) cy_pci_phys2);
i--;
continue;
}
if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_addr2);
+ (ulong) cy_pci_phys2);
printk("but no channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(i);
@@ -4945,7 +4951,7 @@ cy_detect_pci(void)
}
if (j == NR_CARDS) { /* no more cy_cards available */
printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_addr2);
+ (ulong) cy_pci_phys2);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(i);
@@ -4956,13 +4962,15 @@ cy_detect_pci(void)
SA_SHIRQ, "Cyclom-Y", &cy_card[j]))
{
printk("Cyclom-Y/PCI found at 0x%lx ",
- (ulong) cy_pci_addr2);
+ (ulong) cy_pci_phys2);
printk("but could not allocate IRQ%d.\n",
cy_pci_irq);
return(i);
}
/* set cy_card */
+ cy_card[j].base_phys = (ulong)cy_pci_phys2;
+ cy_card[j].ctl_phys = (ulong)cy_pci_phys0;
cy_card[j].base_addr = (ulong)cy_pci_addr2;
cy_card[j].ctl_addr = (ulong)cy_pci_addr0;
cy_card[j].irq = (int) cy_pci_irq;
@@ -4975,10 +4983,7 @@ cy_detect_pci(void)
switch (plx_ver) {
case PLX_9050:
- plx_init(cy_pci_addr0, 0x50);
-
- cy_writew(cy_pci_addr0+0x4c,
- cy_readw(cy_pci_addr0+0x4c)|0x0040);
+ cy_writeb(cy_pci_addr0+0x4c, 0x43);
break;
case PLX_9060:
@@ -5000,8 +5005,8 @@ cy_detect_pci(void)
/* print message */
printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
j+1,
- (ulong)cy_pci_addr2,
- (ulong)(cy_pci_addr2 + CyPCI_Ywin - 1),
+ (ulong)cy_pci_phys2,
+ (ulong)(cy_pci_phys2 + CyPCI_Ywin - 1),
(int)cy_pci_irq);
printk("%d channels starting from port %d.\n",
cy_pci_nchan, cy_next_channel);
@@ -5014,7 +5019,7 @@ cy_detect_pci(void)
printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq);
printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
+ (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
printk("Cyclades-Z/PCI not supported for low addresses\n");
break;
}else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){
@@ -5024,10 +5029,10 @@ cy_detect_pci(void)
printk("rev_id=%d) IRQ%d\n",
cyy_rev_id, (int)cy_pci_irq);
printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n",
- (ulong)cy_pci_addr2, (ulong)cy_pci_addr0);
+ (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
#endif
#if !defined(__alpha__)
- cy_pci_addr0 = (ulong)ioremap(cy_pci_addr0, CyPCI_Zctl);
+ cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
#endif
/* Disable interrupts on the PLX before resetting it */
@@ -5044,21 +5049,23 @@ cy_detect_pci(void)
mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *)
cy_pci_addr0)->mail_box_0);
- if (pdev->resource[2].flags & ~PCI_BASE_ADDRESS_IO_MASK) {
+ if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
printk(" Warning: PCI I/O bit incorrectly set. "
"Ignoring it...\n");
- pdev->resource[2].flags &= PCI_BASE_ADDRESS_IO_MASK;
+ pdev->resource[2].flags &= ~IORESOURCE_IO;
}
if (mailbox == ZE_V1) {
#if !defined(__alpha__)
- cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Ze_win);
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
#endif
if (ZeIndex == NR_CARDS) {
printk("Cyclades-Ze/PCI found at 0x%lx ",
- (ulong)cy_pci_addr2);
+ (ulong)cy_pci_phys2);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
} else {
+ Ze_phys0[ZeIndex] = cy_pci_phys0;
+ Ze_phys2[ZeIndex] = cy_pci_phys2;
Ze_addr0[ZeIndex] = cy_pci_addr0;
Ze_addr2[ZeIndex] = cy_pci_addr2;
Ze_irq[ZeIndex] = cy_pci_irq;
@@ -5068,7 +5075,7 @@ cy_detect_pci(void)
continue;
} else {
#if !defined(__alpha__)
- cy_pci_addr2 = (ulong)ioremap(cy_pci_addr2, CyPCI_Zwin);
+ cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
#endif
}
@@ -5105,7 +5112,7 @@ cy_detect_pci(void)
if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
printk("Cyclades-8Zo/PCI found at 0x%lx ",
- (ulong)cy_pci_addr2);
+ (ulong)cy_pci_phys2);
printk("but no channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(i);
@@ -5117,7 +5124,7 @@ cy_detect_pci(void)
}
if (j == NR_CARDS) { /* no more cy_cards available */
printk("Cyclades-8Zo/PCI found at 0x%lx ",
- (ulong)cy_pci_addr2);
+ (ulong)cy_pci_phys2);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(i);
@@ -5129,10 +5136,10 @@ cy_detect_pci(void)
if(request_irq(cy_pci_irq, cyz_interrupt,
SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
{
- printk("Could not allocate IRQ%d ",
+ printk("Cyclom-8Zo/PCI found at 0x%lx ",
+ (ulong) cy_pci_phys2);
+ printk("but could not allocate IRQ%d.\n",
cy_pci_irq);
- printk("for Cyclades-8Zo/PCI at 0x%lx.\n",
- (ulong)cy_pci_addr2);
return(i);
}
}
@@ -5140,6 +5147,8 @@ cy_detect_pci(void)
/* set cy_card */
+ cy_card[j].base_phys = cy_pci_phys2;
+ cy_card[j].ctl_phys = cy_pci_phys0;
cy_card[j].base_addr = cy_pci_addr2;
cy_card[j].ctl_addr = cy_pci_addr0;
cy_card[j].irq = (int) cy_pci_irq;
@@ -5152,14 +5161,14 @@ cy_detect_pci(void)
/* don't report IRQ if board is no IRQ */
if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
- j+1,(ulong)cy_pci_addr2,
- (ulong)(cy_pci_addr2 + CyPCI_Zwin - 1),
+ j+1,(ulong)cy_pci_phys2,
+ (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1),
(int)cy_pci_irq);
else
#endif /* CONFIG_CYZ_INTR */
printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ",
- j+1,(ulong)cy_pci_addr2,
- (ulong)(cy_pci_addr2 + CyPCI_Zwin - 1));
+ j+1,(ulong)cy_pci_phys2,
+ (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1));
printk("%d channels starting from port %d.\n",
cy_pci_nchan,cy_next_channel);
@@ -5168,10 +5177,14 @@ cy_detect_pci(void)
}
for (; ZeIndex != 0 && i < NR_CARDS; i++) {
+ cy_pci_phys0 = Ze_phys0[0];
+ cy_pci_phys2 = Ze_phys2[0];
cy_pci_addr0 = Ze_addr0[0];
cy_pci_addr2 = Ze_addr2[0];
cy_pci_irq = Ze_irq[0];
for (j = 0 ; j < ZeIndex-1 ; j++) {
+ Ze_phys0[j] = Ze_phys0[j+1];
+ Ze_phys2[j] = Ze_phys2[j+1];
Ze_addr0[j] = Ze_addr0[j+1];
Ze_addr2[j] = Ze_addr2[j+1];
Ze_irq[j] = Ze_irq[j+1];
@@ -5190,7 +5203,7 @@ cy_detect_pci(void)
if((cy_next_channel+cy_pci_nchan) > NR_PORTS) {
printk("Cyclades-Ze/PCI found at 0x%lx ",
- (ulong)cy_pci_addr2);
+ (ulong)cy_pci_phys2);
printk("but no channels are available.\n");
printk("Change NR_PORTS in cyclades.c and recompile kernel.\n");
return(i);
@@ -5202,7 +5215,7 @@ cy_detect_pci(void)
}
if (j == NR_CARDS) { /* no more cy_cards available */
printk("Cyclades-Ze/PCI found at 0x%lx ",
- (ulong)cy_pci_addr2);
+ (ulong)cy_pci_phys2);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
return(i);
@@ -5214,16 +5227,18 @@ cy_detect_pci(void)
if(request_irq(cy_pci_irq, cyz_interrupt,
SA_SHIRQ, "Cyclades-Z", &cy_card[j]))
{
- printk("Could not allocate IRQ%d ",
+ printk("Cyclom-Ze/PCI found at 0x%lx ",
+ (ulong) cy_pci_phys2);
+ printk("but could not allocate IRQ%d.\n",
cy_pci_irq);
- printk("for Cyclades-Ze/PCI at 0x%lx.\n",
- (ulong) cy_pci_addr2);
return(i);
}
}
#endif /* CONFIG_CYZ_INTR */
/* set cy_card */
+ cy_card[j].base_phys = cy_pci_phys2;
+ cy_card[j].ctl_phys = cy_pci_phys0;
cy_card[j].base_addr = cy_pci_addr2;
cy_card[j].ctl_addr = cy_pci_addr0;
cy_card[j].irq = (int) cy_pci_irq;
@@ -5236,14 +5251,14 @@ cy_detect_pci(void)
/* don't report IRQ if board is no IRQ */
if( (cy_pci_irq != 0) && (cy_pci_irq != 255) )
printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ",
- j+1,(ulong)cy_pci_addr2,
- (ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1),
+ j+1,(ulong)cy_pci_phys2,
+ (ulong)(cy_pci_phys2 + CyPCI_Ze_win - 1),
(int)cy_pci_irq);
else
#endif /* CONFIG_CYZ_INTR */
printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ",
- j+1,(ulong)cy_pci_addr2,
- (ulong)(cy_pci_addr2 + CyPCI_Ze_win - 1));
+ j+1,(ulong)cy_pci_phys2,
+ (ulong)(cy_pci_phys2 + CyPCI_Ze_win - 1));
printk("%d channels starting from port %d.\n",
cy_pci_nchan,cy_next_channel);
@@ -5251,7 +5266,7 @@ cy_detect_pci(void)
}
if (ZeIndex != 0) {
printk("Cyclades-Ze/PCI found at 0x%x ",
- (unsigned int) Ze_addr2[0]);
+ (unsigned int) Ze_phys2[0]);
printk("but no more cards can be used.\n");
printk("Change NR_CARDS in cyclades.c and recompile kernel.\n");
}
@@ -5438,10 +5453,8 @@ cy_init(void)
availability of cy_card and cy_port data structures and updating
the cy_next_channel. */
-#ifndef CONFIG_COBALT_27
/* look for isa boards */
cy_isa_nboard = cy_detect_isa();
-#endif /* CONFIG_COBALT_27 */
/* look for pci boards */
cy_pci_nboard = cy_detect_pci();
@@ -5568,9 +5581,10 @@ cy_init(void)
info->icount.frame = info->icount.parity = 0;
info->icount.overrun = info->icount.brk = 0;
chip_number = (port - cinfo->first_line) / 4;
- if ((info->chip_rev = cy_readb(cinfo->base_addr +
- (cy_chip_offset[chip_number]<<index) +
- (CyGFRCR<<index))) >= CD1400_REV_J) {
+ if ((info->chip_rev =
+ cy_readb(cinfo->base_addr +
+ (cy_chip_offset[chip_number]<<index) +
+ (CyGFRCR<<index))) >= CD1400_REV_J) {
/* It is a CD1400 rev. J or later */
info->tbpr = baud_bpr_60[13]; /* Tx BPR */
info->tco = baud_co_60[13]; /* Tx CO */
@@ -5628,16 +5642,8 @@ cy_init(void)
} /* cy_init */
#ifdef MODULE
-/* See linux/drivers/char/riscom.c for ideas on how to
- pass additional base addresses to the driver!!! */
-int
-init_module(void)
-{
- return(cy_init());
-} /* init_module */
-
void
-cleanup_module(void)
+cy_cleanup_module(void)
{
int i;
int e1, e2;
@@ -5679,13 +5685,18 @@ cleanup_module(void)
free_page((unsigned long) tmp_buf);
tmp_buf = NULL;
}
-} /* cleanup_module */
-#else
+} /* cy_cleanup_module */
+
+/* Module entry-points */
+module_init(cy_init);
+module_exit(cy_cleanup_module);
+
+#else /* MODULE */
/* called by linux/init/main.c to parse command line options */
void
cy_setup(char *str, int *ints)
{
-#ifndef CONFIG_COBALT_27
+#ifdef CONFIG_ISA
int i, j;
for (i = 0 ; i < NR_ISA_ADDRS ; i++) {
@@ -5696,110 +5707,7 @@ cy_setup(char *str, int *ints)
cy_isa_addresses[i++] = (unsigned char *)(ints[j]);
}
}
-#endif /* CONFIG_COBALT_27 */
-
+#endif /* CONFIG_ISA */
} /* cy_setup */
-#endif
-
-
-#ifdef CYCLOM_SHOW_STATUS
-static void
-show_status(int line_num)
-{
- unsigned char *base_addr;
- int card,chip,channel,index;
- struct cyclades_port * info;
- unsigned long flags;
-
- info = &cy_port[line_num];
- card = info->card;
- index = cy_card[card].bus_index;
- channel = (info->line) - (cy_card[card].first_line);
- chip = channel>>2;
- channel &= 0x03;
- printk(" card %d, chip %d, channel %d\n", card, chip, channel);/**/
-
- printk(" cy_card\n");
- printk(" irq base_addr num_chips first_line = %d %lx %d %d\n",
- cy_card[card].irq, (long)cy_card[card].base_addr,
- cy_card[card].num_chips, cy_card[card].first_line);
-
- printk(" cy_port\n");
- printk(" card line flags = %d %d %x\n",
- info->card, info->line, info->flags);
- printk(" *tty read_status_mask timeout xmit_fifo_size ",
- printk("= %lx %x %x %x\n",
- (long)info->tty, info->read_status_mask,
- info->timeout, info->xmit_fifo_size);
- printk(" cor1,cor2,cor3,cor4,cor5 = %x %x %x %x %x\n",
- info->cor1, info->cor2, info->cor3, info->cor4, info->cor5);
- printk(" tbpr,tco,rbpr,rco = %d %d %d %d\n",
- info->tbpr, info->tco, info->rbpr, info->rco);
- printk(" close_delay event count = %d %d %d\n",
- info->close_delay, info->event, info->count);
- printk(" x_char blocked_open = %x %x\n",
- info->x_char, info->blocked_open);
- printk(" session pgrp open_wait = %lx %lx %lx\n",
- info->session, info->pgrp, (long)info->open_wait);
-
- CY_LOCK(info, flags);
-
- base_addr = (unsigned char*)
- (cy_card[card].base_addr
- + (cy_chip_offset[chip]<<index));
-
-/* Global Registers */
-
- printk(" CyGFRCR %x\n", cy_readb(base_addr + CyGFRCR<<index));
- printk(" CyCAR %x\n", cy_readb(base_addr + CyCAR<<index));
- printk(" CyGCR %x\n", cy_readb(base_addr + CyGCR<<index));
- printk(" CySVRR %x\n", cy_readb(base_addr + CySVRR<<index));
- printk(" CyRICR %x\n", cy_readb(base_addr + CyRICR<<index));
- printk(" CyTICR %x\n", cy_readb(base_addr + CyTICR<<index));
- printk(" CyMICR %x\n", cy_readb(base_addr + CyMICR<<index));
- printk(" CyRIR %x\n", cy_readb(base_addr + CyRIR<<index));
- printk(" CyTIR %x\n", cy_readb(base_addr + CyTIR<<index));
- printk(" CyMIR %x\n", cy_readb(base_addr + CyMIR<<index));
- printk(" CyPPR %x\n", cy_readb(base_addr + CyPPR<<index));
-
- cy_writeb(base_addr + CyCAR<<index, (u_char)channel);
-
-/* Virtual Registers */
-
- printk(" CyRIVR %x\n", cy_readb(base_addr + CyRIVR<<index));
- printk(" CyTIVR %x\n", cy_readb(base_addr + CyTIVR<<index));
- printk(" CyMIVR %x\n", cy_readb(base_addr + CyMIVR<<index));
- printk(" CyMISR %x\n", cy_readb(base_addr + CyMISR<<index));
-
-/* Channel Registers */
-
- printk(" CyCCR %x\n", cy_readb(base_addr + CyCCR<<index));
- printk(" CySRER %x\n", cy_readb(base_addr + CySRER<<index));
- printk(" CyCOR1 %x\n", cy_readb(base_addr + CyCOR1<<index));
- printk(" CyCOR2 %x\n", cy_readb(base_addr + CyCOR2<<index));
- printk(" CyCOR3 %x\n", cy_readb(base_addr + CyCOR3<<index));
- printk(" CyCOR4 %x\n", cy_readb(base_addr + CyCOR4<<index));
- printk(" CyCOR5 %x\n", cy_readb(base_addr + CyCOR5<<index));
- printk(" CyCCSR %x\n", cy_readb(base_addr + CyCCSR<<index));
- printk(" CyRDCR %x\n", cy_readb(base_addr + CyRDCR<<index));
- printk(" CySCHR1 %x\n", cy_readb(base_addr + CySCHR1<<index));
- printk(" CySCHR2 %x\n", cy_readb(base_addr + CySCHR2<<index));
- printk(" CySCHR3 %x\n", cy_readb(base_addr + CySCHR3<<index));
- printk(" CySCHR4 %x\n", cy_readb(base_addr + CySCHR4<<index));
- printk(" CySCRL %x\n", cy_readb(base_addr + CySCRL<<index));
- printk(" CySCRH %x\n", cy_readb(base_addr + CySCRH<<index));
- printk(" CyLNC %x\n", cy_readb(base_addr + CyLNC<<index));
- printk(" CyMCOR1 %x\n", cy_readb(base_addr + CyMCOR1<<index));
- printk(" CyMCOR2 %x\n", cy_readb(base_addr + CyMCOR2<<index));
- printk(" CyRTPR %x\n", cy_readb(base_addr + CyRTPR<<index));
- printk(" CyMSVR1 %x\n", cy_readb(base_addr + CyMSVR1<<index));
- printk(" CyMSVR2 %x\n", cy_readb(base_addr + CyMSVR2<<index));
- printk(" CyRBPR %x\n", cy_readb(base_addr + CyRBPR<<index));
- printk(" CyRCOR %x\n", cy_readb(base_addr + CyRCOR<<index));
- printk(" CyTBPR %x\n", cy_readb(base_addr + CyTBPR<<index));
- printk(" CyTCOR %x\n", cy_readb(base_addr + CyTCOR<<index));
-
- CY_UNLOCK(info, flags);
-} /* show_status */
-#endif
+#endif /* MODULE */
diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c
index 986b728db..34d996582 100644
--- a/drivers/char/nwbutton.c
+++ b/drivers/char/nwbutton.c
@@ -22,14 +22,14 @@
#define __NWBUTTON_C /* Tell the header file who we are */
#include "nwbutton.h"
-static int button_press_count = 0; /* The count of button presses */
+static int button_press_count; /* The count of button presses */
static struct timer_list button_timer; /* Times for the end of a sequence */
static DECLARE_WAIT_QUEUE_HEAD(button_wait_queue); /* Used for blocking read */
static char button_output_buffer[32]; /* Stores data to write out of device */
-static int bcount = 0; /* The number of bytes in the buffer */
+static int bcount; /* The number of bytes in the buffer */
static int bdelay = BUTTON_DELAY; /* The delay, in jiffies */
static struct button_callback button_callback_list[32]; /* The callback list */
-static int callback_count = 0; /* The number of callbacks registered */
+static int callback_count; /* The number of callbacks registered */
static int reboot_count = NUM_PRESSES_REBOOT; /* Number of presses to reboot */
/*
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index cbe0ec79f..579e970d4 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -50,10 +50,10 @@ static long long flash_llseek(struct file *file, long long offset, int orig);
#define KFLASH_ID 0x89A6 //Intel flash
#define KFLASH_ID4 0xB0D4 //Intel flash 4Meg
-static int flashdebug = 0; //if set - we will display progress msgs
+static int flashdebug; //if set - we will display progress msgs
-static int gbWriteEnable = 0;
-static int gbWriteBase64Enable = 0;
+static int gbWriteEnable;
+static int gbWriteBase64Enable;
MSTATIC int gbFlashSize = KFLASH_SIZE;
extern spinlock_t gpio_lock;
diff --git a/drivers/net/Config.in b/drivers/net/Config.in
index 00c9fc7f3..7aaeb9398 100644
--- a/drivers/net/Config.in
+++ b/drivers/net/Config.in
@@ -218,7 +218,7 @@ if [ ! "$CONFIG_PPP" = "n" ]; then
dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP
dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
- dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m
+ dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
fi
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 77a2c7298..3490fd92f 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -204,29 +204,12 @@ obj-$(CONFIG_ES3210) += es3210.o 8390.o
obj-$(CONFIG_LNE390) += lne390.o 8390.o
obj-$(CONFIG_NE3210) += ne3210.o 8390.o
-# bsd_comp.o is *always* a module, for some documented reason
-# (licensing).
-ifeq ($(CONFIG_PPP),y)
- obj-y += ppp_generic.o slhc.o
- obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
- obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
- obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
- ifeq ($(CONFIG_PPP_BSDCOMP),m)
- obj-m += bsd_comp.o
- endif
- obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
-else
- ifeq ($(CONFIG_PPP),m)
- obj-m += ppp_generic.o slhc.o
- obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
- obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
- obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
- obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
- ifeq ($(CONFIG_PPP_BSDCOMP),m)
- obj-m += bsd_comp.o
- endif
- endif
-endif
+obj-$(CONFIG_PPP) += ppp_generic.o slhc.o
+obj-$(CONFIG_PPP_ASYNC) += ppp_async.o
+obj-$(CONFIG_PPP_SYNC_TTY) += ppp_synctty.o
+obj-$(CONFIG_PPP_DEFLATE) += ppp_deflate.o
+obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
+obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
obj-$(CONFIG_SLIP) += slip.o
ifeq ($(CONFIG_SLIP),y)
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 8fa454af9..7d53e1260 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -29,6 +29,7 @@
* infrastructure and Sparc support
* Pierrick Pinasseau (CERN): For lending me an Ultra 5 to test the
* driver under Linux/Sparc64
+ * Matt Domsch <Matt_Domsch@dell.com>: Detect 1000baseT cards
*/
#include <linux/config.h>
@@ -70,7 +71,10 @@
#ifndef PCI_VENDOR_ID_ALTEON
#define PCI_VENDOR_ID_ALTEON 0x12ae
-#define PCI_DEVICE_ID_ALTEON_ACENIC 0x0001
+#endif
+#ifndef PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE
+#define PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE 0x0001
+#define PCI_DEVICE_ID_ALTEON_ACENIC_COPPER 0x0002
#endif
#ifndef PCI_DEVICE_ID_3COM_3C985
#define PCI_DEVICE_ID_3COM_3C985 0x0001
@@ -105,6 +109,12 @@
#endif
+#if (LINUX_VERSION_CODE < 0x02030d)
+#define pci_resource_start(dev, bar) dev->base_address[bar]
+#elif (LINUX_VERSION_CODE < 0x02032c)
+#define pci_resource_start(dev, bar) dev->resource[bar].start
+#endif
+
#if (LINUX_VERSION_CODE < 0x02030e)
#define net_device device
#endif
@@ -379,7 +389,7 @@ static int tx_ratio[ACE_MAX_MOD_PARMS] = {0, };
static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};
static const char __initdata *version =
- "acenic.c: v0.42 03/02/2000 Jes Sorensen, linux-acenic@SunSITE.auc.dk\n"
+ "acenic.c: v0.44 05/11/2000 Jes Sorensen, linux-acenic@SunSITE.auc.dk\n"
" http://home.cern.ch/~jes/gige/acenic.html\n";
static struct net_device *root_dev = NULL;
@@ -414,7 +424,8 @@ int __init acenic_probe (struct net_device *dev)
while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) {
if (!((pdev->vendor == PCI_VENDOR_ID_ALTEON) &&
- (pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC)) &&
+ ((pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE) ||
+ (pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_COPPER)) ) &&
!((pdev->vendor == PCI_VENDOR_ID_3COM) &&
(pdev->device == PCI_DEVICE_ID_3COM_3C985)) &&
!((pdev->vendor == PCI_VENDOR_ID_NETGEAR) &&
@@ -494,11 +505,7 @@ int __init acenic_probe (struct net_device *dev)
* dev->base_addr since it was means for I/O port
* addresses but who gives a damn.
*/
-#if (LINUX_VERSION_CODE < 0x02030d)
- dev->base_addr = pdev->base_address[0];
-#else
- dev->base_addr = pdev->resource[0].start;
-#endif
+ dev->base_addr = pci_resource_start(pdev, 0);
ap->regs = (struct ace_regs *)ioremap(dev->base_addr, 0x4000);
if (!ap->regs) {
printk(KERN_ERR "%s: Unable to map I/O register, "
@@ -717,10 +724,7 @@ void cleanup_module(void)
{
ace_module_cleanup();
}
-#endif
-
-
-#if (LINUX_VERSION_CODE >= 0x02032a)
+#else
module_init(ace_module_init);
module_exit(ace_module_cleanup);
#endif
@@ -1087,11 +1091,17 @@ static int __init ace_init(struct net_device *dev)
#endif
writel(tmp, &regs->PciState);
+#if 0
+ /*
+ * I have received reports from people having problems when this
+ * bit is enabled.
+ */
if (!(ap->pci_command & PCI_COMMAND_FAST_BACK)) {
printk(KERN_INFO " Enabling PCI Fast Back to Back\n");
ap->pci_command |= PCI_COMMAND_FAST_BACK;
pci_write_config_word(ap->pdev, PCI_COMMAND, ap->pci_command);
}
+#endif
/*
* Initialize the generic info block and the command+event rings
@@ -1760,16 +1770,23 @@ static u32 ace_handle_event(struct net_device *dev, u32 evtcsm, u32 evtprd)
case E_LNK_STATE:
{
u16 code = ap->evt_ring[evtcsm].code;
- if (code == E_C_LINK_UP) {
+ switch (code) {
+ case E_C_LINK_UP:
printk(KERN_WARNING "%s: Optical link UP\n",
dev->name);
- }
- else if (code == E_C_LINK_DOWN)
+ break;
+ case E_C_LINK_DOWN:
printk(KERN_WARNING "%s: Optical link DOWN\n",
dev->name);
- else
+ break;
+ case E_C_LINK_10_100:
+ printk(KERN_WARNING "%s: 10/100BaseT link "
+ "UP\n", dev->name);
+ break;
+ default:
printk(KERN_ERR "%s: Unknown optical link "
"state %02x\n", dev->name, code);
+ }
break;
}
case E_ERROR:
@@ -2949,6 +2966,6 @@ static int __init read_eeprom_byte(struct net_device *dev,
/*
* Local variables:
- * compile-command: "gcc -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c"
+ * compile-command: "gcc -D__SMP__ -D__KERNEL__ -DMODULE -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -DMODVERSIONS -include ../../include/linux/modversions.h -c -o acenic.o acenic.c"
* End:
*/
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
index 958561a69..b74368cae 100644
--- a/drivers/net/acenic.h
+++ b/drivers/net/acenic.h
@@ -324,7 +324,7 @@ struct event {
#define E_LNK_STATE 0x06
#define E_C_LINK_UP 0x01
#define E_C_LINK_DOWN 0x02
-#define E_C_LINK_UP_FAST 0x03
+#define E_C_LINK_10_100 0x03
#define E_ERROR 0x07
#define E_C_ERR_INVAL_CMD 0x01
diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h
index 729eac664..cb2441285 100644
--- a/drivers/net/acenic_firmware.h
+++ b/drivers/net/acenic_firmware.h
@@ -5,17 +5,17 @@
*/
#define tigonFwReleaseMajor 0xc
#define tigonFwReleaseMinor 0x4
-#define tigonFwReleaseFix 0x5
+#define tigonFwReleaseFix 0xb
#define tigonFwStartAddr 0x00004000
#define tigonFwTextAddr 0x00004000
-#define tigonFwTextLen 0x11190
-#define tigonFwRodataAddr 0x00015190
+#define tigonFwTextLen 0x11140
+#define tigonFwRodataAddr 0x00015140
#define tigonFwRodataLen 0xac0
-#define tigonFwDataAddr 0x00015c80
+#define tigonFwDataAddr 0x00015c20
#define tigonFwDataLen 0x170
-#define tigonFwSbssAddr 0x00015df0
-#define tigonFwSbssLen 0x34
-#define tigonFwBssAddr 0x00015e30
+#define tigonFwSbssAddr 0x00015d90
+#define tigonFwSbssLen 0x38
+#define tigonFwBssAddr 0x00015dd0
#define tigonFwBssLen 0x2080
u32 tigonFwText[];
u32 tigonFwData[];
@@ -25,16 +25,16 @@ u32 tigonFwRodata[];
u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x10000003,
0x0, 0xd, 0xd, 0x3c1d0001,
-0x8fbd5cb4, 0x3a0f021, 0x3c100000, 0x26104000,
+0x8fbd5c54, 0x3a0f021, 0x3c100000, 0x26104000,
0xc00100c, 0x0, 0xd, 0x27bdffd8,
0x3c1cc000, 0x3c1b0013, 0x377bd800, 0xd021,
0x3c170013, 0x36f75418, 0x2e02021, 0x340583e8,
0xafbf0024, 0xc002488, 0xafb00020, 0xc0023e8,
-0x0, 0x3c040001, 0x248451f4, 0x24050001,
-0x2e03021, 0x3821, 0x3c100001, 0x26107eb0,
+0x0, 0x3c040001, 0x248451a4, 0x24050001,
+0x2e03021, 0x3821, 0x3c100001, 0x26107e50,
0xafb00010, 0xc002403, 0xafbb0014, 0x3c02000f,
0x3442ffff, 0x2021024, 0x362102b, 0x10400009,
-0x24050003, 0x3c040001, 0x24845200, 0x2003021,
+0x24050003, 0x3c040001, 0x248451b0, 0x2003021,
0x3603821, 0x3c020010, 0xafa20010, 0xc002403,
0xafa00014, 0x2021, 0x3405c000, 0x3c010001,
0x370821, 0xa02083b0, 0x3c010001, 0x370821,
@@ -72,7 +72,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x8ee20450, 0x8ee30454, 0xaee304fc,
0x8ee204fc, 0x2442e000, 0x2c422001, 0x1440000d,
0x26e40030, 0x8ee20450, 0x8ee30454, 0x3c040001,
-0x2484520c, 0x3c050001, 0xafa00010, 0xafa00014,
+0x248451bc, 0x3c050001, 0xafa00010, 0xafa00014,
0x8ee704fc, 0x34a5f000, 0xc002403, 0x603021,
0x26e40030, 0xc002488, 0x24050400, 0x27440080,
0xc002488, 0x24050080, 0x26e4777c, 0xc002488,
@@ -82,7 +82,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x3442ca00, 0x2021, 0x24030002, 0xaee30074,
0xaee30070, 0xaee2006c, 0x240203e8, 0xaee20104,
0x24020001, 0xaee30100, 0xaee2010c, 0x3c030001,
-0x641821, 0x90635c80, 0x2e41021, 0x24840001,
+0x641821, 0x90635c20, 0x2e41021, 0x24840001,
0xa043009c, 0x2c82000f, 0x1440fff8, 0x0,
0x8f820040, 0x2e41821, 0x24840001, 0x21702,
0x24420030, 0xa062009c, 0x2e41021, 0xa040009c,
@@ -128,7 +128,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
0x210c0, 0x24425038, 0x2e22021, 0x24020007,
0xac820000, 0x24020001, 0xac820004, 0x54c0000c,
-0xaee90608, 0x3c040001, 0x24845218, 0xafa00010,
+0xaee90608, 0x3c040001, 0x248451c8, 0xafa00010,
0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
0xc002403, 0x34a5f000, 0x8001223, 0x0,
0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
@@ -154,21 +154,21 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020012, 0xac820000,
0x24020001, 0xac820004, 0x14c0001b, 0x0,
-0x3c040001, 0x24845220, 0xafa00010, 0xafa00014,
+0x3c040001, 0x248451d0, 0xafa00010, 0xafa00014,
0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
0x34a5f001, 0x8ee201b0, 0x24420001, 0xaee201b0,
-0x8001223, 0x8ee201b0, 0x3c040001, 0x2484522c,
+0x8001223, 0x8ee201b0, 0x3c040001, 0x248451dc,
0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
0xc002403, 0x34a5f005, 0x8ee201ac, 0x24420001,
0xaee201ac, 0x8ee201ac, 0x8ee20160, 0x3c040001,
-0x24845238, 0x3405f001, 0x24420001, 0xaee20160,
+0x248451e8, 0x3405f001, 0x24420001, 0xaee20160,
0x8ee20160, 0x3021, 0x3821, 0xafa00010,
0xc002403, 0xafa00014, 0x8001238, 0x0,
0x3c020001, 0x2442f5a8, 0x21100, 0x21182,
0x431025, 0x3c010001, 0xac221278, 0x96e2045a,
0x30420003, 0x10400025, 0x3c050fff, 0x8ee204c8,
0x34a5ffff, 0x34420a00, 0xaee204c8, 0x8ee304c8,
-0x3c040001, 0x24845244, 0x24020001, 0xa2e204ec,
+0x3c040001, 0x248451f4, 0x24020001, 0xa2e204ec,
0xa2e204ed, 0x3c020002, 0x621825, 0x3c020001,
0x2442a390, 0x451024, 0x21082, 0xaee304c8,
0x3c030800, 0x431025, 0x3c010001, 0xac221220,
@@ -211,7 +211,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
0x2e22021, 0x24020007, 0xac820000, 0x24020001,
0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001,
-0x24845218, 0xafa00010, 0xafa00014, 0x8ee60608,
+0x248451c8, 0xafa00010, 0xafa00014, 0x8ee60608,
0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000,
0x800136d, 0x0, 0x8f830120, 0x27623800,
0x24660020, 0xc2102b, 0x50400001, 0x27663000,
@@ -236,17 +236,17 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0x24020012, 0xac820000, 0x24020001, 0xac820004,
-0x14c0001b, 0x0, 0x3c040001, 0x24845220,
+0x14c0001b, 0x0, 0x3c040001, 0x248451d0,
0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228,
0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0,
0x24420001, 0xaee201b0, 0x800136d, 0x8ee201b0,
-0x3c040001, 0x2484522c, 0xafa00014, 0x8ee60608,
+0x3c040001, 0x248451dc, 0xafa00014, 0x8ee60608,
0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005,
0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac,
-0x8ee20160, 0x3c040001, 0x24845238, 0x3405f002,
+0x8ee20160, 0x3c040001, 0x248451e8, 0x3405f002,
0x24420001, 0xaee20160, 0x8ee20160, 0x3021,
0x3821, 0xafa00010, 0xc002403, 0xafa00014,
-0x96e6047a, 0x96e7046a, 0x3c040001, 0x24845250,
+0x96e6047a, 0x96e7046a, 0x3c040001, 0x24845200,
0x24050012, 0xafa00010, 0xc002403, 0xafa00014,
0xc004500, 0x0, 0xc002318, 0x0,
0x3c060001, 0x34c63800, 0xaee00608, 0xaf400228,
@@ -289,7 +289,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
0x2e22021, 0x24020007, 0xac820000, 0x24020001,
0xac820004, 0x54c0000c, 0xaee90608, 0x3c040001,
-0x24845218, 0xafa00010, 0xafa00014, 0x8ee60608,
+0x248451c8, 0xafa00010, 0xafa00014, 0x8ee60608,
0x8f470228, 0x3c050009, 0xc002403, 0x34a5f000,
0x80014a5, 0x0, 0x8f830120, 0x27623800,
0x24660020, 0xc2102b, 0x50400001, 0x27663000,
@@ -314,11 +314,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0x24020012, 0xac820000, 0x24020001, 0xac820004,
-0x14c0001b, 0x0, 0x3c040001, 0x24845220,
+0x14c0001b, 0x0, 0x3c040001, 0x248451d0,
0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228,
0x3c050009, 0xc002403, 0x34a5f001, 0x8ee201b0,
0x24420001, 0xaee201b0, 0x80014a5, 0x8ee201b0,
-0x3c040001, 0x2484522c, 0xafa00014, 0x8ee60608,
+0x3c040001, 0x248451dc, 0xafa00014, 0x8ee60608,
0x8f470228, 0x3c050009, 0xc002403, 0x34a5f005,
0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac,
0x8ee20154, 0x24420001, 0xaee20154, 0xc0014dc,
@@ -340,7 +340,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee07b8c, 0xaee07b84, 0x3c010001, 0x370821,
0xac2083bc, 0x3c010001, 0x370821, 0x3e00008,
0xa02083b9, 0x27bdffd8, 0xafbf0024, 0xafb00020,
-0x8f820054, 0x3c030001, 0x8c635d38, 0x24420067,
+0x8f820054, 0x3c030001, 0x8c635cd8, 0x24420067,
0x1060000d, 0xaf820058, 0x3c020001, 0x571021,
0x904283b8, 0x10400005, 0x3c030200, 0x3c010001,
0x370821, 0x8001503, 0xa02083b8, 0x8ee20000,
@@ -358,7 +358,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x3c030001, 0x771821, 0x8c6383d4,
0x8f8200b4, 0x1462007c, 0x0, 0x3c070001,
0xf73821, 0x8ce783d0, 0x8f8200b0, 0x3c040001,
-0x248452c0, 0xafa00014, 0xafa20010, 0x8f8600b0,
+0x24845270, 0xafa00014, 0xafa20010, 0x8f8600b0,
0x3c050005, 0xc002403, 0x34a50900, 0x8f82011c,
0x34420002, 0xaf82011c, 0x8f830104, 0x8f8200b0,
0x34420001, 0xaf8200b0, 0xaf830104, 0x8f830120,
@@ -386,10 +386,10 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xac820000, 0x24020001, 0xac820004, 0x8f82011c,
0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201e4,
0x3c070001, 0xf73821, 0x8ce783d0, 0x24420001,
-0xaee201e4, 0x8ee201e4, 0x3c040001, 0x248452cc,
+0xaee201e4, 0x8ee201e4, 0x3c040001, 0x2484527c,
0x80015bd, 0xafa00010, 0x8f820104, 0x3c010001,
0x370821, 0xac2283d0, 0x8f8200b4, 0x3c070001,
-0xf73821, 0x8ce783d0, 0x3c040001, 0x248452d4,
+0xf73821, 0x8ce783d0, 0x3c040001, 0x24845284,
0x3c010001, 0x370821, 0xac2283d4, 0xafa00010,
0xafa00014, 0x8f8600b0, 0x3c050005, 0xc002403,
0x34a50900, 0x80015cc, 0x0, 0x8f820104,
@@ -422,7 +422,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020012, 0xac820000,
0x24020001, 0xac820004, 0x5600000b, 0x24100001,
-0x8ee204e4, 0x3c040001, 0x248452dc, 0xafa00014,
+0x8ee204e4, 0x3c040001, 0x2484528c, 0xafa00014,
0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009,
0xc002403, 0x34a5f006, 0x16000003, 0x24020001,
0x8001650, 0xa2e204f4, 0x8ee20170, 0x24420001,
@@ -452,7 +452,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0x24020012, 0xac820000, 0x24020001, 0xac820004,
0x5600000b, 0x24100001, 0x8ee2724c, 0x3c040001,
-0x248452e8, 0xafa00014, 0xafa20010, 0x8ee6724c,
+0x24845298, 0xafa00014, 0xafa20010, 0x8ee6724c,
0x8f470280, 0x3c050009, 0xc002403, 0x34a5f008,
0x56000001, 0xaee00e1c, 0x8ee20174, 0x24420001,
0xaee20174, 0x8ee20174, 0x8ee24e24, 0x10400019,
@@ -563,11 +563,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6,
0x0, 0x316300ff, 0x24020001, 0x14620003,
0x3c050009, 0x800197c, 0x24100001, 0x3c040001,
-0x248452f4, 0xafa00010, 0xafa00014, 0x8f860120,
+0x248452a4, 0xafa00010, 0xafa00014, 0x8f860120,
0x8f870124, 0x800187b, 0x34a5f011, 0x3c040001,
-0x24845300, 0xafa00010, 0xafa00014, 0x8f860120,
+0x248452b0, 0xafa00010, 0xafa00014, 0x8f860120,
0x8f870124, 0x34a5f010, 0xc002403, 0x8021,
-0x800197c, 0x0, 0x3c040001, 0x2484530c,
+0x800197c, 0x0, 0x3c040001, 0x248452bc,
0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
0x8001975, 0x34a5f00f, 0x8ee20608, 0x8f430228,
0x24420001, 0x304900ff, 0x512300e2, 0xafa00010,
@@ -598,7 +598,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020007, 0xac820000,
0x24020001, 0xac820004, 0x5600000c, 0xaee90608,
-0x3c040001, 0x24845318, 0xafa00010, 0xafa00014,
+0x3c040001, 0x248452c8, 0xafa00010, 0xafa00014,
0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
0x34a5f000, 0x800197c, 0x0, 0x8f830120,
0x27623800, 0x24660020, 0xc2102b, 0x50400001,
@@ -624,10 +624,10 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
0x2e22021, 0x24020012, 0xac820000, 0x24020001,
0xac820004, 0x5600001d, 0x24100001, 0x3c040001,
-0x24845320, 0xafa00010, 0xafa00014, 0x8ee60608,
+0x248452d0, 0xafa00010, 0xafa00014, 0x8ee60608,
0x8f470228, 0x3c050009, 0xc002403, 0x34a5f001,
0x8ee201b0, 0x24420001, 0xaee201b0, 0x800197c,
-0x8ee201b0, 0x3c040001, 0x2484532c, 0xafa00014,
+0x8ee201b0, 0x3c040001, 0x248452dc, 0xafa00014,
0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f005,
0xc002403, 0x0, 0x8ee201ac, 0x8021,
0x24420001, 0xaee201ac, 0x8ee201ac, 0x1200000c,
@@ -635,7 +635,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f420238, 0x8ee30158, 0x24630001, 0xaee30158,
0x8ee30158, 0x800198c, 0xaee27278, 0x24020001,
0x3c010001, 0x370821, 0xa02283b0, 0x3c020001,
-0x8c425d38, 0x10400187, 0x0, 0x8ee27b84,
+0x8c425cd8, 0x10400187, 0x0, 0x8ee27b84,
0x24430001, 0x284200c9, 0x144001a4, 0xaee37b84,
0x8ee204d4, 0x30420002, 0x14400119, 0xaee07b84,
0x8ee204d4, 0x3c030600, 0x34631000, 0x34420002,
@@ -699,12 +699,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x56000006, 0x240b0001, 0x8f820054, 0x1221023,
0x2c420033, 0x1440ffa6, 0x0, 0x316300ff,
0x24020001, 0x10620022, 0x0, 0x3c040001,
-0x248452f4, 0xafa00010, 0xafa00014, 0x8f860120,
+0x248452a4, 0xafa00010, 0xafa00014, 0x8f860120,
0x8f870124, 0x3c050009, 0xc002403, 0x34a5f011,
-0x8001aad, 0x0, 0x3c040001, 0x24845300,
+0x8001aad, 0x0, 0x3c040001, 0x248452b0,
0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
0xc002403, 0x34a5f010, 0x8001aad, 0x0,
-0x3c040001, 0x2484530c, 0xafa00014, 0x8ee60608,
+0x3c040001, 0x248452bc, 0xafa00014, 0x8ee60608,
0x8f470228, 0x3c050009, 0xc002403, 0x34a5f00f,
0x8ee201ac, 0x24420001, 0xaee201ac, 0x8ee201ac,
0x8ee2015c, 0x24420001, 0xaee2015c, 0x8ee2015c,
@@ -741,7 +741,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf820044, 0x8f820044, 0x34420040, 0xaf820044,
0x8ee27b88, 0x24430001, 0x28421389, 0x14400005,
0xaee37b88, 0x8f820044, 0x38420020, 0xaf820044,
-0xaee07b88, 0xc0045f4, 0x0, 0x8fbf0024,
+0xaee07b88, 0xc004603, 0x0, 0x8fbf0024,
0x8fb00020, 0x3e00008, 0x27bd0028, 0x27bdffb8,
0xafbf0044, 0xafb60040, 0xafb5003c, 0xafb40038,
0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028,
@@ -751,18 +751,18 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee2016c, 0x80022f4, 0x8ee2016c, 0x32c20001,
0x10400004, 0x24020001, 0xaf820064, 0x80022f4,
0x0, 0x32c20002, 0x1440000c, 0x3c050003,
-0x3c040001, 0x248453a4, 0x34a50001, 0x2c03021,
+0x3c040001, 0x24845354, 0x34a50001, 0x2c03021,
0x3821, 0xafa00010, 0xc002403, 0xafa00014,
0x2402fff8, 0x80022f4, 0xaf820064, 0x8f43022c,
0x8f42010c, 0x5062000c, 0xafa00010, 0x8f42022c,
0x21080, 0x5a1021, 0x8c420300, 0xafa20020,
0x8f42022c, 0x24070001, 0x24420001, 0x3042003f,
-0x8001b80, 0xaf42022c, 0x3c040001, 0x248453b0,
+0x8001b80, 0xaf42022c, 0x3c040001, 0x24845360,
0xafa00014, 0x8f46022c, 0x8f47010c, 0x3c050003,
0xc002403, 0x34a5f01f, 0x3821, 0x14e00003,
0x0, 0x80022ed, 0xaf960064, 0x93a20020,
0x2443ffff, 0x2c620011, 0x10400658, 0x31080,
-0x3c010001, 0x220821, 0x8c225468, 0x400008,
+0x3c010001, 0x220821, 0x8c225418, 0x400008,
0x0, 0x8fa20020, 0x30420fff, 0xaee20e0c,
0x8f820060, 0x34420200, 0xaf820060, 0x8ee20118,
0x24420001, 0xaee20118, 0x80022e8, 0x8ee20118,
@@ -778,7 +778,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f840054, 0x41442, 0x41c82, 0x431021,
0x41cc2, 0x431023, 0x41d02, 0x431021,
0x41d42, 0x431023, 0x8001bd0, 0xaee20078,
-0x3c040001, 0x248453bc, 0xafa00014, 0x8fa60020,
+0x3c040001, 0x2484536c, 0xafa00014, 0x8fa60020,
0x3c050003, 0xc002403, 0x34a50004, 0x8ee20110,
0x24420001, 0xaee20110, 0x80022e8, 0x8ee20110,
0x27440212, 0xc0022fe, 0x24050006, 0x3049001f,
@@ -794,7 +794,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2c820080, 0x1440fff8, 0x410c0, 0x4c10010,
0x618c0, 0x610c0, 0x571821, 0x8c63737c,
0x571021, 0xafa30010, 0x8c427380, 0x3c040001,
-0x248453c8, 0xafa20014, 0x8f470214, 0x3c050003,
+0x24845378, 0xafa20014, 0x8f470214, 0x3c050003,
0xc002403, 0x34a50013, 0x8001c90, 0x3c020800,
0x97440212, 0x771021, 0xa444737e, 0x8f440214,
0x771021, 0x2e31821, 0xac447380, 0x34028000,
@@ -812,7 +812,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24840001, 0x2c820080, 0x1440fff8, 0x410c0,
0x4c10023, 0x618c0, 0x910c0, 0x571821,
0x8c63727c, 0x571021, 0xafa30010, 0x8c427280,
-0x3c040001, 0x248453d4, 0xafa20014, 0x8f470214,
+0x3c040001, 0x24845384, 0xafa20014, 0x8f470214,
0x3c050003, 0xc002403, 0x34a5f017, 0x8001c90,
0x3c020800, 0x8f430210, 0xb71021, 0xac43777c,
0x8f430214, 0xb71021, 0xac437780, 0x3c020001,
@@ -887,13 +887,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006,
0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
0x1440ffa6, 0x0, 0x316300ff, 0x24020001,
-0x10620022, 0x0, 0x3c040001, 0x248453e0,
+0x10620022, 0x0, 0x3c040001, 0x24845390,
0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
0x3c050009, 0xc002403, 0x34a5f011, 0x8001da0,
-0x0, 0x3c040001, 0x248453ec, 0xafa00014,
+0x0, 0x3c040001, 0x2484539c, 0xafa00014,
0x8f860120, 0x8f870124, 0x3c050009, 0xc002403,
0x34a5f010, 0x8001da0, 0x0, 0x3c040001,
-0x248453f8, 0xafa00014, 0x8ee60608, 0x8f470228,
+0x248453a8, 0xafa00014, 0x8ee60608, 0x8f470228,
0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac,
0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20124,
0x24420001, 0xaee20124, 0x8001f97, 0x8ee20124,
@@ -908,7 +908,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1221004, 0x21027, 0x621824, 0xaf830228,
0x910c0, 0x2e21821, 0x3402c000, 0x8001e4e,
0xa462727c, 0x8f420214, 0xafa20010, 0x910c0,
-0x571021, 0x8c42727c, 0x3c040001, 0x24845404,
+0x571021, 0x8c42727c, 0x3c040001, 0x248453b4,
0x3c050003, 0xafa20014, 0x8f470210, 0x34a5f01c,
0xc002403, 0x1203021, 0x8001e83, 0x3c020800,
0xb71021, 0x9443727e, 0x97420212, 0x14620019,
@@ -936,7 +936,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x910c0, 0x2e41821, 0x3402c000, 0x15000015,
0xa462737c, 0x910c0, 0x2e21821, 0x34028000,
0x8001e4e, 0xa462727c, 0x571021, 0x8c42727c,
-0x3c040001, 0x24845410, 0x3c050003, 0xafa20010,
+0x3c040001, 0x248453c0, 0x3c050003, 0xafa20010,
0x710c0, 0x571021, 0x8c42737c, 0x34a5001e,
0x1203021, 0xc002403, 0xafa20014, 0x8001e83,
0x3c020800, 0x2021, 0x428c0, 0xb71021,
@@ -1012,12 +1012,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001,
0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa6,
0x0, 0x316300ff, 0x24020001, 0x10620022,
-0x0, 0x3c040001, 0x248453e0, 0xafa00010,
+0x0, 0x3c040001, 0x24845390, 0xafa00010,
0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
0xc002403, 0x34a5f011, 0x8001f93, 0x0,
-0x3c040001, 0x248453ec, 0xafa00014, 0x8f860120,
+0x3c040001, 0x2484539c, 0xafa00014, 0x8f860120,
0x8f870124, 0x3c050009, 0xc002403, 0x34a5f010,
-0x8001f93, 0x0, 0x3c040001, 0x248453f8,
+0x8001f93, 0x0, 0x3c040001, 0x248453a8,
0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
0xc002403, 0x34a5f00f, 0x8ee201ac, 0x24420001,
0xaee201ac, 0x8ee201ac, 0x8ee20128, 0x24420001,
@@ -1029,7 +1029,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f820228, 0xaee204dc, 0x2402ffff, 0xaf820228,
0x24020001, 0x8001fbe, 0xa2e204d8, 0x92e204d8,
0x5040000c, 0xa2e004d8, 0x8ee204dc, 0xaf820228,
-0x8001fbe, 0xa2e004d8, 0x3c040001, 0x24845418,
+0x8001fbe, 0xa2e004d8, 0x3c040001, 0x248453c8,
0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403,
0x34a5f009, 0x8ee2013c, 0x24420001, 0xaee2013c,
0x80022e8, 0x8ee2013c, 0x8fa20020, 0x21200,
@@ -1040,7 +1040,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x370821, 0xa02283b2, 0x8001fea, 0xaee40108,
0x8f820220, 0x3c0308ff, 0x3463fff7, 0x431024,
0xaf820220, 0x3c010001, 0x370821, 0xa02083b2,
-0x8001fea, 0xaee40108, 0x3c040001, 0x24845424,
+0x8001fea, 0xaee40108, 0x3c040001, 0x248453d4,
0xafa00014, 0x8fa60020, 0x3c050003, 0xc002403,
0x34a5f00a, 0x8ee2012c, 0x24420001, 0xaee2012c,
0x80022e8, 0x8ee2012c, 0x8fa20020, 0x21200,
@@ -1052,13 +1052,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x571021, 0x904283b2, 0x3c010001, 0x370821,
0x1440000e, 0xa02083b3, 0x8f820220, 0x3c0308ff,
0x3463fff7, 0x431024, 0x8002018, 0xaf820220,
-0x3c040001, 0x24845430, 0xafa00014, 0x8fa60020,
+0x3c040001, 0x248453e0, 0xafa00014, 0x8fa60020,
0x3c050003, 0xc002403, 0x34a5f00b, 0x8ee20114,
0x24420001, 0xaee20114, 0x80022e8, 0x8ee20114,
0x27840208, 0x27450200, 0xc00249a, 0x24060008,
0x26e40094, 0x27450200, 0xc00249a, 0x24060008,
0x8ee20134, 0x24420001, 0xaee20134, 0x80022e8,
-0x8ee20134, 0x8f460248, 0x2021, 0xc0050e0,
+0x8ee20134, 0x8f460248, 0x2021, 0xc005108,
0x24050004, 0x8ee20130, 0x24420001, 0xaee20130,
0x80022e8, 0x8ee20130, 0x8ef301cc, 0x8ef401d0,
0x8ef501d8, 0x8ee20140, 0x26e40030, 0x24420001,
@@ -1072,7 +1072,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee20104, 0xaee40100, 0xaee3010c, 0x8f820220,
0x30420008, 0x10400004, 0x0, 0xaee30108,
0x8002061, 0x2021, 0xaee40108, 0x2021,
-0x3c030001, 0x641821, 0x90635c90, 0x2e41021,
+0x3c030001, 0x641821, 0x90635c30, 0x2e41021,
0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8,
0x0, 0x8f820040, 0x2e41821, 0x24840001,
0x21702, 0x24420030, 0xa062009c, 0x2e41021,
@@ -1152,13 +1152,13 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006,
0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
0x1440ffa6, 0x0, 0x316300ff, 0x24020001,
-0x10620022, 0x0, 0x3c040001, 0x248453e0,
+0x10620022, 0x0, 0x3c040001, 0x24845390,
0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
0x3c050009, 0xc002403, 0x34a5f011, 0x80021c4,
-0x0, 0x3c040001, 0x248453ec, 0xafa00014,
+0x0, 0x3c040001, 0x2484539c, 0xafa00014,
0x8f860120, 0x8f870124, 0x3c050009, 0xc002403,
0x34a5f010, 0x80021c4, 0x0, 0x3c040001,
-0x248453f8, 0xafa00014, 0x8ee60608, 0x8f470228,
+0x248453a8, 0xafa00014, 0x8ee60608, 0x8f470228,
0x3c050009, 0xc002403, 0x34a5f00f, 0x8ee201ac,
0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20120,
0x24420001, 0xaee20120, 0x8ee20120, 0x8ee20168,
@@ -1168,7 +1168,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f820220, 0x30420008, 0x14400002, 0x24020001,
0x24020002, 0xaee20108, 0x8ee2011c, 0x24420001,
0xaee2011c, 0x80022e8, 0x8ee2011c, 0x3c040001,
-0x2484543c, 0xafa00010, 0xafa00014, 0x8fa60020,
+0x248453ec, 0xafa00010, 0xafa00014, 0x8fa60020,
0x3c050003, 0xc002403, 0x34a5f00f, 0x93a20020,
0x3c030700, 0x34631000, 0x431025, 0xafa20018,
0x8ee20608, 0x8f430228, 0x24420001, 0x304900ff,
@@ -1199,7 +1199,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0x24020007, 0xac820000, 0x24020001, 0xac820004,
-0x54e0000c, 0xaee90608, 0x3c040001, 0x24845444,
+0x54e0000c, 0xaee90608, 0x3c040001, 0x248453f4,
0xafa00010, 0xafa00014, 0x8ee60608, 0x8f470228,
0x3c050009, 0xc002403, 0x34a5f000, 0x80022e0,
0x0, 0x8f830120, 0x27623800, 0x24660020,
@@ -1225,11 +1225,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
0x210c0, 0x24425038, 0x2e22021, 0x24020012,
0xac820000, 0x24020001, 0xac820004, 0x14e0001b,
-0x0, 0x3c040001, 0x2484544c, 0xafa00010,
+0x0, 0x3c040001, 0x248453fc, 0xafa00010,
0xafa00014, 0x8ee60608, 0x8f470228, 0x3c050009,
0xc002403, 0x34a5f001, 0x8ee201b0, 0x24420001,
0xaee201b0, 0x80022e0, 0x8ee201b0, 0x3c040001,
-0x24845458, 0xafa00014, 0x8ee60608, 0x8f470228,
+0x24845408, 0xafa00014, 0x8ee60608, 0x8f470228,
0x3c050009, 0xc002403, 0x34a5f005, 0x8ee201ac,
0x24420001, 0xaee201ac, 0x8ee201ac, 0x8ee20150,
0x24420001, 0xaee20150, 0x8ee20150, 0x8ee20160,
@@ -1256,7 +1256,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf82011c, 0x8fbf0010, 0x3e00008, 0x27bd0018,
0x27bdffe0, 0xafbf0018, 0x8f820104, 0xafa20010,
0x8f820100, 0x3c050002, 0xafa20014, 0x8f8600b0,
-0x8f87011c, 0x3c040001, 0x24845510, 0xc002403,
+0x8f87011c, 0x3c040001, 0x248454c0, 0xc002403,
0x34a5f000, 0x8f8300b0, 0x3c027f00, 0x621824,
0x3c020400, 0x10620029, 0x43102b, 0x14400008,
0x3c022000, 0x3c020100, 0x10620024, 0x3c020200,
@@ -1273,7 +1273,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x27bd0020, 0x27bdffe0, 0xafbf001c, 0xafb00018,
0x8f820120, 0xafa20010, 0x8f820124, 0x3c050001,
0xafa20014, 0x8f8600a0, 0x8f87011c, 0x3c040001,
-0x2484551c, 0xc002403, 0x34a5f000, 0x8f8300a0,
+0x248454cc, 0xc002403, 0x34a5f000, 0x8f8300a0,
0x3c027f00, 0x621824, 0x3c020400, 0x10620053,
0x8021, 0x43102b, 0x14400008, 0x3c042000,
0x3c020100, 0x1062004d, 0x3c020200, 0x1062003a,
@@ -1298,43 +1298,43 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee2019c, 0x80023e3, 0x8ee2019c, 0x8f8200a0,
0x34420001, 0xaf8200a0, 0x8fbf001c, 0x8fb00018,
0x3e00008, 0x27bd0020, 0x0, 0x3c020001,
-0x8c425cb8, 0x27bdffe8, 0xafbf0014, 0x14400012,
-0xafb00010, 0x3c100001, 0x26105e30, 0x2002021,
+0x8c425c58, 0x27bdffe8, 0xafbf0014, 0x14400012,
+0xafb00010, 0x3c100001, 0x26105dd0, 0x2002021,
0xc002488, 0x24052000, 0x26021fe0, 0x3c010001,
-0xac225df4, 0x3c010001, 0xac225df0, 0xaf420250,
+0xac225d94, 0x3c010001, 0xac225d90, 0xaf420250,
0x24022000, 0xaf500254, 0xaf420258, 0x24020001,
-0x3c010001, 0xac225cb8, 0x8fbf0014, 0x8fb00010,
-0x3e00008, 0x27bd0018, 0x3c030001, 0x8c635df4,
+0x3c010001, 0xac225c58, 0x8fbf0014, 0x8fb00010,
+0x3e00008, 0x27bd0018, 0x3c030001, 0x8c635d94,
0x8c820000, 0x8fa80010, 0x8fa90014, 0xac620000,
-0x3c020001, 0x8c425df4, 0x8c830004, 0xac430004,
+0x3c020001, 0x8c425d94, 0x8c830004, 0xac430004,
0xac450008, 0x8f840054, 0x2443ffe0, 0xac460010,
0xac470014, 0xac480018, 0xac49001c, 0x3c010001,
-0xac235df4, 0xac44000c, 0x3c020001, 0x24425e30,
+0xac235d94, 0xac44000c, 0x3c020001, 0x24425dd0,
0x62182b, 0x10600005, 0x0, 0x3c020001,
-0x8c425df0, 0x3c010001, 0xac225df4, 0x3c030001,
-0x8c635df4, 0x3c020001, 0x8c425ca0, 0xac620000,
-0x3c030001, 0x8c635df4, 0x3c020001, 0x8c425ca0,
+0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001,
+0x8c635d94, 0x3c020001, 0x8c425c40, 0xac620000,
+0x3c030001, 0x8c635d94, 0x3c020001, 0x8c425c40,
0xac620004, 0x3e00008, 0xaf430250, 0x3c030001,
-0x8c635df4, 0x3c020001, 0x8c425ca0, 0x27bdffd0,
+0x8c635d94, 0x3c020001, 0x8c425c40, 0x27bdffd0,
0xafb40020, 0x8fb40040, 0xafb00010, 0x808021,
0xafb50024, 0x8fb50044, 0x8fa40048, 0xafb10014,
0xa08821, 0xafbf0028, 0xafb3001c, 0xafb20018,
-0xac620000, 0x3c050001, 0x8ca55df4, 0x3c020001,
-0x8c425ca0, 0xc09021, 0xe09821, 0x10800006,
+0xac620000, 0x3c050001, 0x8ca55d94, 0x3c020001,
+0x8c425c40, 0xc09021, 0xe09821, 0x10800006,
0xaca20004, 0x24a50008, 0xc002490, 0x24060018,
0x800244e, 0x0, 0x24a40008, 0xc002488,
-0x24050018, 0x3c020001, 0x8c425df4, 0x3c050001,
-0x24a55e30, 0x2442ffe0, 0x3c010001, 0xac225df4,
+0x24050018, 0x3c020001, 0x8c425d94, 0x3c050001,
+0x24a55dd0, 0x2442ffe0, 0x3c010001, 0xac225d94,
0x45102b, 0x10400005, 0x0, 0x3c020001,
-0x8c425df0, 0x3c010001, 0xac225df4, 0x3c030001,
-0x8c635df4, 0x8e020000, 0xac620000, 0x3c030001,
-0x8c635df4, 0x8e020004, 0xac620004, 0xac710008,
-0x8f840054, 0x2462ffe0, 0x3c010001, 0xac225df4,
+0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001,
+0x8c635d94, 0x8e020000, 0xac620000, 0x3c030001,
+0x8c635d94, 0x8e020004, 0xac620004, 0xac710008,
+0x8f840054, 0x2462ffe0, 0x3c010001, 0xac225d94,
0x45102b, 0xac720010, 0xac730014, 0xac740018,
0xac75001c, 0x10400005, 0xac64000c, 0x3c020001,
-0x8c425df0, 0x3c010001, 0xac225df4, 0x3c030001,
-0x8c635df4, 0x3c020001, 0x8c425ca0, 0xac620000,
-0x3c030001, 0x8c635df4, 0x3c020001, 0x8c425ca0,
+0x8c425d90, 0x3c010001, 0xac225d94, 0x3c030001,
+0x8c635d94, 0x3c020001, 0x8c425c40, 0xac620000,
+0x3c030001, 0x8c635d94, 0x3c020001, 0x8c425c40,
0xac620004, 0xaf430250, 0x8fbf0028, 0x8fb50024,
0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
0x8fb00010, 0x3e00008, 0x27bd0030, 0x10a00005,
@@ -1380,7 +1380,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x210c0, 0x24424e38, 0x2e22021, 0x24020005,
0xac820000, 0x24020001, 0xac820004, 0x1520000a,
0x3c040001, 0xafab0010, 0x8ee27264, 0x3c040001,
-0x24845780, 0x3c050004, 0xafa20014, 0x8ee604e4,
+0x24845730, 0x3c050004, 0xafa20014, 0x8ee604e4,
0x80028be, 0x34a5f114, 0x8ee27264, 0x34843800,
0x3641821, 0x24420010, 0x43102b, 0x14400073,
0x0, 0x8ee27264, 0x24480010, 0x3641021,
@@ -1409,7 +1409,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x210c0, 0x24424e38, 0x2e22021, 0x24020005,
0xac820000, 0x24020001, 0xac820004, 0x1520000a,
0x2508fffc, 0xafab0010, 0x8ee27264, 0x3c040001,
-0x24845780, 0x3c050004, 0xafa20014, 0x8ee604e4,
+0x24845730, 0x3c050004, 0xafa20014, 0x8ee604e4,
0x80028be, 0x34a5f125, 0x34028100, 0xa5020000,
0x9582000e, 0x800261d, 0xa5020002, 0x8f850100,
0x27623000, 0x24a60020, 0xc2102b, 0x50400001,
@@ -1436,7 +1436,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ee24e28, 0x210c0, 0x24424e38, 0x2e22021,
0x24020005, 0xac820000, 0x24020001, 0xac820004,
0x1520000a, 0x34028100, 0xafab0010, 0x8ee27264,
-0x3c040001, 0x24845780, 0x3c050004, 0xafa20014,
+0x3c040001, 0x24845730, 0x3c050004, 0xafa20014,
0x8ee604e4, 0x80028be, 0x34a5f015, 0x8ee37264,
0xa462000c, 0x8ee37264, 0x9582000e, 0xa462000e,
0x8002681, 0x24e70004, 0x8f840100, 0x27623000,
@@ -1462,7 +1462,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
0x24424e38, 0x2e22021, 0x24020005, 0xac820000,
0x24020001, 0xac820004, 0x15200009, 0x3c050004,
-0xafab0010, 0x8ee27264, 0x3c040001, 0x24845780,
+0xafab0010, 0x8ee27264, 0x3c040001, 0x24845730,
0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f004,
0x8ee2725c, 0x30e7ffff, 0x471021, 0xaee2725c,
0x8ee204e4, 0x8ee304fc, 0x8ee47258, 0x21100,
@@ -1482,7 +1482,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f8200f0, 0x24090001, 0x8fa30018, 0x8fa4001c,
0xac430000, 0xac440004, 0xaf8700f0, 0x15200012,
0xd1142, 0x8f8200f0, 0xafa20010, 0x8f8200f4,
-0x3c040001, 0x2484578c, 0xafa20014, 0x8fa60018,
+0x3c040001, 0x2484573c, 0xafa20014, 0x8fa60018,
0x8fa7001c, 0x3c050004, 0xc002403, 0x34a5f005,
0x8ee20088, 0x24420001, 0xaee20088, 0x8ee20088,
0x80028d3, 0xaee0725c, 0x30430003, 0x24020002,
@@ -1524,7 +1524,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
0x2e22021, 0x24020005, 0xac820000, 0x24020001,
0xac820004, 0x1520000a, 0x3c040001, 0xafab0010,
-0x8ee27264, 0x3c040001, 0x24845780, 0x3c050004,
+0x8ee27264, 0x3c040001, 0x24845730, 0x3c050004,
0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f014,
0x8ee27264, 0x34843800, 0x3641821, 0x24420010,
0x43102b, 0x14400073, 0x0, 0x8ee27264,
@@ -1553,7 +1553,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
0x2e22021, 0x24020005, 0xac820000, 0x24020001,
0xac820004, 0x1520000a, 0x2508fffc, 0xafab0010,
-0x8ee27264, 0x3c040001, 0x24845780, 0x3c050004,
+0x8ee27264, 0x3c040001, 0x24845730, 0x3c050004,
0xafa20014, 0x8ee604e4, 0x80028be, 0x34a5f015,
0x34028100, 0xa5020000, 0x9582000e, 0x800285f,
0xa5020002, 0x8f850100, 0x27623000, 0x24a60020,
@@ -1580,7 +1580,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
0x24424e38, 0x2e22021, 0x24020005, 0xac820000,
0x24020001, 0xac820004, 0x1520000a, 0x34028100,
-0xafab0010, 0x8ee27264, 0x3c040001, 0x24845780,
+0xafab0010, 0x8ee27264, 0x3c040001, 0x24845730,
0x3c050004, 0xafa20014, 0x8ee604e4, 0x80028be,
0x34a5f016, 0x8ee37264, 0xa462000c, 0x8ee37264,
0x9582000e, 0xa462000e, 0x80028c2, 0x24e70004,
@@ -1606,7 +1606,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
0x2e22021, 0x24020005, 0xac820000, 0x24020001,
0xac820004, 0x1520000b, 0x3c050004, 0x3c040001,
-0x24845798, 0xafab0010, 0xafa00014, 0x8ee604e4,
+0x24845748, 0xafab0010, 0xafa00014, 0x8ee604e4,
0x34a5f017, 0xc002403, 0x30e7ffff, 0x80028e1,
0x0, 0x8ee27264, 0x3c050001, 0x30e4ffff,
0x441021, 0xaee27264, 0x8ee2725c, 0x8ee37264,
@@ -1672,7 +1672,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e28, 0x8ee24e28, 0x210c0,
0x24424e38, 0x2e22021, 0x24020005, 0xac820000,
0x24020001, 0xac820004, 0x1540000a, 0x24020001,
-0xafa90010, 0x8ee27264, 0x3c040001, 0x24845780,
+0xafa90010, 0x8ee27264, 0x3c040001, 0x24845730,
0x3c050004, 0xafa20014, 0x8ee604e4, 0x8002a4f,
0x34a5f204, 0xa2e204ed, 0x8ee204e8, 0x8ee304fc,
0x8ee47258, 0x3c060001, 0x34c63800, 0x3c010001,
@@ -1706,7 +1706,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e28, 0x8ee24e28, 0x210c0, 0x24424e38,
0x2e22021, 0x24020005, 0xac820000, 0x24020001,
0xac820004, 0x1540000c, 0x30e5ffff, 0x3c040001,
-0x24845798, 0x3c050004, 0xafa90010, 0xafa00014,
+0x24845748, 0x3c050004, 0xafa90010, 0xafa00014,
0x8ee604e4, 0x34a5f237, 0xc002403, 0x30e7ffff,
0x8002a72, 0x0, 0x8ee27264, 0x451021,
0xaee27264, 0x8ee2726c, 0x8ee37264, 0x3c040001,
@@ -1730,7 +1730,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f830108, 0x21140, 0x621821, 0xaf830108,
0xac800000, 0x8cc20018, 0x2443fffe, 0x2c620013,
0x104000c1, 0x31080, 0x3c010001, 0x220821,
-0x8c2257c0, 0x400008, 0x0, 0x8ee204f0,
+0x8c225770, 0x400008, 0x0, 0x8ee204f0,
0x471021, 0xaee204f0, 0x8ee204f0, 0x8f43023c,
0x43102b, 0x144000be, 0x0, 0x8ee304e4,
0x8ee204f8, 0x506200ba, 0xa2e004f4, 0x8f830120,
@@ -1757,7 +1757,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
0x2e22021, 0x24020012, 0xac820000, 0x24020001,
0xac820004, 0x5600000b, 0x24100001, 0x8ee204e4,
-0x3c040001, 0x248457a4, 0xafa00014, 0xafa20010,
+0x3c040001, 0x24845754, 0xafa00014, 0xafa20010,
0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
0x34a5f006, 0x16000003, 0x24020001, 0x8002b71,
0xa2e204f4, 0x8ee20170, 0x24420001, 0xaee20170,
@@ -1778,7 +1778,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8002b71, 0xaee20000, 0x8ee2014c, 0x3c010001,
0x370821, 0xa02083e0, 0x24420001, 0xaee2014c,
0x8002b71, 0x8ee2014c, 0x94c7000e, 0x8cc2001c,
-0x3c040001, 0x248457b0, 0xafa60014, 0xafa20010,
+0x3c040001, 0x24845760, 0xafa60014, 0xafa20010,
0x8cc60018, 0x3c050008, 0xc002403, 0x34a50910,
0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
0x27bdff98, 0xafbf0060, 0xafbe005c, 0xafb60058,
@@ -1787,7 +1787,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa00024, 0x106203e7, 0xafa0002c, 0x3c1e0001,
0x37de3800, 0x3c0bffff, 0x8f930108, 0x8e620018,
0x8f830104, 0x2443fffe, 0x2c620014, 0x104003cf,
-0x31080, 0x3c010001, 0x220821, 0x8c225810,
+0x31080, 0x3c010001, 0x220821, 0x8c2257c0,
0x400008, 0x0, 0x9663000e, 0x8ee2725c,
0x8ee404f0, 0x431021, 0xaee2725c, 0x8e63001c,
0x96e20458, 0x24840001, 0xaee404f0, 0x24630001,
@@ -1816,7 +1816,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
0x2e22021, 0x24020012, 0x240c0001, 0xac820000,
0xac8c0004, 0x5600000d, 0x24100001, 0x8ee204e4,
-0x3c040001, 0x248457a4, 0xafa00014, 0xafa20010,
+0x3c040001, 0x24845754, 0xafa00014, 0xafa20010,
0x8ee60608, 0x8f470228, 0x3c050009, 0x34a5f006,
0xc002403, 0xafab0038, 0x8fab0038, 0x1200030a,
0x240c0001, 0x8002f19, 0x0, 0x966c001c,
@@ -2010,7 +2010,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020012, 0x240c0001,
0xac820000, 0xac8c0004, 0x5600000d, 0x24100001,
-0x8ee204e4, 0x3c040001, 0x248457a4, 0xafa00014,
+0x8ee204e4, 0x3c040001, 0x24845754, 0xafa00014,
0xafa20010, 0x8ee60608, 0x8f470228, 0x3c050009,
0x34a5f006, 0xc002403, 0xafab0038, 0x8fab0038,
0x16000003, 0x240c0001, 0x8002f5c, 0xa2ec04f4,
@@ -2065,7 +2065,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8821, 0x8f8200e4, 0x24110001, 0x8c430000,
0x8c440004, 0xafa30018, 0xafa4001c, 0x1620000e,
0x3c02ffff, 0x8f8200c4, 0xafa20010, 0x8f8200c8,
-0x3c040001, 0x248458c0, 0xafa20014, 0x8f8600e0,
+0x3c040001, 0x24845870, 0xafa20014, 0x8f8600e0,
0x8f8700e4, 0x3c050006, 0xc002403, 0x34a5f000,
0x80034cc, 0x0, 0x8fa3001c, 0x8fb20018,
0x3074ffff, 0x2694fffc, 0x621024, 0x10400058,
@@ -2163,11 +2163,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c,
0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0,
-0xafa20010, 0x8f8200e4, 0x3c040001, 0x248458c8,
+0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845878,
0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006,
0xc002403, 0x34a5f003, 0x80034cc, 0x0,
0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001,
-0x248458d4, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
+0x24845884, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
0x3c050006, 0xc002403, 0x34a5f002, 0x8ee201c0,
0x24420001, 0xaee201c0, 0x8ee20000, 0x8ee301c0,
0x2403ffbf, 0x431024, 0x8003470, 0xaee20000,
@@ -2219,7 +2219,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x50550003, 0x1021, 0x8ee24e30, 0x24420001,
0xaee24e30, 0x8ee24e30, 0x210c0, 0x24425038,
0x2e22021, 0xac960000, 0xac9e0004, 0x16200018,
-0x3c050006, 0x8e020018, 0x3c040001, 0x248458e0,
+0x3c050006, 0x8e020018, 0x3c040001, 0x24845890,
0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009,
0x2003021, 0xc002403, 0xafa30014, 0x93a20037,
0x10400216, 0x340f8100, 0x8e420004, 0x8e430008,
@@ -2252,7 +2252,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x210c0, 0x24425038, 0x2e22021, 0xac960000,
0xac9e0004, 0x1620000d, 0x0, 0xa60c000a,
0xa60a000e, 0x8f820100, 0xafa20010, 0x8f820104,
-0x3c040001, 0x248458ec, 0x3c050006, 0xafa20014,
+0x3c040001, 0x2484589c, 0x3c050006, 0xafa20014,
0x8ee6724c, 0x800343b, 0x34a5f00b, 0x3c010001,
0x370821, 0xa02083c0, 0xadab0000, 0x8ee201d8,
0x8ee3724c, 0x2442ffff, 0xaee201d8, 0x8ee201d8,
@@ -2284,7 +2284,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0xac8e0000, 0xac9e0004, 0x5620000d, 0x24110001,
-0x8ee2724c, 0x3c040001, 0x248458f8, 0xafa00014,
+0x8ee2724c, 0x3c040001, 0x248458a8, 0xafa00014,
0xafa20010, 0x8ee6724c, 0x8f470280, 0x3c050009,
0x34a5f008, 0xc002403, 0xafae0048, 0x8fae0048,
0x56200001, 0xaee00e1c, 0x8ee20188, 0x24420001,
@@ -2311,7 +2311,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ee24e30, 0x24420001, 0xaee24e30, 0x8ee24e30,
0x210c0, 0x24425038, 0x2e22021, 0xac8e0000,
0xac9e0004, 0x1620000d, 0x0, 0x8ee2724c,
-0x3c040001, 0x248458f8, 0xafa00014, 0xafa20010,
+0x3c040001, 0x248458a8, 0xafa00014, 0xafa20010,
0x8ee6724c, 0x8f470280, 0x3c050009, 0x34a5f008,
0xc002403, 0xafae0048, 0x8fae0048, 0x8ee20174,
0x24420001, 0xaee20174, 0x8ee20174, 0x800346e,
@@ -2341,7 +2341,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0xac960000, 0xac9e0004, 0x1620001d, 0x0,
0xa60c000a, 0x8f820100, 0xafa20010, 0x8f820104,
-0x3c040001, 0x248458ec, 0x3c050006, 0xafa20014,
+0x3c040001, 0x2484589c, 0x3c050006, 0xafa20014,
0x8ee6724c, 0x34a5f00d, 0xc002403, 0x2003821,
0x93a20037, 0x10400031, 0x340f8100, 0x8e420004,
0x8e430008, 0x8e44000c, 0xa64f000c, 0xae420000,
@@ -2403,7 +2403,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x10430007, 0x4821, 0x8f8200e4, 0x24090001,
0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c,
0x1520000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010,
-0x8f8200c8, 0x3c040001, 0x248458c0, 0xafa20014,
+0x8f8200c8, 0x3c040001, 0x24845870, 0xafa20014,
0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403,
0x34a5f000, 0x8003850, 0x0, 0x8fa3001c,
0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024,
@@ -2501,15 +2501,15 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c,
0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0,
-0xafa20010, 0x8f8200e4, 0x3c040001, 0x248458c8,
+0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845878,
0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006,
0xc002403, 0x34a5f003, 0x8003850, 0x0,
0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001,
-0x248458d4, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
+0x24845884, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001,
0xaee201c0, 0x8ee20000, 0x8ee301c0, 0x2403ffbf,
0x431024, 0x80037f8, 0xaee20000, 0x8ee25240,
-0xafa20010, 0x8ee25244, 0x3c040001, 0x248458d4,
+0xafa20010, 0x8ee25244, 0x3c040001, 0x24845884,
0xafa20014, 0x8ee60e10, 0x8ee70e18, 0x3c050006,
0xc002403, 0x34a5f002, 0x8ee201c0, 0x24420001,
0xaee201c0, 0x80037f8, 0x8ee201c0, 0x96e20468,
@@ -2568,7 +2568,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020007, 0xac820000,
0x24020001, 0xac820004, 0x15200018, 0x3c050006,
-0x8e020018, 0x3c040001, 0x248458e0, 0xafa20010,
+0x8e020018, 0x3c040001, 0x24845890, 0xafa20010,
0x8e020000, 0x8e030004, 0x34a5f009, 0x2003021,
0xc002403, 0xafa30014, 0x32c200ff, 0x1040002b,
0x34028100, 0x8e430004, 0x8e440008, 0x8e45000c,
@@ -2628,7 +2628,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x10430007, 0x3821, 0x8f8200e4, 0x24070001,
0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c,
0x14e0000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010,
-0x8f8200c8, 0x3c040001, 0x24845904, 0xafa20014,
+0x8f8200c8, 0x3c040001, 0x248458b4, 0xafa20014,
0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc002403,
0x34a5f200, 0x8003c5b, 0x0, 0x8fa3001c,
0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024,
@@ -2726,11 +2726,11 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c,
0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0,
-0xafa20010, 0x8f8200e4, 0x3c040001, 0x24845910,
+0xafa20010, 0x8f8200e4, 0x3c040001, 0x248458c0,
0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006,
0xc002403, 0x34a5f203, 0x8003c5b, 0x0,
0x8ee25240, 0xafa20010, 0x8ee25244, 0x3c040001,
-0x2484591c, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
+0x248458cc, 0xafa20014, 0x8ee60e10, 0x8ee70e18,
0x3c050006, 0xc002403, 0x34a5f202, 0x8ee201c0,
0x24420001, 0xaee201c0, 0x8003c02, 0x8ee201c0,
0x96e20468, 0x53102b, 0x54400001, 0x3c168000,
@@ -2826,7 +2826,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0x24020007, 0xac820000, 0x24020001, 0xac820004,
-0x14e00019, 0x3c050006, 0x3c040001, 0x248458e0,
+0x14e00019, 0x3c050006, 0x3c040001, 0x24845890,
0x8e220018, 0x34a5f209, 0xafa20010, 0x8e220000,
0x8e230004, 0x2203021, 0x1603821, 0xc002403,
0xafa30014, 0x93a2002f, 0x1040002a, 0x34028100,
@@ -2890,7 +2890,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24020001, 0xac620004, 0x1480000e, 0x24030040,
0x8ee20e14, 0xafa20010, 0x8ee20e18, 0x3c050007,
0xafa20014, 0x8ee60e0c, 0x8ee70e10, 0x3c040001,
-0x24845924, 0xc002403, 0x34a5f001, 0x8003cdd,
+0x248458d4, 0xc002403, 0x34a5f001, 0x8003cdd,
0x0, 0x8ee20500, 0x24420001, 0x50430003,
0x1021, 0x8ee20500, 0x24420001, 0xaee20500,
0x8ee20500, 0x21080, 0x571021, 0xac490508,
@@ -2922,7 +2922,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24020003, 0xac620000, 0x24020001, 0xac620004,
0x1480000e, 0x24030040, 0x8ee2523c, 0xafa20010,
0x8ee25244, 0x3c050007, 0xafa20014, 0x8ee65238,
-0x8ee75240, 0x3c040001, 0x24845930, 0xc002403,
+0x8ee75240, 0x3c040001, 0x248458e0, 0xc002403,
0x34a5f010, 0x8003d5f, 0x0, 0x8ee20500,
0x24420001, 0x50430003, 0x1021, 0x8ee20500,
0x24420001, 0xaee20500, 0x8ee20500, 0x21080,
@@ -2942,7 +2942,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f830128, 0x21140, 0x621821, 0xaf830128,
0xaca00000, 0x8cc20018, 0x2443fffe, 0x2c620012,
0x10400008, 0x31080, 0x3c010001, 0x220821,
-0x8c225940, 0x400008, 0x0, 0x24020001,
+0x8c2258f0, 0x400008, 0x0, 0x24020001,
0xaee24e24, 0x3e00008, 0x0, 0x27bdffc8,
0xafbf0030, 0xafb5002c, 0xafb40028, 0xafb30024,
0xafb20020, 0xafb1001c, 0xafb00018, 0x8f830128,
@@ -2951,7 +2951,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24140040, 0x8f8c0128, 0x8f820128, 0x24420020,
0xaf820128, 0x9182001b, 0x8f830128, 0x2443fffe,
0x2c620012, 0x1040029c, 0x31080, 0x3c010001,
-0x220821, 0x8c225998, 0x400008, 0x0,
+0x220821, 0x8c225948, 0x400008, 0x0,
0x8f420218, 0x30420100, 0x10400007, 0x0,
0x95830016, 0x95820018, 0x621823, 0x31402,
0x431021, 0xa5820016, 0x8d82001c, 0x3c038000,
@@ -3052,7 +3052,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020007, 0xac820000,
0x24020001, 0xac820004, 0x1600000d, 0x0,
-0x8f820120, 0x3c040001, 0x24845988, 0xafa00014,
+0x8f820120, 0x3c040001, 0x24845938, 0xafa00014,
0xafa20010, 0x8d86001c, 0x8f870124, 0x3c050008,
0xc002403, 0x34a50001, 0x8004057, 0x0,
0x8ee2724c, 0x24420001, 0x304207ff, 0x11a00006,
@@ -3087,7 +3087,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24420001, 0xaee24e30, 0x8ee24e30, 0x210c0,
0x24425038, 0x2e22021, 0x24020001, 0xac950000,
0xac820004, 0x5600000b, 0x24100001, 0x8ee2724c,
-0x3c040001, 0x248458f8, 0xafa00014, 0xafa20010,
+0x3c040001, 0x248458a8, 0xafa00014, 0xafa20010,
0x8ee6724c, 0x8f470280, 0x3c050009, 0xc002403,
0x34a5f008, 0x56000001, 0xaee00e1c, 0x8ee20188,
0x24420001, 0xaee20188, 0x8004050, 0x8ee20188,
@@ -3113,7 +3113,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1021, 0x8ee24e30, 0x24420001, 0xaee24e30,
0x8ee24e30, 0x210c0, 0x24425038, 0x2e22021,
0x24020001, 0xac950000, 0xac820004, 0x1600000b,
-0x0, 0x8ee2724c, 0x3c040001, 0x248458f8,
+0x0, 0x8ee2724c, 0x3c040001, 0x248458a8,
0xafa00014, 0xafa20010, 0x8ee6724c, 0x8f470280,
0x3c050009, 0xc002403, 0x34a5f008, 0x8ee20174,
0x24420001, 0xaee20174, 0x8004057, 0x8ee20174,
@@ -3125,16 +3125,16 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xc00249a, 0xafb00010, 0x2021, 0x24100001,
0x2402241f, 0xaf900210, 0xaf900200, 0xaf800204,
0xaf820214, 0x8f460248, 0x24030004, 0x3c020040,
-0x3c010001, 0xac235d24, 0x3c010001, 0xac235d28,
-0x3c010001, 0xac205dfc, 0x3c010001, 0xac225d20,
-0x3c010001, 0xac235d28, 0xc0050e0, 0x24050004,
-0xc0047fc, 0x0, 0x8ee20000, 0x3c03feff,
+0x3c010001, 0xac235cc4, 0x3c010001, 0xac235cc8,
+0x3c010001, 0xac205d9c, 0x3c010001, 0xac225cc0,
+0x3c010001, 0xac235cc8, 0xc005108, 0x24050004,
+0xc004822, 0x0, 0x8ee20000, 0x3c03feff,
0x3463fffd, 0x431024, 0xaee20000, 0x3c023c00,
0xaf82021c, 0x3c010001, 0x370821, 0xac3083ac,
0x8fbf0014, 0x8fb00010, 0x3e00008, 0x27bd0018,
0x27bdffe0, 0x3c050008, 0x34a50400, 0xafbf0018,
0xafa00010, 0xafa00014, 0x8f860200, 0x3c040001,
-0x24845a40, 0xc002403, 0x3821, 0x8ee20280,
+0x248459f0, 0xc002403, 0x3821, 0x8ee20280,
0x24420001, 0xaee20280, 0x8ee20280, 0x8f830200,
0x3c023f00, 0x621824, 0x8fbf0018, 0x3c020400,
0x3e00008, 0x27bd0020, 0x27bdffd8, 0xafbf0020,
@@ -3146,16 +3146,16 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaee20218, 0x8ee20218, 0x80040c6, 0x3c03fdff,
0x8ee2021c, 0x24420001, 0xaee2021c, 0x8ee2021c,
0x3c03fdff, 0x3463ffff, 0x3c0808ff, 0x3508ffff,
-0x8ee20000, 0x3c040001, 0x24845a4c, 0x3c050008,
+0x8ee20000, 0x3c040001, 0x248459fc, 0x3c050008,
0x2003021, 0x431024, 0xaee20000, 0x8f820220,
0x3821, 0x3c030300, 0x481024, 0x431025,
0xaf820220, 0xafa00010, 0xc002403, 0xafa00014,
0x8004296, 0x0, 0x2111024, 0x1040001f,
0x3c024000, 0x8f830224, 0x24021402, 0x1462000b,
-0x3c03fdff, 0x3c040001, 0x24845a58, 0x3c050008,
+0x3c03fdff, 0x3c040001, 0x24845a08, 0x3c050008,
0xafa00010, 0xafa00014, 0x8f860224, 0x34a5ffff,
0xc002403, 0x3821, 0x3c03fdff, 0x8ee20000,
-0x3463ffff, 0x2002021, 0x431024, 0xc004e2c,
+0x3463ffff, 0x2002021, 0x431024, 0xc004e54,
0xaee20000, 0x8ee20220, 0x24420001, 0xaee20220,
0x8ee20220, 0x8f820220, 0x3c0308ff, 0x3463ffff,
0x431024, 0x8004295, 0x511025, 0x2021024,
@@ -3226,7 +3226,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x431025, 0xaf820220, 0x8f8600e0, 0x8f8400e4,
0x10c4002a, 0x0, 0x8ee2007c, 0x24420001,
0xaee2007c, 0x8ee2007c, 0x24c2fff8, 0xaf8200e0,
-0x3c020001, 0x8c427e90, 0x3c030008, 0x8f8600e0,
+0x3c020001, 0x8c427e30, 0x3c030008, 0x8f8600e0,
0x431024, 0x1040001d, 0x0, 0x10c4001b,
0x240dfff8, 0x3c0a000a, 0x354af000, 0x3c0c0080,
0x24850008, 0x27622800, 0x50a20001, 0x27651800,
@@ -3262,12 +3262,12 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x621023, 0x2c420002, 0x1440fffc, 0x0,
0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024,
0xaf820220, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x3c020001, 0x8c425d38,
+0x3e00008, 0x27bd0028, 0x3c020001, 0x8c425cd8,
0x27bdffd8, 0x10400012, 0xafbf0020, 0x3c040001,
-0x24845a64, 0x3c050008, 0x24020001, 0x3c010001,
+0x24845a14, 0x3c050008, 0x24020001, 0x3c010001,
0x370821, 0xac2283ac, 0xafa00010, 0xafa00014,
-0x8f860220, 0x34a50498, 0x3c010001, 0xac205d38,
-0x3c010001, 0xac225d2c, 0xc002403, 0x3821,
+0x8f860220, 0x34a50498, 0x3c010001, 0xac205cd8,
+0x3c010001, 0xac225ccc, 0xc002403, 0x3821,
0x8f420268, 0x3c037fff, 0x3463ffff, 0x431024,
0xaf420268, 0x8ee204d0, 0x8ee404d4, 0x2403fffe,
0x431024, 0x30840002, 0x1080011e, 0xaee204d0,
@@ -3333,24 +3333,24 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x54a00006, 0x240b0001, 0x8f820054, 0x1221023,
0x2c420033, 0x1440ffa6, 0x0, 0x316300ff,
0x24020001, 0x54620003, 0xafa00010, 0x80043d6,
-0x0, 0x3c040001, 0x24845a70, 0xafa00014,
+0x0, 0x3c040001, 0x24845a20, 0xafa00014,
0x8f860120, 0x8f870124, 0x3c050009, 0xc002403,
0x34a5f011, 0x80043d6, 0x0, 0x3c040001,
-0x24845a7c, 0xafa00014, 0x8f860120, 0x8f870124,
+0x24845a2c, 0xafa00014, 0x8f860120, 0x8f870124,
0x3c050009, 0xc002403, 0x34a5f010, 0x80043d6,
-0x0, 0x3c040001, 0x24845a88, 0xafa00014,
+0x0, 0x3c040001, 0x24845a38, 0xafa00014,
0x8ee60608, 0x8f470228, 0x3c050009, 0xc002403,
0x34a5f00f, 0x8ee201ac, 0x24420001, 0xaee201ac,
0x8ee201ac, 0x8ee2015c, 0x24420001, 0xaee2015c,
0x8ee2015c, 0x8fbf0020, 0x3e00008, 0x27bd0028,
-0x3c020001, 0x8c425d38, 0x27bdffe0, 0x1440000d,
-0xafbf0018, 0x3c040001, 0x24845a94, 0x3c050008,
+0x3c020001, 0x8c425cd8, 0x27bdffe0, 0x1440000d,
+0xafbf0018, 0x3c040001, 0x24845a44, 0x3c050008,
0xafa00010, 0xafa00014, 0x8f860220, 0x34a50499,
-0x24020001, 0x3c010001, 0xac225d38, 0xc002403,
+0x24020001, 0x3c010001, 0xac225cd8, 0xc002403,
0x3821, 0x8ee204d0, 0x3c030001, 0x771821,
0x946383b2, 0x34420001, 0x10600007, 0xaee204d0,
0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024,
-0x34420008, 0xaf820220, 0x2021, 0xc005276,
+0x34420008, 0xaf820220, 0x2021, 0xc0052a2,
0x24050004, 0xaf420268, 0x8fbf0018, 0x3e00008,
0x27bd0020, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
@@ -3368,7 +3368,7 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x3c120001,
-0x26521200, 0x3c140001, 0x8e945cb0, 0x3c100001,
+0x26521200, 0x3c140001, 0x8e945c50, 0x3c100001,
0x26101120, 0x3c15c000, 0x36b50060, 0x8e8a0000,
0x8eb30000, 0x26a400b, 0x248000a, 0x200f821,
0x0, 0xd, 0x0, 0x0,
@@ -3429,978 +3429,973 @@ u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1062000c, 0x43102b, 0x14400006, 0x3c026000,
0x3c024000, 0x10620008, 0x24020800, 0x8004539,
0x0, 0x10620004, 0x24020800, 0x8004539,
-0x0, 0x24020700, 0x3c010001, 0xac225d3c,
-0x3e00008, 0x0, 0x27bdffd0, 0xafbf0028,
-0x8f830054, 0x8f820054, 0x3c010001, 0xac205d24,
-0x8004544, 0x24630064, 0x8f820054, 0x621023,
-0x2c420065, 0x1440fffc, 0x0, 0xc004d49,
-0x0, 0x24040001, 0x2821, 0x27a60020,
-0x34028000, 0xc004966, 0xa7a20020, 0x8f830054,
-0x8f820054, 0x8004555, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x24040001,
-0x24050001, 0xc004924, 0x27a60020, 0x8f830054,
-0x8f820054, 0x8004561, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x24040001,
-0x24050001, 0xc004924, 0x27a60020, 0x8f830054,
-0x8f820054, 0x800456d, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x24040001,
-0x24050002, 0xc004924, 0x27a60018, 0x8f830054,
-0x8f820054, 0x8004579, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x24040001,
-0x24050003, 0xc004924, 0x27a6001a, 0x3c040001,
-0x24845b00, 0x97a60020, 0x97a70018, 0x97a2001a,
-0x3c05000d, 0x34a50100, 0xafa00014, 0xc002403,
-0xafa20010, 0x97a20020, 0x10400045, 0x24036040,
-0x97a2001a, 0x3042fff0, 0x14430009, 0x24020020,
-0x97a30018, 0x54620008, 0x24027830, 0x24020003,
-0x3c010001, 0xac225d24, 0x80045a4, 0x24020005,
-0x97a30018, 0x24027830, 0x1462000e, 0x24030010,
-0x97a2001a, 0x3042fff0, 0x1443000a, 0x24020003,
-0x3c010001, 0xac225d24, 0x24020006, 0x3c010001,
-0xac225e0c, 0x3c010001, 0xac225e18, 0x80045da,
-0x3c09fff0, 0x3c020001, 0x8c425d24, 0x97a30018,
-0x34420001, 0x3c010001, 0xac225d24, 0x24020015,
-0x1462000e, 0x0, 0x97a2001a, 0x3042fff0,
-0x3843f420, 0x2c630001, 0x3842f430, 0x2c420001,
-0x621825, 0x10600005, 0x24020003, 0x3c010001,
-0xac225e18, 0x80045da, 0x3c09fff0, 0x97a30018,
-0x24027810, 0x1462000a, 0x24020002, 0x97a2001a,
+0x0, 0x24020700, 0x3c010001, 0xac225cdc,
+0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
+0xafb00020, 0x8f830054, 0x8f820054, 0x3c010001,
+0xac205cc4, 0x8004545, 0x24630064, 0x8f820054,
+0x621023, 0x2c420065, 0x1440fffc, 0x0,
+0xc004d71, 0x0, 0x24040001, 0x2821,
+0x27a60018, 0x34028000, 0xc00498e, 0xa7a20018,
+0x8f830054, 0x8f820054, 0x8004556, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
+0x24040001, 0x24050001, 0xc00494c, 0x27a60018,
+0x8f830054, 0x8f820054, 0x8004562, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
+0x24040001, 0x24050001, 0xc00494c, 0x27a60018,
+0x8f830054, 0x8f820054, 0x800456e, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
+0x24040001, 0x3c060001, 0x24c65da0, 0xc00494c,
+0x24050002, 0x8f830054, 0x8f820054, 0x800457b,
+0x24630064, 0x8f820054, 0x621023, 0x2c420065,
+0x1440fffc, 0x24040001, 0x24050003, 0x3c100001,
+0x26105da2, 0xc00494c, 0x2003021, 0x97a60018,
+0x3c070001, 0x94e75da0, 0x3c040001, 0x24845ab0,
+0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100,
+0xc002403, 0xafa20010, 0x97a20018, 0x1040004c,
+0x24036040, 0x96020000, 0x3042fff0, 0x1443000a,
+0x24020020, 0x3c030001, 0x94635da0, 0x54620009,
+0x24027830, 0x24020003, 0x3c010001, 0xac225cc4,
+0x80045ac, 0x24020005, 0x3c030001, 0x94635da0,
+0x24027830, 0x1462000f, 0x24030010, 0x3c020001,
+0x94425da2, 0x3042fff0, 0x1443000a, 0x24020003,
+0x3c010001, 0xac225cc4, 0x24020006, 0x3c010001,
+0xac225db0, 0x3c010001, 0xac225dbc, 0x80045e6,
+0x3c09fff0, 0x3c020001, 0x8c425cc4, 0x3c030001,
+0x94635da0, 0x34420001, 0x3c010001, 0xac225cc4,
+0x24020015, 0x1462000f, 0x0, 0x3c020001,
+0x94425da2, 0x3042fff0, 0x3843f420, 0x2c630001,
+0x3842f430, 0x2c420001, 0x621825, 0x10600005,
+0x24020003, 0x3c010001, 0xac225dbc, 0x80045e6,
+0x3c09fff0, 0x3c030001, 0x94635da0, 0x24027810,
+0x1462000b, 0x24020002, 0x3c020001, 0x94425da2,
0x3042fff0, 0x14400006, 0x24020002, 0x24020004,
-0x3c010001, 0xac225e18, 0x80045da, 0x3c09fff0,
-0x3c010001, 0xac225e18, 0x80045da, 0x3c09fff0,
-0x3c020001, 0x8c425d24, 0x24030001, 0x3c010001,
-0xac235e18, 0x34420004, 0x3c010001, 0xac225d24,
-0x3c09fff0, 0x3529bdc0, 0x8f830054, 0x3c060001,
-0x8cc65d24, 0x3c070001, 0x8ce75e18, 0x97a80018,
-0x3c040001, 0x24845b00, 0x24020001, 0x3c010001,
-0xac225d2c, 0xafa80010, 0x97a2001a, 0x3c05000d,
-0x34a50100, 0x3c010001, 0xac205d28, 0x691821,
-0x3c010001, 0xac235e08, 0xc002403, 0xafa20014,
-0x8fbf0028, 0x3e00008, 0x27bd0030, 0x27bdffe8,
-0x3c050001, 0x8ca55d28, 0x24060004, 0x24020001,
-0x14a20014, 0xafbf0010, 0x3c020001, 0x8c427e9c,
-0x30428000, 0x10400005, 0x3c04000f, 0x3c030001,
-0x8c635e18, 0x8004608, 0x34844240, 0x3c040004,
-0x3c030001, 0x8c635e18, 0x348493e0, 0x24020005,
-0x14620016, 0x0, 0x3c04003d, 0x8004620,
-0x34840900, 0x3c020001, 0x8c427e98, 0x30428000,
-0x10400005, 0x3c04001e, 0x3c030001, 0x8c635e18,
-0x800461b, 0x34848480, 0x3c04000f, 0x3c030001,
-0x8c635e18, 0x34844240, 0x24020005, 0x14620003,
-0x0, 0x3c04007a, 0x34841200, 0x3c020001,
-0x8c425e08, 0x8f830054, 0x441021, 0x431023,
-0x44102b, 0x14400037, 0x0, 0x3c020001,
-0x8c425d30, 0x14400033, 0x0, 0x3c010001,
-0x10c00025, 0xac205d40, 0x3c090001, 0x8d295d24,
-0x24070001, 0x3c044000, 0x3c080001, 0x25087e9c,
-0x250afffc, 0x52842, 0x14a00002, 0x24c6ffff,
-0x24050008, 0xa91024, 0x10400010, 0x0,
-0x14a70008, 0x0, 0x8d020000, 0x441024,
-0x1040000a, 0x0, 0x3c010001, 0x800464c,
-0xac255d40, 0x8d420000, 0x441024, 0x10400003,
-0x0, 0x3c010001, 0xac275d40, 0x3c020001,
-0x8c425d40, 0x6182b, 0x2c420001, 0x431024,
-0x5440ffe5, 0x52842, 0x8f820054, 0x3c030001,
-0x8c635d40, 0x3c010001, 0xac225e08, 0x1060002a,
-0x24020001, 0x3c010001, 0xac255d28, 0x3c010001,
-0xac225d2c, 0x3c020001, 0x8c425d40, 0x10400022,
-0x0, 0x3c020001, 0x8c425d2c, 0x1040000a,
-0x24020001, 0x3c010001, 0xac205d2c, 0x3c010001,
-0x370821, 0xac2283ac, 0x3c010001, 0xac205dac,
-0x3c010001, 0xac225d64, 0x3c030001, 0x771821,
-0x8c6383ac, 0x24020008, 0x10620005, 0x24020001,
-0xc004686, 0x0, 0x8004683, 0x0,
-0x3c030001, 0x8c635d28, 0x10620007, 0x2402000e,
-0x3c030001, 0x8c637e30, 0x10620003, 0x0,
-0xc004e2c, 0x8f840220, 0x8fbf0010, 0x3e00008,
-0x27bd0018, 0x27bdffe0, 0x3c02fdff, 0xafbf001c,
-0xafb00018, 0x8ee30000, 0x3c050001, 0x8ca55d28,
-0x3c040001, 0x8c845d50, 0x3442ffff, 0x621824,
-0x14a40008, 0xaee30000, 0x3c030001, 0x771821,
-0x8c6383ac, 0x3c020001, 0x8c425d54, 0x10620008,
-0x0, 0x3c020001, 0x571021, 0x8c4283ac,
-0x3c010001, 0xac255d50, 0x3c010001, 0xac225d54,
-0x3c030001, 0x8c635d28, 0x24020002, 0x10620150,
-0x2c620003, 0x10400005, 0x24020001, 0x10620008,
-0x0, 0x80047f5, 0x0, 0x24020004,
-0x10620098, 0x24020001, 0x80047f6, 0x0,
-0x3c020001, 0x571021, 0x8c4283ac, 0x2443ffff,
-0x2c620008, 0x10400141, 0x31080, 0x3c010001,
-0x220821, 0x8c225b18, 0x400008, 0x0,
-0x3c030001, 0x8c635e18, 0x24020005, 0x14620014,
-0x0, 0x3c020001, 0x8c425d34, 0x1040000a,
-0x24020003, 0xc0047fc, 0x0, 0x24020002,
+0x3c010001, 0xac225dbc, 0x80045e6, 0x3c09fff0,
+0x3c010001, 0xac225dbc, 0x80045e6, 0x3c09fff0,
+0x3c020001, 0x8c425cc4, 0x24030001, 0x3c010001,
+0xac235dbc, 0x34420004, 0x3c010001, 0xac225cc4,
+0x3c09fff0, 0x3529bdc0, 0x3c060001, 0x8cc65cc4,
+0x3c040001, 0x24845ab0, 0x24020001, 0x3c010001,
+0xac225ccc, 0x8f820054, 0x3c070001, 0x8ce75dbc,
+0x3c030001, 0x94635da0, 0x3c080001, 0x95085da2,
+0x3c05000d, 0x34a50100, 0x3c010001, 0xac205cc8,
+0x491021, 0x3c010001, 0xac225dac, 0xafa30010,
+0xc002403, 0xafa80014, 0x8fbf0024, 0x8fb00020,
+0x3e00008, 0x27bd0028, 0x27bdffe8, 0x3c050001,
+0x8ca55cc8, 0x24060004, 0x24020001, 0x14a20014,
+0xafbf0010, 0x3c020001, 0x8c427e3c, 0x30428000,
+0x10400005, 0x3c04000f, 0x3c030001, 0x8c635dbc,
+0x8004617, 0x34844240, 0x3c040004, 0x3c030001,
+0x8c635dbc, 0x348493e0, 0x24020005, 0x14620016,
+0x0, 0x3c04003d, 0x800462f, 0x34840900,
+0x3c020001, 0x8c427e38, 0x30428000, 0x10400005,
+0x3c04001e, 0x3c030001, 0x8c635dbc, 0x800462a,
+0x34848480, 0x3c04000f, 0x3c030001, 0x8c635dbc,
+0x34844240, 0x24020005, 0x14620003, 0x0,
+0x3c04007a, 0x34841200, 0x3c020001, 0x8c425dac,
+0x8f830054, 0x441021, 0x431023, 0x44102b,
+0x14400037, 0x0, 0x3c020001, 0x8c425cd0,
+0x14400033, 0x0, 0x3c010001, 0x10c00025,
+0xac205ce0, 0x3c090001, 0x8d295cc4, 0x24070001,
+0x3c044000, 0x3c080001, 0x25087e3c, 0x250afffc,
+0x52842, 0x14a00002, 0x24c6ffff, 0x24050008,
+0xa91024, 0x10400010, 0x0, 0x14a70008,
+0x0, 0x8d020000, 0x441024, 0x1040000a,
+0x0, 0x3c010001, 0x800465b, 0xac255ce0,
+0x8d420000, 0x441024, 0x10400003, 0x0,
+0x3c010001, 0xac275ce0, 0x3c020001, 0x8c425ce0,
+0x6182b, 0x2c420001, 0x431024, 0x5440ffe5,
+0x52842, 0x8f820054, 0x3c030001, 0x8c635ce0,
+0x3c010001, 0xac225dac, 0x1060002a, 0x24020001,
+0x3c010001, 0xac255cc8, 0x3c010001, 0xac225ccc,
+0x3c020001, 0x8c425ce0, 0x10400022, 0x0,
+0x3c020001, 0x8c425ccc, 0x1040000a, 0x24020001,
+0x3c010001, 0xac205ccc, 0x3c010001, 0x370821,
+0xac2283ac, 0x3c010001, 0xac205d4c, 0x3c010001,
+0xac225d04, 0x3c030001, 0x771821, 0x8c6383ac,
+0x24020008, 0x10620005, 0x24020001, 0xc004695,
+0x0, 0x8004692, 0x0, 0x3c030001,
+0x8c635cc8, 0x10620007, 0x2402000e, 0x3c030001,
+0x8c637dd0, 0x10620003, 0x0, 0xc004e54,
+0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018,
+0x27bdffe0, 0x3c02fdff, 0xafbf0018, 0x8ee30000,
+0x3c050001, 0x8ca55cc8, 0x3c040001, 0x8c845cf0,
+0x3442ffff, 0x621824, 0x14a40008, 0xaee30000,
+0x3c030001, 0x771821, 0x8c6383ac, 0x3c020001,
+0x8c425cf4, 0x10620008, 0x0, 0x3c020001,
+0x571021, 0x8c4283ac, 0x3c010001, 0xac255cf0,
+0x3c010001, 0xac225cf4, 0x3c030001, 0x8c635cc8,
+0x24020002, 0x10620169, 0x2c620003, 0x10400005,
+0x24020001, 0x10620008, 0x0, 0x800481c,
+0x0, 0x24020004, 0x106200b1, 0x24020001,
+0x800481d, 0x0, 0x3c020001, 0x571021,
+0x8c4283ac, 0x2443ffff, 0x2c620008, 0x1040015a,
+0x31080, 0x3c010001, 0x220821, 0x8c225ac8,
+0x400008, 0x0, 0x3c030001, 0x8c635dbc,
+0x24020005, 0x14620014, 0x0, 0x3c020001,
+0x8c425cd4, 0x1040000a, 0x24020003, 0xc004822,
+0x0, 0x24020002, 0x3c010001, 0x370821,
+0xac2283ac, 0x3c010001, 0x80046e0, 0xac205cd4,
0x3c010001, 0x370821, 0xac2283ac, 0x3c010001,
-0x80046d2, 0xac205d34, 0x3c010001, 0x370821,
-0xac2283ac, 0x3c010001, 0x80047f8, 0xac205cc0,
-0xc0047fc, 0x0, 0x3c020001, 0x8c425d34,
-0x3c010001, 0xac205cc0, 0x104000c4, 0x24020002,
+0x800481f, 0xac205c60, 0xc004822, 0x0,
+0x3c020001, 0x8c425cd4, 0x3c010001, 0xac205c60,
+0x104000dd, 0x24020002, 0x3c010001, 0x370821,
+0xac2283ac, 0x3c010001, 0x800481f, 0xac205cd4,
+0x3c030001, 0x8c635dbc, 0x24020005, 0x14620003,
+0x24020001, 0x3c010001, 0xac225d00, 0xc0049cf,
+0x0, 0x3c030001, 0x8c635d00, 0x800478e,
+0x24020011, 0x3c050001, 0x8ca55cc8, 0x3c060001,
+0x8cc67e3c, 0xc005108, 0x2021, 0x24020005,
+0x3c010001, 0xac205cd4, 0x3c010001, 0x370821,
+0x800481f, 0xac2283ac, 0x3c040001, 0x24845abc,
+0x3c05000f, 0x34a50100, 0x3021, 0x3821,
+0xafa00010, 0xc002403, 0xafa00014, 0x800481f,
+0x0, 0x8f820220, 0x3c03f700, 0x431025,
+0x80047b7, 0xaf820220, 0x8f820220, 0x3c030004,
+0x431024, 0x144000a9, 0x24020007, 0x8f830054,
+0x3c020001, 0x8c425da4, 0x2463d8f0, 0x431023,
+0x2c422710, 0x144000f8, 0x24020001, 0x800481d,
+0x0, 0x3c050001, 0x8ca55cc8, 0xc0052a2,
+0x2021, 0xc005386, 0x2021, 0x3c030001,
+0x8c637e34, 0x46100ea, 0x24020001, 0x3c020008,
+0x621024, 0x10400006, 0x0, 0x8f820214,
+0x3c03ffff, 0x431024, 0x8004741, 0x3442251f,
+0x8f820214, 0x3c03ffff, 0x431024, 0x3442241f,
+0xaf820214, 0x8ee20000, 0x3c030200, 0x431025,
+0xaee20000, 0x8f820220, 0x2403fffb, 0x431024,
+0xaf820220, 0x8f820220, 0x34420002, 0xaf820220,
+0x24020008, 0x3c010001, 0x370821, 0xac2283ac,
+0x8f820220, 0x3c030004, 0x431024, 0x14400005,
+0x0, 0x8f820220, 0x3c03f700, 0x431025,
+0xaf820220, 0x3c030001, 0x8c635dbc, 0x24020005,
+0x1462000a, 0x0, 0x3c020001, 0x94425da2,
+0x24429fbc, 0x2c420004, 0x10400004, 0x24040018,
+0x24050002, 0xc004d93, 0x24060020, 0xc0043dd,
+0x0, 0x3c010001, 0x800481f, 0xac205d50,
+0x3c020001, 0x571021, 0x8c4283ac, 0x2443ffff,
+0x2c620008, 0x104000ac, 0x31080, 0x3c010001,
+0x220821, 0x8c225ae8, 0x400008, 0x0,
+0xc00429b, 0x0, 0x3c010001, 0xac205ccc,
+0xaf800204, 0x3c010001, 0xc004822, 0xac207e20,
+0x24020001, 0x3c010001, 0xac225ce4, 0x24020002,
+0x3c010001, 0x370821, 0x800481f, 0xac2283ac,
+0xc00489f, 0x0, 0x3c030001, 0x8c635ce4,
+0x24020009, 0x14620090, 0x24020003, 0x3c010001,
+0x370821, 0x800481f, 0xac2283ac, 0x3c020001,
+0x8c427e38, 0x30424000, 0x10400005, 0x0,
+0x8f820044, 0x3c03ffff, 0x800479f, 0x34637fff,
+0x8f820044, 0x2403ff7f, 0x431024, 0xaf820044,
+0x8f830054, 0x80047b9, 0x24020004, 0x8f830054,
+0x3c020001, 0x8c425da4, 0x2463d8f0, 0x431023,
+0x2c422710, 0x14400074, 0x24020005, 0x3c010001,
+0x370821, 0x800481f, 0xac2283ac, 0x8f820220,
+0x3c03f700, 0x431025, 0xaf820220, 0xaf800204,
+0x3c010001, 0xac207e20, 0x8f830054, 0x24020006,
0x3c010001, 0x370821, 0xac2283ac, 0x3c010001,
-0x80047f8, 0xac205d34, 0x24020001, 0x3c010001,
-0xc0049a7, 0xac225d60, 0x3c030001, 0x8c635d60,
-0x8004767, 0x24020011, 0x3c020001, 0x8c425e18,
-0x24100005, 0x10500007, 0x0, 0x3c050001,
-0x8ca55d28, 0x3c060001, 0x8cc67e9c, 0xc0050e0,
-0x2021, 0x3c010001, 0xac205d34, 0x3c010001,
-0x370821, 0x80047f8, 0xac3083ac, 0x3c040001,
-0x24845b0c, 0x3c05000f, 0x34a50100, 0x3021,
-0x3821, 0xafa00010, 0xc002403, 0xafa00014,
-0x80047f8, 0x0, 0x8f820220, 0x3c03f700,
-0x431025, 0x8004790, 0xaf820220, 0x8f820220,
-0x3c030004, 0x431024, 0x14400091, 0x24020007,
-0x8f830054, 0x3c020001, 0x8c425e00, 0x2463d8f0,
-0x431023, 0x2c422710, 0x144000e0, 0x24020001,
-0x80047f6, 0x0, 0x3c050001, 0x8ca55d28,
-0xc005276, 0x2021, 0xc005397, 0x2021,
-0x3c030001, 0x8c637e94, 0x46100d2, 0x24020001,
-0x3c020008, 0x621024, 0x10400006, 0x0,
-0x8f820214, 0x3c03ffff, 0x431024, 0x8004732,
-0x3442251f, 0x8f820214, 0x3c03ffff, 0x431024,
-0x3442241f, 0xaf820214, 0x8ee20000, 0x3c030200,
-0x431025, 0xaee20000, 0x8f820220, 0x2403fffb,
-0x431024, 0xaf820220, 0x8f820220, 0x34420002,
-0xaf820220, 0x24020008, 0x3c010001, 0x370821,
-0xc0043dd, 0xac2283ac, 0x3c010001, 0x80047f8,
-0xac205db0, 0x3c020001, 0x571021, 0x8c4283ac,
-0x2443ffff, 0x2c620008, 0x104000ac, 0x31080,
-0x3c010001, 0x220821, 0x8c225b38, 0x400008,
-0x0, 0xc00429b, 0x0, 0x3c010001,
-0xac205d2c, 0xaf800204, 0x3c010001, 0xc0047fc,
-0xac207e80, 0x24020001, 0x3c010001, 0xac225d44,
-0x24020002, 0x3c010001, 0x370821, 0x80047f8,
-0xac2283ac, 0xc004879, 0x0, 0x3c030001,
-0x8c635d44, 0x24020009, 0x14620090, 0x24020003,
-0x3c010001, 0x370821, 0x80047f8, 0xac2283ac,
-0x3c020001, 0x8c427e98, 0x30424000, 0x10400005,
-0x0, 0x8f820044, 0x3c03ffff, 0x8004778,
-0x34637fff, 0x8f820044, 0x2403ff7f, 0x431024,
-0xaf820044, 0x8f830054, 0x8004792, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c425e00, 0x2463d8f0,
-0x431023, 0x2c422710, 0x14400074, 0x24020005,
-0x3c010001, 0x370821, 0x80047f8, 0xac2283ac,
+0x800481f, 0xac235da4, 0x8f830054, 0x3c020001,
+0x8c425da4, 0x2463fff6, 0x431023, 0x2c42000a,
+0x14400059, 0x0, 0x24020007, 0x3c010001,
+0x370821, 0x800481f, 0xac2283ac, 0x8f820220,
+0x3c04f700, 0x441025, 0xaf820220, 0x8f820220,
+0x3c030300, 0x431024, 0x14400005, 0x1821,
+0x8f820220, 0x24030001, 0x441025, 0xaf820220,
+0x10600043, 0x24020001, 0x8f820214, 0x3c03ffff,
+0x3c040001, 0x8c845d98, 0x431024, 0x3442251f,
+0xaf820214, 0x24020008, 0x3c010001, 0x370821,
+0x1080000b, 0xac2283ac, 0x3c020001, 0x8c425d74,
+0x14400007, 0x24020001, 0x3c010001, 0xac227dd0,
+0xc004e54, 0x8f840220, 0x800480c, 0x0,
+0x8f820220, 0x3c030008, 0x431024, 0x14400017,
+0x2402000e, 0x3c010001, 0xac227dd0, 0x8ee20000,
+0x2021, 0x3c030200, 0x431025, 0xc005386,
+0xaee20000, 0x8f820220, 0x2403fffb, 0x431024,
+0xaf820220, 0x8f820220, 0x34420002, 0xc0043dd,
+0xaf820220, 0x3c050001, 0x8ca55cc8, 0xc0052a2,
+0x2021, 0x800481f, 0x0, 0x3c020001,
+0x8c425d74, 0x10400010, 0x0, 0x3c020001,
+0x8c425d70, 0x2442ffff, 0x3c010001, 0xac225d70,
+0x14400009, 0x24020002, 0x3c010001, 0xac205d74,
+0x3c010001, 0x800481f, 0xac225d70, 0x24020001,
+0x3c010001, 0xac225ccc, 0x8fbf0018, 0x3e00008,
+0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220,
+0x34420004, 0xaf820220, 0x8f820200, 0x3c060001,
+0x8cc65cc8, 0x34420004, 0xaf820200, 0x24020002,
+0x10c2003a, 0x2cc20003, 0x10400005, 0x24020001,
+0x10c20008, 0x0, 0x8004868, 0x0,
+0x24020004, 0x10c20013, 0x24020001, 0x8004868,
+0x0, 0x3c030001, 0x8c635cb8, 0x3c020001,
+0x8c425cc0, 0x3c040001, 0x8c845cdc, 0x3c050001,
+0x8ca55cbc, 0xaf860200, 0xaf860220, 0x34630022,
+0x441025, 0x451025, 0x34420002, 0x8004867,
+0xaf830200, 0x3c030001, 0x8c635d98, 0xaf820200,
+0x10600009, 0xaf820220, 0x3c020001, 0x8c425d74,
+0x14400005, 0x3c033f00, 0x3c020001, 0x8c425cb0,
+0x800485b, 0x346300e0, 0x3c020001, 0x8c425cb0,
+0x3c033f00, 0x346300e2, 0x431025, 0xaf820200,
+0x3c030001, 0x8c635cb4, 0x3c04f700, 0x3c020001,
+0x8c425cc0, 0x3c050001, 0x8ca55cdc, 0x641825,
+0x431025, 0x451025, 0xaf820220, 0x3e00008,
+0x0, 0x8f820220, 0x3c030001, 0x8c635cc8,
+0x34420004, 0xaf820220, 0x24020001, 0x1062000f,
+0x0, 0x8f830054, 0x8f820054, 0x24630002,
+0x621023, 0x2c420003, 0x10400011, 0x0,
+0x8f820054, 0x621023, 0x2c420003, 0x1040000c,
+0x0, 0x8004879, 0x0, 0x8f830054,
+0x8f820054, 0x8004885, 0x24630007, 0x8f820054,
+0x621023, 0x2c420008, 0x1440fffc, 0x0,
+0x8f8400e0, 0x30820007, 0x1040000d, 0x0,
+0x8f820054, 0x8f8300e0, 0x14830009, 0x24450032,
+0x8f820054, 0xa21023, 0x2c420033, 0x10400004,
+0x0, 0x8f8200e0, 0x1082fff9, 0x0,
+0x8f820220, 0x2403fffd, 0x431024, 0xaf820220,
+0x3e00008, 0x0, 0x3c030001, 0x8c635ce4,
+0x3c020001, 0x8c425ce8, 0x50620004, 0x2463ffff,
+0x3c010001, 0xac235ce8, 0x2463ffff, 0x2c620009,
+0x1040009d, 0x31080, 0x3c010001, 0x220821,
+0x8c225b08, 0x400008, 0x0, 0x8f820044,
+0x34428080, 0xaf820044, 0x8f830054, 0x8004938,
+0x24020002, 0x8f830054, 0x3c020001, 0x8c425da8,
+0x2463d8f0, 0x431023, 0x2c422710, 0x1440008a,
+0x24020003, 0x8004945, 0x0, 0x8f820044,
+0x3c03ffff, 0x34637fff, 0x431024, 0xaf820044,
+0x8f830054, 0x8004938, 0x24020004, 0x8f830054,
+0x3c020001, 0x8c425da8, 0x2463fff6, 0x431023,
+0x2c42000a, 0x14400078, 0x24020005, 0x8004945,
+0x0, 0x8f820220, 0x3c03f700, 0x431025,
+0xaf820220, 0x8f820220, 0x2403fffb, 0x431024,
+0xaf820220, 0x8f820220, 0x34420002, 0xaf820220,
+0x3c023f00, 0x344200e0, 0xaf820200, 0x8f820200,
+0x2403fffd, 0x431024, 0xaf820200, 0x24040001,
+0x3405ffff, 0xaf840204, 0x8f830054, 0x8f820054,
+0x80048ec, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820224,
+0x42040, 0xa4102b, 0x1040fff2, 0x0,
0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0xaf800204, 0x3c010001, 0xac207e80, 0x8f830054,
-0x24020006, 0x3c010001, 0x370821, 0xac2283ac,
-0x3c010001, 0x80047f8, 0xac235e00, 0x8f830054,
-0x3c020001, 0x8c425e00, 0x2463fff6, 0x431023,
-0x2c42000a, 0x14400059, 0x0, 0x24020007,
-0x3c010001, 0x370821, 0x80047f8, 0xac2283ac,
-0x8f820220, 0x3c04f700, 0x441025, 0xaf820220,
-0x8f820220, 0x3c030300, 0x431024, 0x14400005,
-0x1821, 0x8f820220, 0x24030001, 0x441025,
-0xaf820220, 0x10600043, 0x24020001, 0x8f820214,
-0x3c03ffff, 0x3c040001, 0x8c845df8, 0x431024,
-0x3442251f, 0xaf820214, 0x24020008, 0x3c010001,
-0x370821, 0x1080000b, 0xac2283ac, 0x3c020001,
-0x8c425dd4, 0x14400007, 0x24020001, 0x3c010001,
-0xac227e30, 0xc004e2c, 0x8f840220, 0x80047e5,
-0x0, 0x8f820220, 0x3c030008, 0x431024,
-0x14400017, 0x2402000e, 0x3c010001, 0xac227e30,
-0x8ee20000, 0x2021, 0x3c030200, 0x431025,
-0xc005397, 0xaee20000, 0x8f820220, 0x2403fffb,
-0x431024, 0xaf820220, 0x8f820220, 0x34420002,
-0xc0043dd, 0xaf820220, 0x3c050001, 0x8ca55d28,
-0xc005276, 0x2021, 0x80047f8, 0x0,
-0x3c020001, 0x8c425dd4, 0x10400010, 0x0,
-0x3c020001, 0x8c425dd0, 0x2442ffff, 0x3c010001,
-0xac225dd0, 0x14400009, 0x24020002, 0x3c010001,
-0xac205dd4, 0x3c010001, 0x80047f8, 0xac225dd0,
-0x24020001, 0x3c010001, 0xac225d2c, 0x8fbf001c,
-0x8fb00018, 0x3e00008, 0x27bd0020, 0x8f820200,
-0x8f820220, 0x8f820220, 0x34420004, 0xaf820220,
-0x8f820200, 0x3c060001, 0x8cc65d28, 0x34420004,
-0xaf820200, 0x24020002, 0x10c2003a, 0x2cc20003,
-0x10400005, 0x24020001, 0x10c20008, 0x0,
-0x8004842, 0x0, 0x24020004, 0x10c20013,
-0x24020001, 0x8004842, 0x0, 0x3c030001,
-0x8c635d18, 0x3c020001, 0x8c425d20, 0x3c040001,
-0x8c845d3c, 0x3c050001, 0x8ca55d1c, 0xaf860200,
-0xaf860220, 0x34630022, 0x441025, 0x451025,
-0x34420002, 0x8004841, 0xaf830200, 0x3c030001,
-0x8c635df8, 0xaf820200, 0x10600009, 0xaf820220,
-0x3c020001, 0x8c425dd4, 0x14400005, 0x3c033f00,
-0x3c020001, 0x8c425d10, 0x8004835, 0x346300e0,
-0x3c020001, 0x8c425d10, 0x3c033f00, 0x346300e2,
-0x431025, 0xaf820200, 0x3c030001, 0x8c635d14,
-0x3c04f700, 0x3c020001, 0x8c425d20, 0x3c050001,
-0x8ca55d3c, 0x641825, 0x431025, 0x451025,
-0xaf820220, 0x3e00008, 0x0, 0x8f820220,
-0x3c030001, 0x8c635d28, 0x34420004, 0xaf820220,
-0x24020001, 0x1062000f, 0x0, 0x8f830054,
-0x8f820054, 0x24630002, 0x621023, 0x2c420003,
-0x10400011, 0x0, 0x8f820054, 0x621023,
-0x2c420003, 0x1040000c, 0x0, 0x8004853,
-0x0, 0x8f830054, 0x8f820054, 0x800485f,
-0x24630007, 0x8f820054, 0x621023, 0x2c420008,
-0x1440fffc, 0x0, 0x8f8400e0, 0x30820007,
-0x1040000d, 0x0, 0x8f820054, 0x8f8300e0,
-0x14830009, 0x24450032, 0x8f820054, 0xa21023,
-0x2c420033, 0x10400004, 0x0, 0x8f8200e0,
-0x1082fff9, 0x0, 0x8f820220, 0x2403fffd,
-0x431024, 0xaf820220, 0x3e00008, 0x0,
-0x3c030001, 0x8c635d44, 0x3c020001, 0x8c425d48,
-0x50620004, 0x2463ffff, 0x3c010001, 0xac235d48,
-0x2463ffff, 0x2c620009, 0x1040009d, 0x31080,
-0x3c010001, 0x220821, 0x8c225b58, 0x400008,
-0x0, 0x8f820044, 0x34428080, 0xaf820044,
-0x8f830054, 0x8004912, 0x24020002, 0x8f830054,
-0x3c020001, 0x8c425e04, 0x2463d8f0, 0x431023,
-0x2c422710, 0x1440008a, 0x24020003, 0x800491f,
-0x0, 0x8f820044, 0x3c03ffff, 0x34637fff,
-0x431024, 0xaf820044, 0x8f830054, 0x8004912,
-0x24020004, 0x8f830054, 0x3c020001, 0x8c425e04,
-0x2463fff6, 0x431023, 0x2c42000a, 0x14400078,
-0x24020005, 0x800491f, 0x0, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0x8f820220,
-0x2403fffb, 0x431024, 0xaf820220, 0x8f820220,
-0x34420002, 0xaf820220, 0x3c023f00, 0x344200e0,
-0xaf820200, 0x8f820200, 0x2403fffd, 0x431024,
-0xaf820200, 0x24040001, 0x3405ffff, 0xaf840204,
-0x8f830054, 0x8f820054, 0x80048c6, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820224, 0x42040, 0xa4102b,
-0x1040fff2, 0x0, 0x8f820220, 0x3c03f700,
-0x431025, 0xaf820220, 0x8f820214, 0x3c03ffff,
-0x431024, 0x3442251f, 0xaf820214, 0x8f820220,
-0x2403fffb, 0x431024, 0xaf820220, 0x8f820220,
-0x3c04f700, 0x34840008, 0x34420002, 0xaf820220,
-0x8f820220, 0x3c033f00, 0x346300e2, 0x441025,
-0xaf820220, 0xaf830200, 0x8f8400f0, 0x276217f8,
-0x14820002, 0x24850008, 0x27651000, 0x8f8200f4,
-0x10a20007, 0x3c038000, 0x34630040, 0x3c020001,
-0x24425cd0, 0xac820000, 0xac830004, 0xaf8500f0,
-0x8f830054, 0x8004912, 0x24020006, 0x8f830054,
-0x3c020001, 0x8c425e04, 0x2463fff6, 0x431023,
-0x2c42000a, 0x14400022, 0x24020007, 0x800491f,
-0x0, 0x8f8200e0, 0xaf8200e4, 0x8f8200e0,
-0xaf8200e8, 0x8f820220, 0x34420004, 0xaf820220,
-0x8f820220, 0x2403fff7, 0x431024, 0xaf820220,
-0x8f820044, 0x34428080, 0xaf820044, 0x8f830054,
-0x24020008, 0x3c010001, 0xac225d44, 0x3c010001,
-0x8004921, 0xac235e04, 0x8f830054, 0x3c020001,
-0x8c425e04, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400003, 0x24020009, 0x3c010001, 0xac225d44,
-0x3e00008, 0x0, 0x0, 0x27bdffd8,
+0x8f820214, 0x3c03ffff, 0x431024, 0x3442251f,
+0xaf820214, 0x8f820220, 0x2403fffb, 0x431024,
+0xaf820220, 0x8f820220, 0x3c04f700, 0x34840008,
+0x34420002, 0xaf820220, 0x8f820220, 0x3c033f00,
+0x346300e2, 0x441025, 0xaf820220, 0xaf830200,
+0x8f8400f0, 0x276217f8, 0x14820002, 0x24850008,
+0x27651000, 0x8f8200f4, 0x10a20007, 0x3c038000,
+0x34630040, 0x3c020001, 0x24425c70, 0xac820000,
+0xac830004, 0xaf8500f0, 0x8f830054, 0x8004938,
+0x24020006, 0x8f830054, 0x3c020001, 0x8c425da8,
+0x2463fff6, 0x431023, 0x2c42000a, 0x14400022,
+0x24020007, 0x8004945, 0x0, 0x8f8200e0,
+0xaf8200e4, 0x8f8200e0, 0xaf8200e8, 0x8f820220,
+0x34420004, 0xaf820220, 0x8f820220, 0x2403fff7,
+0x431024, 0xaf820220, 0x8f820044, 0x34428080,
+0xaf820044, 0x8f830054, 0x24020008, 0x3c010001,
+0xac225ce4, 0x3c010001, 0x8004947, 0xac235da8,
+0x8f830054, 0x3c020001, 0x8c425da8, 0x2463d8f0,
+0x431023, 0x2c422710, 0x14400003, 0x24020009,
+0x3c010001, 0xac225ce4, 0x3e00008, 0x0,
+0x0, 0x0, 0x0, 0x27bdffd8,
0xafb20018, 0x809021, 0xafb3001c, 0xa09821,
0xafb10014, 0xc08821, 0xafb00010, 0x8021,
-0xafbf0020, 0xa6200000, 0xc004d23, 0x24040001,
+0xafbf0020, 0xa6200000, 0xc004d4b, 0x24040001,
0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004d23, 0x2021, 0xc004d23, 0x24040001,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x2021, 0xc004d4b, 0x24040001,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x24100010, 0x2501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d23, 0x108042, 0x1600fffa,
+0x24040001, 0xc004d4b, 0x108042, 0x1600fffa,
0x2501024, 0x24100010, 0x2701024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fffa, 0x2701024, 0xc004d49, 0x34108000,
-0xc004d49, 0x0, 0xc004d03, 0x0,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fffa, 0x2701024, 0xc004d71, 0x34108000,
+0xc004d71, 0x0, 0xc004d2b, 0x0,
0x50400005, 0x108042, 0x96220000, 0x501025,
0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004d49, 0x0, 0x8fbf0020, 0x8fb3001c,
+0xc004d71, 0x0, 0x8fbf0020, 0x8fb3001c,
0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008,
0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821,
0xafb20018, 0xa09021, 0xafb3001c, 0xc09821,
-0xafb00010, 0x8021, 0xafbf0020, 0xc004d23,
+0xafb00010, 0x8021, 0xafbf0020, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
0x24040001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
0x1600fffa, 0x2301024, 0x24100010, 0x2501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fffa, 0x2501024, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fffa, 0x2501024, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0x34108000,
0x96620000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d23, 0x108042, 0x1600fff8,
-0x0, 0xc004d49, 0x0, 0x8fbf0020,
+0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
+0x0, 0xc004d71, 0x0, 0x8fbf0020,
0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
-0x3e00008, 0x27bd0028, 0x3c030001, 0x8c635d60,
-0x3c020001, 0x8c425da8, 0x27bdffd8, 0xafbf0020,
+0x3e00008, 0x27bd0028, 0x3c030001, 0x8c635d00,
+0x3c020001, 0x8c425d48, 0x27bdffd8, 0xafbf0020,
0xafb1001c, 0x10620003, 0xafb00018, 0x3c010001,
-0xac235da8, 0x2463ffff, 0x2c620013, 0x10400349,
-0x31080, 0x3c010001, 0x220821, 0x8c225b80,
-0x400008, 0x0, 0xc004d49, 0x8021,
-0x34028000, 0xa7a20010, 0x27b10010, 0xc004d23,
+0xac235d48, 0x2463ffff, 0x2c620013, 0x10400349,
+0x31080, 0x3c010001, 0x220821, 0x8c225b30,
+0x400008, 0x0, 0xc004d71, 0x8021,
+0x34028000, 0xa7a20010, 0x27b10010, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004d23,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0xc004d4b,
0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fff8, 0x0, 0xc004d49, 0x0,
-0x8004cfc, 0x24020002, 0x27b10010, 0xa7a00010,
-0x8021, 0xc004d23, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004d23,
-0x2021, 0xc004d23, 0x24040001, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0x24100010,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fff8, 0x0, 0xc004d71, 0x0,
+0x8004d24, 0x24020002, 0x27b10010, 0xa7a00010,
+0x8021, 0xc004d4b, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004d4b,
+0x2021, 0xc004d4b, 0x24040001, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0x24100010,
0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004d23, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004d49, 0x34108000,
-0xc004d49, 0x0, 0xc004d03, 0x0,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020001,
+0x24100010, 0xc004d4b, 0x2021, 0x108042,
+0x1600fffc, 0x0, 0xc004d71, 0x34108000,
+0xc004d71, 0x0, 0xc004d2b, 0x0,
0x50400005, 0x108042, 0x96220000, 0x501025,
0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004d49, 0x0, 0x97a20010, 0x30428000,
-0x144002dc, 0x24020003, 0x8004cfc, 0x0,
+0xc004d71, 0x0, 0x97a20010, 0x30428000,
+0x144002dc, 0x24020003, 0x8004d24, 0x0,
0x24021200, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0xc004d23, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0xc004d23, 0x24040001, 0xc004d23,
+0xc004d4b, 0x2021, 0x108042, 0x1600fffc,
+0x0, 0xc004d4b, 0x24040001, 0xc004d4b,
0x2021, 0x34108000, 0x96220000, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fff8, 0x0, 0xc004d49,
-0x0, 0x8f830054, 0x8004cee, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c425e14, 0x2463ff9c,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fff8, 0x0, 0xc004d71,
+0x0, 0x8f830054, 0x8004d16, 0x24020004,
+0x8f830054, 0x3c020001, 0x8c425db8, 0x2463ff9c,
0x431023, 0x2c420064, 0x1440029e, 0x24020002,
-0x3c030001, 0x8c635e18, 0x10620297, 0x2c620003,
+0x3c030001, 0x8c635dbc, 0x10620297, 0x2c620003,
0x14400296, 0x24020011, 0x24020003, 0x10620005,
-0x24020004, 0x10620291, 0x2402000f, 0x8004cfc,
-0x24020011, 0x8004cfc, 0x24020005, 0x24020014,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d23,
+0x24020004, 0x10620291, 0x2402000f, 0x8004d24,
+0x24020011, 0x8004d24, 0x24020005, 0x24020014,
+0xa7a20010, 0x27b10010, 0x8021, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x32020012,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fffa, 0x32020012, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fffa, 0x32020012, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0x34108000,
0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d23, 0x108042, 0x1600fff8,
-0x0, 0xc004d49, 0x0, 0x8f830054,
-0x8004cee, 0x24020006, 0x8f830054, 0x3c020001,
-0x8c425e14, 0x2463ff9c, 0x431023, 0x2c420064,
-0x14400250, 0x24020007, 0x8004cfc, 0x0,
+0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
+0x0, 0xc004d71, 0x0, 0x8f830054,
+0x8004d16, 0x24020006, 0x8f830054, 0x3c020001,
+0x8c425db8, 0x2463ff9c, 0x431023, 0x2c420064,
+0x14400250, 0x24020007, 0x8004d24, 0x0,
0x24020006, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020013, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020013,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020013,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fff8, 0x0, 0xc004d49, 0x0,
-0x8f830054, 0x8004cee, 0x24020008, 0x8f830054,
-0x3c020001, 0x8c425e14, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440020f, 0x24020009, 0x8004cfc,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fff8, 0x0, 0xc004d71, 0x0,
+0x8f830054, 0x8004d16, 0x24020008, 0x8f830054,
+0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
+0x2c420064, 0x1440020f, 0x24020009, 0x8004d24,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x24040001,
-0xc004d23, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
+0xc004d4b, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d49, 0x34108000, 0xc004d49, 0x0,
-0xc004d03, 0x0, 0x50400005, 0x108042,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
+0xc004d71, 0x34108000, 0xc004d71, 0x0,
+0xc004d2b, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d49, 0x8021,
+0x1600fff7, 0x0, 0xc004d71, 0x8021,
0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fff8, 0x0, 0xc004d49, 0x0,
-0x8f830054, 0x8004cee, 0x2402000a, 0x8f830054,
-0x3c020001, 0x8c425e14, 0x2463ff9c, 0x431023,
-0x2c420064, 0x1440019b, 0x2402000b, 0x8004cfc,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fff8, 0x0, 0xc004d71, 0x0,
+0x8f830054, 0x8004d16, 0x2402000a, 0x8f830054,
+0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
+0x2c420064, 0x1440019b, 0x2402000b, 0x8004d24,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x24040001,
-0xc004d23, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
+0xc004d4b, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020017,
-0xc004d49, 0x34108000, 0xc004d49, 0x0,
-0xc004d03, 0x0, 0x50400005, 0x108042,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020017,
+0xc004d71, 0x34108000, 0xc004d71, 0x0,
+0xc004d2b, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d49, 0x8021,
+0x1600fff7, 0x0, 0xc004d71, 0x8021,
0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020017,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020017,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fff8, 0x0, 0xc004d49, 0x0,
-0x8f830054, 0x8004cee, 0x2402000c, 0x8f830054,
-0x3c020001, 0x8c425e14, 0x2463ff9c, 0x431023,
-0x2c420064, 0x14400127, 0x24020012, 0x8004cfc,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fff8, 0x0, 0xc004d71, 0x0,
+0x8f830054, 0x8004d16, 0x2402000c, 0x8f830054,
+0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
+0x2c420064, 0x14400127, 0x24020012, 0x8004d24,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x24040001,
-0xc004d23, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
+0xc004d4b, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020014,
-0xc004d49, 0x34108000, 0xc004d49, 0x0,
-0xc004d03, 0x0, 0x50400005, 0x108042,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020014,
+0xc004d71, 0x34108000, 0xc004d71, 0x0,
+0xc004d2b, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d49, 0x8021,
+0x1600fff7, 0x0, 0xc004d71, 0x8021,
0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020014,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020014,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fff8, 0x0, 0xc004d49, 0x0,
-0x8f830054, 0x8004cee, 0x24020013, 0x8f830054,
-0x3c020001, 0x8c425e14, 0x2463ff9c, 0x431023,
-0x2c420064, 0x144000b3, 0x2402000d, 0x8004cfc,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fff8, 0x0, 0xc004d71, 0x0,
+0x8f830054, 0x8004d16, 0x24020013, 0x8f830054,
+0x3c020001, 0x8c425db8, 0x2463ff9c, 0x431023,
+0x2c420064, 0x144000b3, 0x2402000d, 0x8004d24,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x24040001,
-0xc004d23, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x24040001,
+0xc004d4b, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d49, 0x34108000, 0xc004d49, 0x0,
-0xc004d03, 0x0, 0x50400005, 0x108042,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
+0xc004d71, 0x34108000, 0xc004d71, 0x0,
+0xc004d2b, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004d49, 0x8021,
+0x1600fff7, 0x0, 0xc004d71, 0x8021,
0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010,
-0xc004d23, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
-0xc004d23, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
+0xc004d4b, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
+0xc004d4b, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004d23, 0x108042, 0x1600fffa, 0x32020018,
-0xc004d23, 0x24040001, 0xc004d23, 0x2021,
+0xc004d4b, 0x108042, 0x1600fffa, 0x32020018,
+0xc004d4b, 0x24040001, 0xc004d4b, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
-0x1600fff8, 0x0, 0xc004d49, 0x0,
-0x8f830054, 0x8004cee, 0x2402000e, 0x24020840,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004d23,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
+0x1600fff8, 0x0, 0xc004d71, 0x0,
+0x8f830054, 0x8004d16, 0x2402000e, 0x24020840,
+0xa7a20010, 0x27b10010, 0x8021, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x32020013,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fffa, 0x32020013, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fffa, 0x32020013, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0x34108000,
0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d23, 0x108042, 0x1600fff8,
-0x0, 0xc004d49, 0x0, 0x8f830054,
-0x24020010, 0x3c010001, 0xac225d60, 0x3c010001,
-0x8004cfe, 0xac235e14, 0x8f830054, 0x3c020001,
-0x8c425e14, 0x2463ff9c, 0x431023, 0x2c420064,
+0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
+0x0, 0xc004d71, 0x0, 0x8f830054,
+0x24020010, 0x3c010001, 0xac225d00, 0x3c010001,
+0x8004d26, 0xac235db8, 0x8f830054, 0x3c020001,
+0x8c425db8, 0x2463ff9c, 0x431023, 0x2c420064,
0x14400004, 0x0, 0x24020011, 0x3c010001,
-0xac225d60, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
+0xac225d00, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
0x3e00008, 0x27bd0028, 0x8f850044, 0x8f820044,
0x3c030001, 0x431025, 0x3c030008, 0xaf820044,
-0x8f840054, 0x8f820054, 0xa32824, 0x8004d0f,
+0x8f840054, 0x8f820054, 0xa32824, 0x8004d37,
0x24840001, 0x8f820054, 0x821023, 0x2c420002,
0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x8004d1d, 0x24630001, 0x8f820054,
+0x8f820054, 0x8004d45, 0x24630001, 0x8f820054,
0x621023, 0x2c420002, 0x1440fffc, 0x0,
0x3e00008, 0xa01021, 0x8f830044, 0x3c02fff0,
0x3442ffff, 0x42480, 0x621824, 0x3c020002,
0x822025, 0x641825, 0xaf830044, 0x8f820044,
0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
-0x8f830054, 0x8f820054, 0x8004d36, 0x24630001,
+0x8f830054, 0x8f820054, 0x8004d5e, 0x24630001,
0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
0x0, 0x8f820044, 0x3c030001, 0x431025,
-0xaf820044, 0x8f830054, 0x8f820054, 0x8004d43,
+0xaf820044, 0x8f830054, 0x8f820054, 0x8004d6b,
0x24630001, 0x8f820054, 0x621023, 0x2c420002,
0x1440fffc, 0x0, 0x3e00008, 0x0,
0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024,
0xaf820044, 0x8f820044, 0x3c030001, 0x431025,
-0xaf820044, 0x8f830054, 0x8f820054, 0x8004d57,
+0xaf820044, 0x8f830054, 0x8f820054, 0x8004d7f,
0x24630001, 0x8f820054, 0x621023, 0x2c420002,
0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x8004d65, 0x24630001, 0x8f820054,
+0x8f820054, 0x8004d8d, 0x24630001, 0x8f820054,
0x621023, 0x2c420002, 0x1440fffc, 0x0,
0x3e00008, 0x0, 0x27bdffc8, 0xafb30024,
0x809821, 0xafb5002c, 0xa0a821, 0xafb20020,
0xc09021, 0x32a2ffff, 0xafbf0030, 0xafb40028,
0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d23,
+0x3271ffff, 0x27b20010, 0x8021, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fffa, 0x2301024, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0x34108000,
0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d23, 0x108042, 0x12000075,
-0x0, 0x8004da1, 0x0, 0x3274ffff,
-0x27b10010, 0xa7a00010, 0x8021, 0xc004d23,
+0x24040001, 0xc004d4b, 0x108042, 0x12000075,
+0x0, 0x8004dc9, 0x0, 0x3274ffff,
+0x27b10010, 0xa7a00010, 0x8021, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x24040001, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x24040001, 0xc004d4b,
0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x2901024,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fffa, 0x2901024, 0xc004d49,
-0x34108000, 0xc004d49, 0x0, 0xc004d03,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fffa, 0x2901024, 0xc004d71,
+0x34108000, 0xc004d71, 0x0, 0xc004d2b,
0x0, 0x50400005, 0x108042, 0x96220000,
0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004d49, 0x0, 0x32a5ffff,
+0x0, 0xc004d71, 0x0, 0x32a5ffff,
0x24020001, 0x54a20004, 0x24020002, 0x97a20010,
-0x8004dec, 0x521025, 0x14a20006, 0x3271ffff,
+0x8004e14, 0x521025, 0x14a20006, 0x3271ffff,
0x97a20010, 0x121827, 0x431024, 0xa7a20010,
-0x3271ffff, 0x27b20010, 0x8021, 0xc004d23,
+0x3271ffff, 0x27b20010, 0x8021, 0xc004d4b,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004d23, 0x2021, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0xc004d23,
+0x0, 0xc004d4b, 0x2021, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0xc004d4b,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004d23, 0x108042,
+0x2021, 0x24040001, 0xc004d4b, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
-0x10400002, 0x2021, 0x24040001, 0xc004d23,
-0x108042, 0x1600fffa, 0x2301024, 0xc004d23,
-0x24040001, 0xc004d23, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d4b,
+0x108042, 0x1600fffa, 0x2301024, 0xc004d4b,
+0x24040001, 0xc004d4b, 0x2021, 0x34108000,
0x96420000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004d23, 0x108042, 0x1600fff8,
-0x0, 0xc004d49, 0x0, 0x8fbf0030,
+0x24040001, 0xc004d4b, 0x108042, 0x1600fff8,
+0x0, 0xc004d71, 0x0, 0x8fbf0030,
0x8fb5002c, 0x8fb40028, 0x8fb30024, 0x8fb20020,
0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038,
0x0, 0x0, 0x0, 0x27bdffe8,
0xafbf0010, 0x3c030001, 0x771821, 0x8c6383ac,
0x24020008, 0x1462022c, 0x803021, 0x3c020001,
-0x8c425df8, 0x14400033, 0x0, 0x8f850224,
+0x8c425d98, 0x14400033, 0x0, 0x8f850224,
0x38a30020, 0x2c630001, 0x38a20010, 0x2c420001,
0x621825, 0x1460000d, 0x38a30030, 0x2c630001,
0x38a20400, 0x2c420001, 0x621825, 0x14600007,
0x38a30402, 0x2c630001, 0x38a20404, 0x2c420001,
0x621825, 0x10600005, 0x0, 0xc00429b,
-0x0, 0x8004e65, 0x2402000e, 0xc0043dd,
-0x0, 0x3c050001, 0x8ca55d28, 0xc005276,
-0x2021, 0x3c030001, 0x8c635d28, 0x24020004,
-0x14620005, 0x2403fffb, 0x3c020001, 0x8c425d24,
-0x8004e61, 0x2403fff7, 0x3c020001, 0x8c425d24,
-0x431024, 0x3c010001, 0xac225d24, 0x2402000e,
-0x3c010001, 0xc00429b, 0xac227e30, 0x800505f,
+0x0, 0x8004e8d, 0x2402000e, 0xc0043dd,
+0x0, 0x3c050001, 0x8ca55cc8, 0xc0052a2,
+0x2021, 0x3c030001, 0x8c635cc8, 0x24020004,
+0x14620005, 0x2403fffb, 0x3c020001, 0x8c425cc4,
+0x8004e89, 0x2403fff7, 0x3c020001, 0x8c425cc4,
+0x431024, 0x3c010001, 0xac225cc4, 0x2402000e,
+0x3c010001, 0xc00429b, 0xac227dd0, 0x8005087,
0x0, 0x8f820220, 0x3c030400, 0x431024,
0x10400027, 0x2403ffbf, 0x8f850224, 0x3c020001,
-0x8c427e3c, 0xa32024, 0x431024, 0x1482000c,
-0x0, 0x3c020001, 0x8c427e40, 0x24420001,
-0x3c010001, 0xac227e40, 0x2c420002, 0x14400008,
-0x24020001, 0x3c010001, 0x8004e85, 0xac227e60,
-0x3c010001, 0xac207e40, 0x3c010001, 0xac207e60,
-0x3c020001, 0x8c427e60, 0x10400006, 0x30a20040,
-0x10400004, 0x24020001, 0x3c010001, 0x8004e90,
-0xac227e64, 0x3c010001, 0xac207e64, 0x3c010001,
-0xac257e3c, 0x3c010001, 0x8004ea0, 0xac207e70,
-0x24020001, 0x3c010001, 0xac227e70, 0x3c010001,
-0xac207e60, 0x3c010001, 0xac207e40, 0x3c010001,
-0xac207e64, 0x3c010001, 0xac207e3c, 0x3c030001,
-0x8c637e30, 0x3c020001, 0x8c427e34, 0x10620003,
-0x3c020200, 0x3c010001, 0xac237e34, 0xc21024,
+0x8c427ddc, 0xa32024, 0x431024, 0x1482000c,
+0x0, 0x3c020001, 0x8c427de0, 0x24420001,
+0x3c010001, 0xac227de0, 0x2c420002, 0x14400008,
+0x24020001, 0x3c010001, 0x8004ead, 0xac227e00,
+0x3c010001, 0xac207de0, 0x3c010001, 0xac207e00,
+0x3c020001, 0x8c427e00, 0x10400006, 0x30a20040,
+0x10400004, 0x24020001, 0x3c010001, 0x8004eb8,
+0xac227e04, 0x3c010001, 0xac207e04, 0x3c010001,
+0xac257ddc, 0x3c010001, 0x8004ec8, 0xac207e10,
+0x24020001, 0x3c010001, 0xac227e10, 0x3c010001,
+0xac207e00, 0x3c010001, 0xac207de0, 0x3c010001,
+0xac207e04, 0x3c010001, 0xac207ddc, 0x3c030001,
+0x8c637dd0, 0x3c020001, 0x8c427dd4, 0x10620003,
+0x3c020200, 0x3c010001, 0xac237dd4, 0xc21024,
0x10400007, 0x2463ffff, 0x8f820220, 0x24030001,
-0x3c010001, 0xac235d2c, 0x800505d, 0x3c03f700,
+0x3c010001, 0xac235ccc, 0x8005085, 0x3c03f700,
0x2c62000e, 0x104001a8, 0x31080, 0x3c010001,
-0x220821, 0x8c225bd0, 0x400008, 0x0,
-0x3c010001, 0xac207e60, 0x3c010001, 0xac207e40,
-0x3c010001, 0xac207e3c, 0x3c010001, 0xac207e64,
-0x3c010001, 0xac207e58, 0x3c010001, 0xac207e50,
-0xc004844, 0xaf800224, 0x24020002, 0x3c010001,
-0xac227e30, 0x3c020001, 0x8c427e70, 0x14400056,
+0x220821, 0x8c225b80, 0x400008, 0x0,
+0x3c010001, 0xac207e00, 0x3c010001, 0xac207de0,
+0x3c010001, 0xac207ddc, 0x3c010001, 0xac207e04,
+0x3c010001, 0xac207df8, 0x3c010001, 0xac207df0,
+0xc00486a, 0xaf800224, 0x24020002, 0x3c010001,
+0xac227dd0, 0x3c020001, 0x8c427e10, 0x14400056,
0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024,
0xc00429b, 0xaee20000, 0xaf800204, 0x8f820200,
0x2403fffd, 0x431024, 0xaf820200, 0x3c010001,
-0xac207e80, 0x8f830054, 0x3c020001, 0x8c427e58,
-0x24040001, 0x3c010001, 0xac247e6c, 0x24420001,
-0x3c010001, 0xac227e58, 0x2c420004, 0x3c010001,
-0xac237e54, 0x14400006, 0x24020003, 0x3c010001,
-0xac245d2c, 0x3c010001, 0x800505b, 0xac207e58,
-0x3c010001, 0x800505b, 0xac227e30, 0x8f830054,
-0x3c020001, 0x8c427e54, 0x2463d8f0, 0x431023,
+0xac207e20, 0x8f830054, 0x3c020001, 0x8c427df8,
+0x24040001, 0x3c010001, 0xac247e0c, 0x24420001,
+0x3c010001, 0xac227df8, 0x2c420004, 0x3c010001,
+0xac237df4, 0x14400006, 0x24020003, 0x3c010001,
+0xac245ccc, 0x3c010001, 0x8005083, 0xac207df8,
+0x3c010001, 0x8005083, 0xac227dd0, 0x8f830054,
+0x3c020001, 0x8c427df4, 0x2463d8f0, 0x431023,
0x2c422710, 0x14400003, 0x24020004, 0x3c010001,
-0xac227e30, 0x3c020001, 0x8c427e70, 0x14400026,
+0xac227dd0, 0x3c020001, 0x8c427e10, 0x14400026,
0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x431024,
-0x800505b, 0xaee20000, 0x3c040001, 0x8c845dfc,
-0x3c010001, 0xc005062, 0xac207e48, 0x3c020001,
-0x8c427e7c, 0xaf820204, 0x3c020001, 0x8c427e70,
+0x8005083, 0xaee20000, 0x3c040001, 0x8c845d9c,
+0x3c010001, 0xc00508a, 0xac207de8, 0x3c020001,
+0x8c427e1c, 0xaf820204, 0x3c020001, 0x8c427e10,
0x14400015, 0x3c03fdff, 0x8ee20000, 0x3463ffff,
0x431024, 0xaee20000, 0x8f820204, 0x30420030,
-0x1440013c, 0x24020002, 0x3c030001, 0x8c637e7c,
-0x24020005, 0x3c010001, 0xac227e30, 0x3c010001,
-0x800505b, 0xac237e80, 0x3c020001, 0x8c427e70,
-0x10400010, 0x3c03fdff, 0x3c020001, 0x8c425dcc,
-0x24420001, 0x3c010001, 0xac225dcc, 0x2c420002,
-0x14400131, 0x24020001, 0x3c010001, 0xac225dd4,
-0x3c010001, 0xac205dcc, 0x3c010001, 0x800505b,
-0xac225d2c, 0x8ee20000, 0x3463ffff, 0x431024,
-0xaee20000, 0x3c020001, 0x8c427e60, 0x10400122,
-0x0, 0x3c020001, 0x8c427e3c, 0x1040011e,
-0x0, 0x3c010001, 0xac227e68, 0x24020003,
-0x3c010001, 0xac227e40, 0x8004ffc, 0x24020006,
-0x3c010001, 0xac207e48, 0x8f820204, 0x34420040,
-0xaf820204, 0x3c020001, 0x8c427e80, 0x24030007,
-0x3c010001, 0xac237e30, 0x34420040, 0x3c010001,
-0xac227e80, 0x3c020001, 0x8c427e60, 0x10400005,
-0x0, 0x3c020001, 0x8c427e3c, 0x104000f9,
-0x24020002, 0x3c050001, 0x24a57e40, 0x8ca20000,
+0x1440013c, 0x24020002, 0x3c030001, 0x8c637e1c,
+0x24020005, 0x3c010001, 0xac227dd0, 0x3c010001,
+0x8005083, 0xac237e20, 0x3c020001, 0x8c427e10,
+0x10400010, 0x3c03fdff, 0x3c020001, 0x8c425d6c,
+0x24420001, 0x3c010001, 0xac225d6c, 0x2c420002,
+0x14400131, 0x24020001, 0x3c010001, 0xac225d74,
+0x3c010001, 0xac205d6c, 0x3c010001, 0x8005083,
+0xac225ccc, 0x8ee20000, 0x3463ffff, 0x431024,
+0xaee20000, 0x3c020001, 0x8c427e00, 0x10400122,
+0x0, 0x3c020001, 0x8c427ddc, 0x1040011e,
+0x0, 0x3c010001, 0xac227e08, 0x24020003,
+0x3c010001, 0xac227de0, 0x8005024, 0x24020006,
+0x3c010001, 0xac207de8, 0x8f820204, 0x34420040,
+0xaf820204, 0x3c020001, 0x8c427e20, 0x24030007,
+0x3c010001, 0xac237dd0, 0x34420040, 0x3c010001,
+0xac227e20, 0x3c020001, 0x8c427e00, 0x10400005,
+0x0, 0x3c020001, 0x8c427ddc, 0x104000f9,
+0x24020002, 0x3c050001, 0x24a57de0, 0x8ca20000,
0x2c424e21, 0x104000f3, 0x24020002, 0x3c020001,
-0x8c427e64, 0x104000f8, 0x2404ffbf, 0x3c020001,
-0x8c427e3c, 0x3c030001, 0x8c637e68, 0x441024,
+0x8c427e04, 0x104000f8, 0x2404ffbf, 0x3c020001,
+0x8c427ddc, 0x3c030001, 0x8c637e08, 0x441024,
0x641824, 0x10430004, 0x24020001, 0x3c010001,
-0x800505b, 0xac227e30, 0x24020003, 0xaca20000,
-0x24020008, 0x3c010001, 0xac227e30, 0x3c020001,
-0x8c427e6c, 0x1040000c, 0x24020001, 0x3c040001,
-0xc00506f, 0x8c847e3c, 0x3c020001, 0x8c427e88,
-0x14400005, 0x24020001, 0x3c020001, 0x8c427e84,
-0x10400006, 0x24020001, 0x3c010001, 0xac225d2c,
-0x3c010001, 0x800505b, 0xac207e58, 0x3c020001,
-0x8c427e50, 0x3c030001, 0x8c637e3c, 0x2c420001,
-0x210c0, 0x30630008, 0x3c010001, 0xac227e50,
-0x3c010001, 0xac237e4c, 0x8f830054, 0x24020009,
-0x3c010001, 0xac227e30, 0x3c010001, 0x800505b,
-0xac237e54, 0x8f830054, 0x3c020001, 0x8c427e54,
+0x8005083, 0xac227dd0, 0x24020003, 0xaca20000,
+0x24020008, 0x3c010001, 0xac227dd0, 0x3c020001,
+0x8c427e0c, 0x1040000c, 0x24020001, 0x3c040001,
+0xc005097, 0x8c847ddc, 0x3c020001, 0x8c427e28,
+0x14400005, 0x24020001, 0x3c020001, 0x8c427e24,
+0x10400006, 0x24020001, 0x3c010001, 0xac225ccc,
+0x3c010001, 0x8005083, 0xac207df8, 0x3c020001,
+0x8c427df0, 0x3c030001, 0x8c637ddc, 0x2c420001,
+0x210c0, 0x30630008, 0x3c010001, 0xac227df0,
+0x3c010001, 0xac237dec, 0x8f830054, 0x24020009,
+0x3c010001, 0xac227dd0, 0x3c010001, 0x8005083,
+0xac237df4, 0x8f830054, 0x3c020001, 0x8c427df4,
0x2463d8f0, 0x431023, 0x2c422710, 0x144000a8,
-0x0, 0x3c020001, 0x8c427e60, 0x10400005,
-0x0, 0x3c020001, 0x8c427e3c, 0x104000a9,
-0x24020002, 0x3c030001, 0x24637e40, 0x8c620000,
+0x0, 0x3c020001, 0x8c427e00, 0x10400005,
+0x0, 0x3c020001, 0x8c427ddc, 0x104000a9,
+0x24020002, 0x3c030001, 0x24637de0, 0x8c620000,
0x2c424e21, 0x104000a3, 0x24020002, 0x3c020001,
-0x8c427e6c, 0x1040000e, 0x0, 0x3c020001,
-0x8c427e3c, 0x3c010001, 0xac207e6c, 0x30420080,
+0x8c427e0c, 0x1040000e, 0x0, 0x3c020001,
+0x8c427ddc, 0x3c010001, 0xac207e0c, 0x30420080,
0x1040002f, 0x2402000c, 0x8f820204, 0x30420080,
-0x1440000c, 0x24020003, 0x8004fe9, 0x2402000c,
-0x3c020001, 0x8c427e3c, 0x30420080, 0x14400005,
+0x1440000c, 0x24020003, 0x8005011, 0x2402000c,
+0x3c020001, 0x8c427ddc, 0x30420080, 0x14400005,
0x24020003, 0x8f820204, 0x30420080, 0x1040001f,
0x24020003, 0xac620000, 0x2402000a, 0x3c010001,
-0xac227e30, 0x3c040001, 0x24847e78, 0x8c820000,
-0x3c030001, 0x8c637e50, 0x431025, 0xaf820204,
-0x8c830000, 0x3c040001, 0x8c847e50, 0x2402000b,
-0x3c010001, 0xac227e30, 0x641825, 0x3c010001,
-0xac237e80, 0x3c050001, 0x24a57e40, 0x8ca20000,
+0xac227dd0, 0x3c040001, 0x24847e18, 0x8c820000,
+0x3c030001, 0x8c637df0, 0x431025, 0xaf820204,
+0x8c830000, 0x3c040001, 0x8c847df0, 0x2402000b,
+0x3c010001, 0xac227dd0, 0x641825, 0x3c010001,
+0xac237e20, 0x3c050001, 0x24a57de0, 0x8ca20000,
0x2c424e21, 0x1040006f, 0x24020002, 0x3c020001,
-0x8c427e70, 0x10400005, 0x0, 0x2402000c,
-0x3c010001, 0x800505b, 0xac227e30, 0x3c020001,
-0x8c427e60, 0x1040006c, 0x0, 0x3c040001,
-0x8c847e3c, 0x1080005e, 0x30820008, 0x3c030001,
-0x8c637e4c, 0x10620064, 0x24020003, 0x3c010001,
-0xac247e68, 0xaca20000, 0x24020006, 0x3c010001,
-0x800505b, 0xac227e30, 0x8f820200, 0x34420002,
+0x8c427e10, 0x10400005, 0x0, 0x2402000c,
+0x3c010001, 0x8005083, 0xac227dd0, 0x3c020001,
+0x8c427e00, 0x1040006c, 0x0, 0x3c040001,
+0x8c847ddc, 0x1080005e, 0x30820008, 0x3c030001,
+0x8c637dec, 0x10620064, 0x24020003, 0x3c010001,
+0xac247e08, 0xaca20000, 0x24020006, 0x3c010001,
+0x8005083, 0xac227dd0, 0x8f820200, 0x34420002,
0xaf820200, 0x8f830054, 0x2402000d, 0x3c010001,
-0xac227e30, 0x3c010001, 0xac237e54, 0x8f830054,
-0x3c020001, 0x8c427e54, 0x2463d8f0, 0x431023,
+0xac227dd0, 0x3c010001, 0xac237df4, 0x8f830054,
+0x3c020001, 0x8c427df4, 0x2463d8f0, 0x431023,
0x2c422710, 0x1440003a, 0x0, 0x3c020001,
-0x8c427e70, 0x10400029, 0x2402000e, 0x3c030001,
-0x8c637e84, 0x3c010001, 0x14600015, 0xac227e30,
-0xc0043dd, 0x0, 0x3c050001, 0x8ca55d28,
-0xc005276, 0x2021, 0x3c030001, 0x8c635d28,
+0x8c427e10, 0x10400029, 0x2402000e, 0x3c030001,
+0x8c637e24, 0x3c010001, 0x14600015, 0xac227dd0,
+0xc0043dd, 0x0, 0x3c050001, 0x8ca55cc8,
+0xc0052a2, 0x2021, 0x3c030001, 0x8c635cc8,
0x24020004, 0x14620005, 0x2403fffb, 0x3c020001,
-0x8c425d24, 0x800502a, 0x2403fff7, 0x3c020001,
-0x8c425d24, 0x431024, 0x3c010001, 0xac225d24,
+0x8c425cc4, 0x8005052, 0x2403fff7, 0x3c020001,
+0x8c425cc4, 0x431024, 0x3c010001, 0xac225cc4,
0x8ee20000, 0x3c030200, 0x431025, 0xaee20000,
-0x8f820224, 0x3c010001, 0xac227e8c, 0x8f820220,
+0x8f820224, 0x3c010001, 0xac227e2c, 0x8f820220,
0x2403fffb, 0x431024, 0xaf820220, 0x8f820220,
-0x34420002, 0x800505b, 0xaf820220, 0x3c020001,
-0x8c427e60, 0x10400005, 0x0, 0x3c020001,
-0x8c427e3c, 0x1040000f, 0x24020002, 0x3c020001,
-0x8c427e40, 0x2c424e21, 0x1040000a, 0x24020002,
-0x3c020001, 0x8c427e60, 0x1040000f, 0x0,
-0x3c020001, 0x8c427e3c, 0x1440000b, 0x0,
-0x24020002, 0x3c010001, 0x800505b, 0xac227e30,
-0x3c020001, 0x8c427e60, 0x10400003, 0x0,
+0x34420002, 0x8005083, 0xaf820220, 0x3c020001,
+0x8c427e00, 0x10400005, 0x0, 0x3c020001,
+0x8c427ddc, 0x1040000f, 0x24020002, 0x3c020001,
+0x8c427de0, 0x2c424e21, 0x1040000a, 0x24020002,
+0x3c020001, 0x8c427e00, 0x1040000f, 0x0,
+0x3c020001, 0x8c427ddc, 0x1440000b, 0x0,
+0x24020002, 0x3c010001, 0x8005083, 0xac227dd0,
+0x3c020001, 0x8c427e00, 0x10400003, 0x0,
0xc00429b, 0x0, 0x8f820220, 0x3c03f700,
0x431025, 0xaf820220, 0x8fbf0010, 0x3e00008,
-0x27bd0018, 0x3c030001, 0x24637e88, 0x8c620000,
-0x10400005, 0x34422000, 0x3c010001, 0xac227e7c,
-0x800506d, 0xac600000, 0x3c010001, 0xac247e7c,
+0x27bd0018, 0x3c030001, 0x24637e28, 0x8c620000,
+0x10400005, 0x34422000, 0x3c010001, 0xac227e1c,
+0x8005095, 0xac600000, 0x3c010001, 0xac247e1c,
0x3e00008, 0x0, 0x27bdffe0, 0x30820030,
-0xafbf0018, 0x3c010001, 0xac227e84, 0x14400067,
+0xafbf0018, 0x3c010001, 0xac227e24, 0x14400067,
0x3c02ffff, 0x34421f0e, 0x821024, 0x14400061,
0x24020030, 0x30822000, 0x1040005d, 0x30838000,
0x31a02, 0x30820001, 0x21200, 0x3c040001,
-0x8c845dfc, 0x621825, 0x331c2, 0x3c030001,
-0x24635dd8, 0x30828000, 0x21202, 0x30840001,
+0x8c845d9c, 0x621825, 0x331c2, 0x3c030001,
+0x24635d78, 0x30828000, 0x21202, 0x30840001,
0x42200, 0x441025, 0x239c2, 0x61080,
0x431021, 0x471021, 0x90430000, 0x24020001,
0x10620025, 0x0, 0x10600007, 0x24020002,
0x10620013, 0x24020003, 0x1062002c, 0x3c05000f,
-0x80050d1, 0x0, 0x8f820200, 0x2403feff,
+0x80050f9, 0x0, 0x8f820200, 0x2403feff,
0x431024, 0xaf820200, 0x8f820220, 0x3c03fffe,
0x3463ffff, 0x431024, 0xaf820220, 0x3c010001,
-0xac207ea4, 0x3c010001, 0x80050dc, 0xac207eac,
+0xac207e44, 0x3c010001, 0x8005104, 0xac207e4c,
0x8f820200, 0x34420100, 0xaf820200, 0x8f820220,
0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220,
-0x24020100, 0x3c010001, 0xac227ea4, 0x3c010001,
-0x80050dc, 0xac207eac, 0x8f820200, 0x2403feff,
+0x24020100, 0x3c010001, 0xac227e44, 0x3c010001,
+0x8005104, 0xac207e4c, 0x8f820200, 0x2403feff,
0x431024, 0xaf820200, 0x8f820220, 0x3c030001,
-0x431025, 0xaf820220, 0x3c010001, 0xac207ea4,
-0x3c010001, 0x80050dc, 0xac237eac, 0x8f820200,
+0x431025, 0xaf820220, 0x3c010001, 0xac207e44,
+0x3c010001, 0x8005104, 0xac237e4c, 0x8f820200,
0x34420100, 0xaf820200, 0x8f820220, 0x3c030001,
0x431025, 0xaf820220, 0x24020100, 0x3c010001,
-0xac227ea4, 0x3c010001, 0x80050dc, 0xac237eac,
-0x34a5ffff, 0x3c040001, 0x24845c08, 0xafa30010,
-0xc002403, 0xafa00014, 0x80050dc, 0x0,
-0x24020030, 0x3c010001, 0xac227e88, 0x8fbf0018,
+0xac227e44, 0x3c010001, 0x8005104, 0xac237e4c,
+0x34a5ffff, 0x3c040001, 0x24845bb8, 0xafa30010,
+0xc002403, 0xafa00014, 0x8005104, 0x0,
+0x24020030, 0x3c010001, 0xac227e28, 0x8fbf0018,
0x3e00008, 0x27bd0020, 0x0, 0x27bdffc8,
0xafb20028, 0x809021, 0xafb3002c, 0xa09821,
-0xafb00020, 0xc08021, 0x3c040001, 0x24845c20,
-0x3c050009, 0x3c020001, 0x8c425d28, 0x34a59001,
+0xafb00020, 0xc08021, 0x3c040001, 0x24845bd0,
+0x3c050009, 0x3c020001, 0x8c425cc8, 0x34a59001,
0x2403021, 0x2603821, 0xafbf0030, 0xafb10024,
0xa7a0001a, 0xafb00014, 0xc002403, 0xafa20010,
-0x24020002, 0x1262007f, 0x2e620003, 0x10400005,
-0x24020001, 0x1262000a, 0x0, 0x800526f,
-0x0, 0x24020004, 0x126200f6, 0x24020008,
-0x126200f5, 0x3c02ffec, 0x800526f, 0x0,
-0x3c020001, 0x8c425d24, 0x30420002, 0x14400004,
+0x24020002, 0x12620083, 0x2e620003, 0x10400005,
+0x24020001, 0x1262000a, 0x0, 0x800529b,
+0x0, 0x24020004, 0x126200fa, 0x24020008,
+0x126200f9, 0x3c02ffec, 0x800529b, 0x0,
+0x3c020001, 0x8c425cc4, 0x30420002, 0x14400004,
0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024,
-0x3c010001, 0x310821, 0xac307e9c, 0x3c024000,
-0x2021024, 0x1040004a, 0x1023c2, 0x30840030,
-0x101382, 0x3042001c, 0x3c030001, 0x24635d68,
+0x3c010001, 0x310821, 0xac307e3c, 0x3c024000,
+0x2021024, 0x1040004e, 0x1023c2, 0x30840030,
+0x101382, 0x3042001c, 0x3c030001, 0x24635d08,
0x431021, 0x823821, 0x3c020020, 0x2021024,
0x10400006, 0x24020100, 0x3c010001, 0x310821,
-0xac227ea0, 0x8005128, 0x3c020080, 0x3c010001,
-0x310821, 0xac207ea0, 0x3c020080, 0x2021024,
+0xac227e40, 0x8005150, 0x3c020080, 0x3c010001,
+0x310821, 0xac207e40, 0x3c020080, 0x2021024,
0x10400006, 0x121940, 0x3c020001, 0x3c010001,
-0x230821, 0x8005134, 0xac227ea8, 0x121140,
-0x3c010001, 0x220821, 0xac207ea8, 0x94e30000,
-0x32024000, 0x10400003, 0xa7a30018, 0x34624000,
+0x230821, 0x800515c, 0xac227e48, 0x121140,
+0x3c010001, 0x220821, 0xac207e48, 0x94e40000,
+0x3c030001, 0x8c635dbc, 0x24020005, 0x10620010,
+0xa7a40018, 0x32024000, 0x10400002, 0x34824000,
0xa7a20018, 0x24040001, 0x94e20002, 0x24050004,
-0x24e60002, 0x34420001, 0xc004966, 0xa4e20002,
-0x24040001, 0x2821, 0xc004966, 0x27a60018,
-0x3c020001, 0x8c425d28, 0x24110001, 0x3c010001,
-0xac315d34, 0x14530004, 0x32028000, 0xc00429b,
+0x24e60002, 0x34420001, 0xc00498e, 0xa4e20002,
+0x24040001, 0x2821, 0xc00498e, 0x27a60018,
+0x3c020001, 0x8c425cc8, 0x24110001, 0x3c010001,
+0xac315cd4, 0x14530004, 0x32028000, 0xc00429b,
0x0, 0x32028000, 0x1040011f, 0x0,
-0xc00429b, 0x0, 0x3c030001, 0x8c635e18,
+0xc00429b, 0x0, 0x3c030001, 0x8c635dbc,
0x24020005, 0x10620118, 0x24020002, 0x3c010001,
-0xac315d2c, 0x3c010001, 0x800526f, 0xac225d28,
-0x24040001, 0x24050004, 0x27b0001a, 0xc004966,
-0x2003021, 0x24040001, 0x2821, 0xc004966,
-0x2003021, 0x3c020001, 0x511021, 0x8c427e94,
-0x3c040001, 0x8c845d28, 0x3c03bfff, 0x3463ffff,
-0x3c010001, 0xac335d34, 0x431024, 0x3c010001,
-0x310821, 0x109300fa, 0xac227e94, 0x800526f,
+0xac315ccc, 0x3c010001, 0x800529b, 0xac225cc8,
+0x24040001, 0x24050004, 0x27b0001a, 0xc00498e,
+0x2003021, 0x24040001, 0x2821, 0xc00498e,
+0x2003021, 0x3c020001, 0x511021, 0x8c427e34,
+0x3c040001, 0x8c845cc8, 0x3c03bfff, 0x3463ffff,
+0x3c010001, 0xac335cd4, 0x431024, 0x3c010001,
+0x310821, 0x109300fa, 0xac227e34, 0x800529b,
0x0, 0x3c022000, 0x2021024, 0x10400005,
-0x24020001, 0x3c010001, 0xac225df8, 0x8005181,
-0x128940, 0x3c010001, 0xac205df8, 0x128940,
-0x3c010001, 0x310821, 0xac307e98, 0x3c024000,
+0x24020001, 0x3c010001, 0xac225d98, 0x80051ad,
+0x128940, 0x3c010001, 0xac205d98, 0x128940,
+0x3c010001, 0x310821, 0xac307e38, 0x3c024000,
0x2021024, 0x14400016, 0x0, 0x3c020001,
-0x8c425df8, 0x10400008, 0x24040004, 0x24050001,
-0xc004d6b, 0x24062000, 0x24020001, 0x3c010001,
+0x8c425d98, 0x10400008, 0x24040004, 0x24050001,
+0xc004d93, 0x24062000, 0x24020001, 0x3c010001,
0x370821, 0xac2283ac, 0x3c020001, 0x511021,
-0x8c427e90, 0x3c03bfff, 0x3463ffff, 0x431024,
-0x3c010001, 0x310821, 0x800526d, 0xac227e90,
-0x3c020001, 0x8c425df8, 0x10400028, 0x3c0300a0,
+0x8c427e30, 0x3c03bfff, 0x3463ffff, 0x431024,
+0x3c010001, 0x310821, 0x8005299, 0xac227e30,
+0x3c020001, 0x8c425d98, 0x10400028, 0x3c0300a0,
0x2031024, 0x5443000d, 0x3c020020, 0x3c020001,
-0x8c425dfc, 0x24030100, 0x3c010001, 0x310821,
-0xac237ea4, 0x3c030001, 0x3c010001, 0x310821,
-0xac237eac, 0x80051c4, 0x34420400, 0x2021024,
-0x10400008, 0x24030100, 0x3c020001, 0x8c425dfc,
-0x3c010001, 0x310821, 0xac237ea4, 0x80051c4,
+0x8c425d9c, 0x24030100, 0x3c010001, 0x310821,
+0xac237e44, 0x3c030001, 0x3c010001, 0x310821,
+0xac237e4c, 0x80051f0, 0x34420400, 0x2021024,
+0x10400008, 0x24030100, 0x3c020001, 0x8c425d9c,
+0x3c010001, 0x310821, 0xac237e44, 0x80051f0,
0x34420800, 0x3c020080, 0x2021024, 0x1040002e,
-0x3c030001, 0x3c020001, 0x8c425dfc, 0x3c010001,
-0x310821, 0xac237eac, 0x34420c00, 0x3c010001,
-0xac225dfc, 0x80051ec, 0x24040001, 0x3c020020,
+0x3c030001, 0x3c020001, 0x8c425d9c, 0x3c010001,
+0x310821, 0xac237e4c, 0x34420c00, 0x3c010001,
+0xac225d9c, 0x8005218, 0x24040001, 0x3c020020,
0x2021024, 0x10400006, 0x24020100, 0x3c010001,
-0x310821, 0xac227ea4, 0x80051d5, 0x3c020080,
-0x3c010001, 0x310821, 0xac207ea4, 0x3c020080,
+0x310821, 0xac227e44, 0x8005201, 0x3c020080,
+0x3c010001, 0x310821, 0xac207e44, 0x3c020080,
0x2021024, 0x10400007, 0x121940, 0x3c020001,
-0x3c010001, 0x230821, 0xac227eac, 0x80051e3,
+0x3c010001, 0x230821, 0xac227e4c, 0x800520f,
0x24040001, 0x121140, 0x3c010001, 0x220821,
-0xac207eac, 0x24040001, 0x2821, 0x27b0001e,
-0xc004924, 0x2003021, 0x24040001, 0x2821,
-0xc004924, 0x2003021, 0x24040001, 0x24050001,
-0x27b0001c, 0xc004924, 0x2003021, 0x24040001,
-0x24050001, 0xc004924, 0x2003021, 0x800526d,
+0xac207e4c, 0x24040001, 0x2821, 0x27b0001e,
+0xc00494c, 0x2003021, 0x24040001, 0x2821,
+0xc00494c, 0x2003021, 0x24040001, 0x24050001,
+0x27b0001c, 0xc00494c, 0x2003021, 0x24040001,
+0x24050001, 0xc00494c, 0x2003021, 0x8005299,
0x0, 0x3c02ffec, 0x3442ffff, 0x2028024,
0x3c020008, 0x2028025, 0x121140, 0x3c010001,
-0x220821, 0xac307e98, 0x3c022000, 0x2021024,
-0x10400009, 0x0, 0x3c020001, 0x8c425dd4,
-0x14400005, 0x24020001, 0x3c010001, 0xac225df8,
-0x800520e, 0x3c024000, 0x3c010001, 0xac205df8,
+0x220821, 0xac307e38, 0x3c022000, 0x2021024,
+0x10400009, 0x0, 0x3c020001, 0x8c425d74,
+0x14400005, 0x24020001, 0x3c010001, 0xac225d98,
+0x800523a, 0x3c024000, 0x3c010001, 0xac205d98,
0x3c024000, 0x2021024, 0x1440001e, 0x0,
-0x3c020001, 0x8c425df8, 0x3c010001, 0xac205d40,
-0x10400007, 0x24022020, 0x3c010001, 0xac225dfc,
+0x3c020001, 0x8c425d98, 0x3c010001, 0xac205ce0,
+0x10400007, 0x24022020, 0x3c010001, 0xac225d9c,
0x24020001, 0x3c010001, 0x370821, 0xac2283ac,
0x3c04bfff, 0x121940, 0x3c020001, 0x431021,
-0x8c427e90, 0x3c050001, 0x8ca55d28, 0x3484ffff,
-0x441024, 0x3c010001, 0x230821, 0xac227e90,
-0x24020001, 0x10a20044, 0x0, 0x800526d,
-0x0, 0x3c020001, 0x8c425df8, 0x1040001c,
-0x24022000, 0x3c010001, 0xac225dfc, 0x3c0300a0,
+0x8c427e30, 0x3c050001, 0x8ca55cc8, 0x3484ffff,
+0x441024, 0x3c010001, 0x230821, 0xac227e30,
+0x24020001, 0x10a20044, 0x0, 0x8005299,
+0x0, 0x3c020001, 0x8c425d98, 0x1040001c,
+0x24022000, 0x3c010001, 0xac225d9c, 0x3c0300a0,
0x2031024, 0x14430005, 0x121140, 0x3402a000,
-0x3c010001, 0x8005268, 0xac225dfc, 0x3c030001,
-0x621821, 0x8c637e98, 0x3c020020, 0x621024,
-0x10400004, 0x24022001, 0x3c010001, 0x8005268,
-0xac225dfc, 0x3c020080, 0x621024, 0x1040001f,
-0x3402a001, 0x3c010001, 0x8005268, 0xac225dfc,
+0x3c010001, 0x8005294, 0xac225d9c, 0x3c030001,
+0x621821, 0x8c637e38, 0x3c020020, 0x621024,
+0x10400004, 0x24022001, 0x3c010001, 0x8005294,
+0xac225d9c, 0x3c020080, 0x621024, 0x1040001f,
+0x3402a001, 0x3c010001, 0x8005294, 0xac225d9c,
0x3c020020, 0x2021024, 0x10400007, 0x121940,
-0x24020100, 0x3c010001, 0x230821, 0xac227ea4,
-0x800525c, 0x3c020080, 0x121140, 0x3c010001,
-0x220821, 0xac207ea4, 0x3c020080, 0x2021024,
+0x24020100, 0x3c010001, 0x230821, 0xac227e44,
+0x8005288, 0x3c020080, 0x121140, 0x3c010001,
+0x220821, 0xac207e44, 0x3c020080, 0x2021024,
0x10400006, 0x121940, 0x3c020001, 0x3c010001,
-0x230821, 0x8005268, 0xac227eac, 0x121140,
-0x3c010001, 0x220821, 0xac207eac, 0x3c030001,
-0x8c635d28, 0x24020001, 0x10620003, 0x0,
+0x230821, 0x8005294, 0xac227e4c, 0x121140,
+0x3c010001, 0x220821, 0xac207e4c, 0x3c030001,
+0x8c635cc8, 0x24020001, 0x10620003, 0x0,
0xc00429b, 0x0, 0x8fbf0030, 0x8fb3002c,
0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
-0x27bd0038, 0x27bdffc0, 0xafb40038, 0x80a021,
-0xafb20030, 0x9021, 0xafb1002c, 0x8821,
-0x24020002, 0xafbf003c, 0xafb30034, 0xafb00028,
-0xa7a00020, 0xa7a00018, 0xa7a0001a, 0xa7a0001c,
-0x10a20108, 0xa7a0001e, 0x2ca20003, 0x10400005,
-0x24020001, 0x10a2000a, 0x149940, 0x800538f,
-0x2201021, 0x24020004, 0x10a200b2, 0x24020008,
-0x10a200b1, 0x142940, 0x800538f, 0x2201021,
-0x3c030001, 0x731821, 0x8c637e9c, 0x3c024000,
-0x621024, 0x14400009, 0x24040001, 0x3c027fff,
-0x3442ffff, 0x628824, 0x3c010001, 0x330821,
-0xac317e94, 0x800538f, 0x2201021, 0x2821,
-0xc004924, 0x27a60018, 0x24040001, 0x2821,
-0xc004924, 0x27a60018, 0x24040001, 0x24050001,
-0x27b0001a, 0xc004924, 0x2003021, 0x24040001,
-0x24050001, 0xc004924, 0x2003021, 0x24040001,
-0x24050004, 0x27b0001c, 0xc004924, 0x2003021,
-0x24040001, 0x24050004, 0xc004924, 0x2003021,
-0x24040001, 0x24050005, 0x27b0001e, 0xc004924,
-0x2003021, 0x24040001, 0x24050005, 0xc004924,
-0x2003021, 0x24040001, 0x24050009, 0xc004924,
-0x2003021, 0x24040001, 0x24050009, 0xc004924,
-0x2003021, 0x24040001, 0x24050001, 0xc004924,
-0x27a60018, 0x24040001, 0x24050001, 0xc004924,
-0x27a60018, 0x97a20018, 0x30420004, 0x10400034,
-0x3c114000, 0x3c020001, 0x8c425e18, 0x2443ffff,
-0x2c620006, 0x10400034, 0x31080, 0x3c010001,
-0x220821, 0x8c225c38, 0x400008, 0x0,
-0x24040001, 0x24050011, 0x27b00020, 0xc004924,
-0x2003021, 0x24040001, 0x24050011, 0xc004924,
-0x2003021, 0x97a40020, 0x30824000, 0x10400002,
-0x3c030010, 0x3c030008, 0x3c120001, 0x8005306,
-0x30828000, 0x24040001, 0x24050014, 0x27b00020,
-0xc004924, 0x2003021, 0x24040001, 0x24050014,
-0xc004924, 0x2003021, 0x97a40020, 0x30821000,
-0x10400002, 0x3c030010, 0x3c030008, 0x3c120001,
-0x30820800, 0x54400001, 0x3c120002, 0x3c028000,
-0x2221025, 0x2431825, 0x8005313, 0x438825,
-0x3c110001, 0x2338821, 0x8e317e9c, 0x3c027fff,
-0x3442ffff, 0x2228824, 0x3c020001, 0x8c425d38,
-0x1040001c, 0x0, 0x3c020001, 0x8c425df8,
-0x10400002, 0x3c022000, 0x2228825, 0x141140,
-0x3c010001, 0x220821, 0x8c227ea0, 0x10400003,
-0x3c020020, 0x8005327, 0x2228825, 0x3c02ffdf,
-0x3442ffff, 0x2228824, 0x141140, 0x3c010001,
-0x220821, 0x8c227ea8, 0x10400003, 0x3c020080,
-0x8005332, 0x2228825, 0x3c02ff7f, 0x3442ffff,
-0x2228824, 0x3c040001, 0x24845c2c, 0x3c05000c,
-0x34a50326, 0x3c070001, 0x8ce75d28, 0x3021,
-0x141140, 0x3c010001, 0x220821, 0xac317e94,
-0xafb20010, 0xc002403, 0xafb10014, 0x800538f,
-0x2201021, 0x142940, 0x3c030001, 0x651821,
-0x8c637e98, 0x3c024000, 0x621024, 0x14400008,
-0x3c027fff, 0x3442ffff, 0x628824, 0x3c010001,
-0x250821, 0xac317e90, 0x800538f, 0x2201021,
-0x3c020001, 0x8c425d38, 0x10400033, 0x3c11c00c,
-0x3c020001, 0x8c425dd4, 0x3c04c00c, 0x34842000,
-0x3c030001, 0x8c635df8, 0x2102b, 0x21023,
-0x441024, 0x10600003, 0x518825, 0x3c022000,
-0x2228825, 0x3c020001, 0x451021, 0x8c427ea4,
-0x10400003, 0x3c020020, 0x800536c, 0x2228825,
-0x3c02ffdf, 0x3442ffff, 0x2228824, 0x141140,
-0x3c010001, 0x220821, 0x8c227eac, 0x10400003,
-0x3c020080, 0x8005377, 0x2228825, 0x3c02ff7f,
-0x3442ffff, 0x2228824, 0x3c020001, 0x8c425dc0,
-0x10400002, 0x3c020800, 0x2228825, 0x3c020001,
-0x8c425dc4, 0x10400002, 0x3c020400, 0x2228825,
-0x3c020001, 0x8c425dc8, 0x10400006, 0x3c020100,
-0x800538a, 0x2228825, 0x3c027fff, 0x3442ffff,
-0x628824, 0x141140, 0x3c010001, 0x220821,
-0xac317e90, 0x2201021, 0x8fbf003c, 0x8fb40038,
-0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028,
-0x3e00008, 0x27bd0040, 0x27bdffd8, 0xafb40020,
-0x80a021, 0xafbf0024, 0xafb3001c, 0xafb20018,
-0xafb10014, 0xafb00010, 0x8f900200, 0x3c030001,
-0x8c635d28, 0x8f930220, 0x24020002, 0x10620063,
-0x2c620003, 0x10400005, 0x24020001, 0x1062000a,
-0x141940, 0x8005459, 0x0, 0x24020004,
-0x1062005a, 0x24020008, 0x10620059, 0x149140,
-0x8005459, 0x0, 0x3c040001, 0x832021,
-0x8c847e9c, 0x3c110001, 0x2238821, 0x8e317e94,
-0x3c024000, 0x821024, 0x1040003e, 0x3c020008,
-0x2221024, 0x10400020, 0x36100002, 0x3c020001,
-0x431021, 0x8c427ea0, 0x10400005, 0x36100020,
-0x36100100, 0x3c020020, 0x80053ce, 0x2228825,
-0x2402feff, 0x2028024, 0x3c02ffdf, 0x3442ffff,
+0x27bd0038, 0x27bdffd8, 0xafb20020, 0x809021,
+0xafb1001c, 0x8821, 0x24020002, 0xafbf0024,
+0xafb00018, 0xa7a00012, 0x10a200d3, 0xa7a00010,
+0x2ca20003, 0x10400005, 0x24020001, 0x10a2000a,
+0x128140, 0x8005380, 0x2201021, 0x24020004,
+0x10a2007d, 0x24020008, 0x10a2007c, 0x122940,
+0x8005380, 0x2201021, 0x3c030001, 0x701821,
+0x8c637e3c, 0x3c024000, 0x621024, 0x14400009,
+0x24040001, 0x3c027fff, 0x3442ffff, 0x628824,
+0x3c010001, 0x300821, 0xac317e34, 0x8005380,
+0x2201021, 0x24050001, 0xc00494c, 0x27a60010,
+0x24040001, 0x24050001, 0xc00494c, 0x27a60010,
+0x97a20010, 0x30420004, 0x10400034, 0x3c114000,
+0x3c020001, 0x8c425dbc, 0x2443ffff, 0x2c620006,
+0x10400034, 0x31080, 0x3c010001, 0x220821,
+0x8c225be0, 0x400008, 0x0, 0x24040001,
+0x24050011, 0x27b00012, 0xc00494c, 0x2003021,
+0x24040001, 0x24050011, 0xc00494c, 0x2003021,
+0x97a50012, 0x30a24000, 0x10400002, 0x3c040010,
+0x3c040008, 0x3c030001, 0x8005301, 0x30a28000,
+0x24040001, 0x24050014, 0x27b00012, 0xc00494c,
+0x2003021, 0x24040001, 0x24050014, 0xc00494c,
+0x2003021, 0x97a50012, 0x30a21000, 0x10400002,
+0x3c040010, 0x3c040008, 0x3c030001, 0x30a20800,
+0x54400001, 0x3c030002, 0x3c028000, 0x2221025,
+0x641825, 0x800530e, 0x438825, 0x3c110001,
+0x2308821, 0x8e317e3c, 0x3c027fff, 0x3442ffff,
+0x2228824, 0x3c020001, 0x8c425cd8, 0x1040001d,
+0x121140, 0x3c020001, 0x8c425d98, 0x10400002,
+0x3c022000, 0x2228825, 0x121140, 0x3c010001,
+0x220821, 0x8c227e40, 0x10400003, 0x3c020020,
+0x8005322, 0x2228825, 0x3c02ffdf, 0x3442ffff,
+0x2228824, 0x121140, 0x3c010001, 0x220821,
+0x8c227e48, 0x10400003, 0x3c020080, 0x800532d,
+0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824,
+0x121140, 0x3c010001, 0x220821, 0xac317e34,
+0x8005380, 0x2201021, 0x122940, 0x3c030001,
+0x651821, 0x8c637e38, 0x3c024000, 0x621024,
+0x14400008, 0x3c027fff, 0x3442ffff, 0x628824,
+0x3c010001, 0x250821, 0xac317e30, 0x8005380,
+0x2201021, 0x3c020001, 0x8c425cd8, 0x10400033,
+0x3c11c00c, 0x3c020001, 0x8c425d74, 0x3c04c00c,
+0x34842000, 0x3c030001, 0x8c635d98, 0x2102b,
+0x21023, 0x441024, 0x10600003, 0x518825,
+0x3c022000, 0x2228825, 0x3c020001, 0x451021,
+0x8c427e44, 0x10400003, 0x3c020020, 0x800535d,
+0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
+0x121140, 0x3c010001, 0x220821, 0x8c227e4c,
+0x10400003, 0x3c020080, 0x8005368, 0x2228825,
+0x3c02ff7f, 0x3442ffff, 0x2228824, 0x3c020001,
+0x8c425d60, 0x10400002, 0x3c020800, 0x2228825,
+0x3c020001, 0x8c425d64, 0x10400002, 0x3c020400,
+0x2228825, 0x3c020001, 0x8c425d68, 0x10400006,
+0x3c020100, 0x800537b, 0x2228825, 0x3c027fff,
+0x3442ffff, 0x628824, 0x121140, 0x3c010001,
+0x220821, 0xac317e30, 0x2201021, 0x8fbf0024,
+0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008,
+0x27bd0028, 0x27bdffd8, 0xafb40020, 0x80a021,
+0xafbf0024, 0xafb3001c, 0xafb20018, 0xafb10014,
+0xafb00010, 0x8f900200, 0x3c030001, 0x8c635cc8,
+0x8f930220, 0x24020002, 0x10620063, 0x2c620003,
+0x10400005, 0x24020001, 0x1062000a, 0x141940,
+0x8005448, 0x0, 0x24020004, 0x1062005a,
+0x24020008, 0x10620059, 0x149140, 0x8005448,
+0x0, 0x3c040001, 0x832021, 0x8c847e3c,
+0x3c110001, 0x2238821, 0x8e317e34, 0x3c024000,
+0x821024, 0x1040003e, 0x3c020008, 0x2221024,
+0x10400020, 0x36100002, 0x3c020001, 0x431021,
+0x8c427e40, 0x10400005, 0x36100020, 0x36100100,
+0x3c020020, 0x80053bd, 0x2228825, 0x2402feff,
+0x2028024, 0x3c02ffdf, 0x3442ffff, 0x2228824,
+0x141140, 0x3c010001, 0x220821, 0x8c227e48,
+0x10400005, 0x3c020001, 0x2629825, 0x3c020080,
+0x80053dc, 0x2228825, 0x3c02fffe, 0x3442ffff,
+0x2629824, 0x3c02ff7f, 0x3442ffff, 0x80053dc,
+0x2228824, 0x2402fedf, 0x2028024, 0x3c02fffe,
+0x3442ffff, 0x2629824, 0x3c02ff5f, 0x3442ffff,
+0x2228824, 0x3c010001, 0x230821, 0xac207e40,
+0x3c010001, 0x230821, 0xac207e48, 0xc00486a,
+0x0, 0xaf900200, 0xaf930220, 0x8f820220,
+0x2403fffb, 0x431024, 0xaf820220, 0x8f820220,
+0x34420002, 0xaf820220, 0x80053f3, 0x141140,
+0x8f820200, 0x2403fffd, 0x431024, 0xc00486a,
+0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b,
0x2228824, 0x141140, 0x3c010001, 0x220821,
-0x8c227ea8, 0x10400005, 0x3c020001, 0x2629825,
-0x3c020080, 0x80053ed, 0x2228825, 0x3c02fffe,
-0x3442ffff, 0x2629824, 0x3c02ff7f, 0x3442ffff,
-0x80053ed, 0x2228824, 0x2402fedf, 0x2028024,
-0x3c02fffe, 0x3442ffff, 0x2629824, 0x3c02ff5f,
-0x3442ffff, 0x2228824, 0x3c010001, 0x230821,
-0xac207ea0, 0x3c010001, 0x230821, 0xac207ea8,
-0xc004844, 0x0, 0xaf900200, 0xaf930220,
+0x8005448, 0xac317e34, 0x149140, 0x3c040001,
+0x922021, 0x8c847e38, 0x3c110001, 0x2328821,
+0x8e317e30, 0x3c024000, 0x821024, 0x14400011,
+0x0, 0x3c020001, 0x8c425d98, 0x14400006,
+0x3c02bfff, 0x8f820200, 0x34420002, 0xc00486a,
+0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc00429b,
+0x2228824, 0x3c010001, 0x320821, 0x8005448,
+0xac317e30, 0x3c020001, 0x8c425d98, 0x10400005,
+0x3c020020, 0x3c020001, 0x8c425d74, 0x1040002b,
+0x3c020020, 0x821024, 0x10400007, 0x36100020,
+0x24020100, 0x3c010001, 0x320821, 0xac227e44,
+0x8005428, 0x36100100, 0x3c010001, 0x320821,
+0xac207e44, 0x2402feff, 0x2028024, 0x3c020080,
+0x821024, 0x10400007, 0x141940, 0x3c020001,
+0x3c010001, 0x230821, 0xac227e4c, 0x8005439,
+0x2629825, 0x141140, 0x3c010001, 0x220821,
+0xac207e4c, 0x3c02fffe, 0x3442ffff, 0x2629824,
+0xc00486a, 0x0, 0xaf900200, 0xaf930220,
0x8f820220, 0x2403fffb, 0x431024, 0xaf820220,
-0x8f820220, 0x34420002, 0xaf820220, 0x8005404,
-0x141140, 0x8f820200, 0x2403fffd, 0x431024,
-0xc004844, 0xaf820200, 0x3c02bfff, 0x3442ffff,
-0xc00429b, 0x2228824, 0x141140, 0x3c010001,
-0x220821, 0x8005459, 0xac317e94, 0x149140,
-0x3c040001, 0x922021, 0x8c847e98, 0x3c110001,
-0x2328821, 0x8e317e90, 0x3c024000, 0x821024,
-0x14400011, 0x0, 0x3c020001, 0x8c425df8,
-0x14400006, 0x3c02bfff, 0x8f820200, 0x34420002,
-0xc004844, 0xaf820200, 0x3c02bfff, 0x3442ffff,
-0xc00429b, 0x2228824, 0x3c010001, 0x320821,
-0x8005459, 0xac317e90, 0x3c020001, 0x8c425df8,
-0x10400005, 0x3c020020, 0x3c020001, 0x8c425dd4,
-0x1040002b, 0x3c020020, 0x821024, 0x10400007,
-0x36100020, 0x24020100, 0x3c010001, 0x320821,
-0xac227ea4, 0x8005439, 0x36100100, 0x3c010001,
-0x320821, 0xac207ea4, 0x2402feff, 0x2028024,
-0x3c020080, 0x821024, 0x10400007, 0x141940,
-0x3c020001, 0x3c010001, 0x230821, 0xac227eac,
-0x800544a, 0x2629825, 0x141140, 0x3c010001,
-0x220821, 0xac207eac, 0x3c02fffe, 0x3442ffff,
-0x2629824, 0xc004844, 0x0, 0xaf900200,
-0xaf930220, 0x8f820220, 0x2403fffb, 0x431024,
-0xaf820220, 0x8f820220, 0x34420002, 0xaf820220,
-0x141140, 0x3c010001, 0x220821, 0xac317e90,
-0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
-0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0028,
-0x0, 0x0, 0x0, 0x0 };
+0x8f820220, 0x34420002, 0xaf820220, 0x141140,
+0x3c010001, 0x220821, 0xac317e30, 0x8fbf0024,
+0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
+0x8fb00010, 0x3e00008, 0x27bd0028, 0x0 };
u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x24486561, 0x6465723a, 0x202f7072,
0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
@@ -4473,10 +4468,10 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x32203139, 0x39382f30, 0x342f3237, 0x2032323a,
0x31333a34, 0x30207368, 0x75616e67, 0x20457870,
0x20240000, 0x46575f56, 0x45525349, 0x4f4e3a20,
-0x23312053, 0x61742044, 0x65632031, 0x31203136,
-0x3a30333a, 0x31392050, 0x53542031, 0x39393900,
+0x23312046, 0x72692041, 0x70722037, 0x2031373a,
+0x35353a34, 0x38205044, 0x54203230, 0x30300000,
0x46575f43, 0x4f4d5049, 0x4c455f54, 0x494d453a,
-0x2031363a, 0x30333a31, 0x39000000, 0x46575f43,
+0x2031373a, 0x35353a34, 0x38000000, 0x46575f43,
0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263,
0x73000000, 0x46575f43, 0x4f4d5049, 0x4c455f48,
0x4f53543a, 0x20636f6d, 0x70757465, 0x0,
@@ -4554,27 +4549,27 @@ u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x2e322031, 0x3939382f, 0x30342f32, 0x37203232,
0x3a31333a, 0x33392073, 0x6875616e, 0x67204578,
0x70202400, 0x50726f62, 0x65506879, 0x0,
-0x6c6e6b41, 0x53535254, 0x0, 0x11af4,
-0x11b8c, 0x11bac, 0x11bf0, 0x11c1c,
-0x11c30, 0x11c6c, 0x11fe0, 0x11d48,
-0x11d88, 0x11db4, 0x11df4, 0x11e24,
-0x11e60, 0x11e94, 0x11fe0, 0x12228,
-0x12240, 0x12268, 0x12288, 0x122b0,
-0x123e0, 0x12408, 0x1245c, 0x12484,
-0x0, 0x126ec, 0x127bc, 0x12894,
-0x12964, 0x129c0, 0x12a9c, 0x12ac4,
-0x12ba0, 0x12bc8, 0x12d70, 0x12d98,
-0x12f40, 0x13138, 0x133cc, 0x132e0,
-0x133cc, 0x133f8, 0x12f68, 0x13110,
-0x0, 0x13ae4, 0x13b28, 0x13bc0,
-0x13c0c, 0x13c7c, 0x13d14, 0x13d48,
-0x13dd0, 0x13e68, 0x13f38, 0x13f78,
-0x13ffc, 0x14020, 0x14154, 0x646f4261,
+0x6c6e6b41, 0x53535254, 0x0, 0x11b2c,
+0x11bc4, 0x11bf8, 0x11c2c, 0x11c58,
+0x11c6c, 0x11ca8, 0x1207c, 0x11de4,
+0x11e24, 0x11e50, 0x11e90, 0x11ec0,
+0x11efc, 0x11f30, 0x1207c, 0x122c0,
+0x122d8, 0x12300, 0x12320, 0x12348,
+0x12478, 0x124a0, 0x124f4, 0x1251c,
+0x0, 0x1278c, 0x1285c, 0x12934,
+0x12a04, 0x12a60, 0x12b3c, 0x12b64,
+0x12c40, 0x12c68, 0x12e10, 0x12e38,
+0x12fe0, 0x131d8, 0x1346c, 0x13380,
+0x1346c, 0x13498, 0x13008, 0x131b0,
+0x0, 0x13b84, 0x13bc8, 0x13c60,
+0x13cac, 0x13d1c, 0x13db4, 0x13de8,
+0x13e70, 0x13f08, 0x13fd8, 0x14018,
+0x1409c, 0x140c0, 0x141f4, 0x646f4261,
0x73655067, 0x0, 0x0, 0x0,
0x0, 0x73746d61, 0x634c4e4b, 0x0,
-0x6765746d, 0x636c6e6b, 0x0, 0x14c4c,
-0x14c4c, 0x14b94, 0x14bd8, 0x14c4c,
-0x14c4c, 0x0 };
+0x0, 0x14c38, 0x14c38, 0x14b80,
+0x14bc4, 0x14c38, 0x14c38, 0x0,
+0x0, 0x0 };
u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = {
0x416c7465,
0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465,
@@ -4604,25 +4599,25 @@ u32 tigonFwData[(MAX_DATA_LEN/4) + 1] __initdata = {
/* Generated by genfw.c */
#define tigon2FwReleaseMajor 0xc
#define tigon2FwReleaseMinor 0x4
-#define tigon2FwReleaseFix 0x5
+#define tigon2FwReleaseFix 0xb
#define tigon2FwStartAddr 0x00004000
#define tigon2FwTextAddr 0x00004000
-#define tigon2FwTextLen 0x11c50
-#define tigon2FwRodataAddr 0x00015c50
-#define tigon2FwRodataLen 0x10c0
-#define tigon2FwDataAddr 0x00016d40
+#define tigon2FwTextLen 0x11bc0
+#define tigon2FwRodataAddr 0x00015bc0
+#define tigon2FwRodataLen 0x10d0
+#define tigon2FwDataAddr 0x00016cc0
#define tigon2FwDataLen 0x1c0
-#define tigon2FwSbssAddr 0x00016f00
-#define tigon2FwSbssLen 0xc4
-#define tigon2FwBssAddr 0x00016fd0
+#define tigon2FwSbssAddr 0x00016e80
+#define tigon2FwSbssLen 0xcc
+#define tigon2FwBssAddr 0x00016f50
#define tigon2FwBssLen 0x20c0
u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0,
0x10000003, 0x0, 0xd, 0xd,
-0x3c1d0001, 0x8fbd6da0, 0x3a0f021, 0x3c100000,
+0x3c1d0001, 0x8fbd6d20, 0x3a0f021, 0x3c100000,
0x26104000, 0xc0010c0, 0x0, 0xd,
-0x3c1d0001, 0x8fbd6da4, 0x3a0f021, 0x3c100000,
-0x26104000, 0xc0017c8, 0x0, 0xd,
+0x3c1d0001, 0x8fbd6d24, 0x3a0f021, 0x3c100000,
+0x26104000, 0xc0017e0, 0x0, 0xd,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
@@ -4634,22 +4629,22 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x2000008,
-0x0, 0x8001717, 0x3c0a0001, 0x8001717,
-0x3c0a0002, 0x8001717, 0x0, 0x8002c68,
-0x0, 0x8002c0b, 0x0, 0x8001717,
-0x3c0a0004, 0x8003272, 0x0, 0x8001a3a,
-0x0, 0x8003925, 0x0, 0x80038cc,
-0x0, 0x8001717, 0x3c0a0006, 0x8003993,
-0x3c0a0007, 0x8001717, 0x3c0a0008, 0x8001717,
-0x3c0a0009, 0x80039eb, 0x0, 0x8002e62,
-0x0, 0x8001717, 0x3c0a000b, 0x8001717,
-0x3c0a000c, 0x8001717, 0x3c0a000d, 0x80028d7,
-0x0, 0x800286c, 0x0, 0x8001717,
-0x3c0a000e, 0x8002074, 0x0, 0x800194c,
-0x0, 0x80019ec, 0x0, 0x8003c7e,
-0x0, 0x8003c6c, 0x0, 0x8001717,
-0x0, 0x8001902, 0x0, 0x8001717,
-0x0, 0x8001717, 0x3c0a0013, 0x8001717,
+0x0, 0x800172f, 0x3c0a0001, 0x800172f,
+0x3c0a0002, 0x800172f, 0x0, 0x8002cac,
+0x0, 0x8002c4f, 0x0, 0x800172f,
+0x3c0a0004, 0x800328a, 0x0, 0x8001a52,
+0x0, 0x800394d, 0x0, 0x80038f4,
+0x0, 0x800172f, 0x3c0a0006, 0x80039bb,
+0x3c0a0007, 0x800172f, 0x3c0a0008, 0x800172f,
+0x3c0a0009, 0x8003a13, 0x0, 0x8002ea6,
+0x0, 0x800172f, 0x3c0a000b, 0x800172f,
+0x3c0a000c, 0x800172f, 0x3c0a000d, 0x80028fb,
+0x0, 0x8002890, 0x0, 0x800172f,
+0x3c0a000e, 0x800208c, 0x0, 0x8001964,
+0x0, 0x8001a04, 0x0, 0x8003ca6,
+0x0, 0x8003c94, 0x0, 0x800172f,
+0x0, 0x800191a, 0x0, 0x800172f,
+0x0, 0x800172f, 0x3c0a0013, 0x800172f,
0x3c0a0014, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
@@ -4667,335 +4662,341 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x27bdffe0,
0x3c1cc000, 0xafbf001c, 0xafb00018, 0x8f820140,
-0x24030003, 0xaf8300ec, 0x34420004, 0xc002afc,
-0xaf820140, 0x3c0100c0, 0xc00174b, 0xac203ffc,
-0x403021, 0x3c020008, 0x3c010001, 0xac266f18,
-0x50c2000d, 0x24020008, 0x3c100010, 0x10d00009,
-0x24050100, 0x3c040001, 0x24845d04, 0x3821,
-0xafa00010, 0xc002b17, 0xafa00014, 0x3c010001,
-0xac306f18, 0x24020008, 0x3c010001, 0xac226f30,
-0x2402001f, 0x3c010001, 0xac226f40, 0x24020016,
-0x3c010001, 0xac226f14, 0x3c05fffe, 0x34a56f08,
-0x3c020001, 0x8c426f18, 0x3c030002, 0x24639090,
-0x3c040001, 0x8c846d44, 0x431023, 0x14800002,
-0x458021, 0x2610fa38, 0x2402f000, 0x2028024,
-0xc00176d, 0x2002021, 0x2022823, 0x3c040020,
-0x821823, 0x651823, 0x247bb000, 0x3c03fffe,
-0x3463bf08, 0x363b821, 0x3c0600bf, 0x34c6f000,
-0x3c070001, 0x8ce76d40, 0x3c0300bf, 0x3463e000,
-0x852023, 0x3c010001, 0xac246f24, 0x822023,
-0x3c010001, 0xac256f0c, 0x52842, 0x3c010001,
-0xac226f00, 0x27620ffc, 0x3c010001, 0xac226da0,
-0x27621ffc, 0xdb3023, 0x7b1823, 0x3c010001,
-0xac246f04, 0x3c010001, 0xac256f28, 0x3c010001,
-0xac226da4, 0xaf860150, 0x10e00011, 0xaf830250,
-0x3c1d0001, 0x8fbd6d4c, 0x3a0f021, 0xc001731,
-0x0, 0x3c020001, 0x8c426d50, 0x3c030001,
-0x8c636d54, 0x2442fe00, 0x24630200, 0x3c010001,
-0xac226d50, 0x3c010001, 0x10000004, 0xac236d54,
-0x3c1d0001, 0x8fbd6da0, 0x3a0f021, 0x3c020001,
-0x8c426d44, 0x1040000d, 0x26fafa38, 0x3c020001,
-0x8c426d50, 0x3c030001, 0x8c636d54, 0x3c1a0001,
-0x8f5a6d54, 0x2442fa38, 0x246305c8, 0x3c010001,
-0xac226d50, 0x3c010001, 0xac236d54, 0x3c020001,
-0x8c426d48, 0x14400003, 0x0, 0x3c010001,
-0xac206d50, 0xc00114c, 0x0, 0x8fbf001c,
-0x8fb00018, 0x3e00008, 0x27bd0020, 0x3c020001,
-0x8c426d50, 0x3c030001, 0x8c636d54, 0x27bdffa0,
-0xafb00040, 0x3c100001, 0x8e106748, 0x3c040001,
-0x24845d10, 0xafbf0058, 0xafbe0054, 0xafb50050,
-0xafb3004c, 0xafb20048, 0xafb10044, 0xafa20034,
-0xafa30030, 0xafa00010, 0xafa00014, 0x8f860040,
-0x24050200, 0xc002b17, 0x2003821, 0x8f830040,
-0x3c02f000, 0x621824, 0x3c026000, 0x1062000b,
-0xa3a0003f, 0x240e0001, 0x3c040001, 0x24845d18,
-0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f860040,
-0x24050300, 0xc002b17, 0x2003821, 0x8f820240,
-0x3c030001, 0x431025, 0xaf820240, 0xaf800048,
-0x8f820048, 0x14400005, 0x0, 0xaf800048,
-0x8f820048, 0x10400004, 0x0, 0xaf800048,
-0x10000003, 0x2e02021, 0xaf80004c, 0x2e02021,
-0x3c050001, 0xc002b84, 0x34a540f8, 0x3402021,
-0xc002b84, 0x240505c8, 0x3c020001, 0x8c426f24,
-0x3c0d0001, 0x8dad6f04, 0x3c030001, 0x8c636f00,
-0x3c080001, 0x8d086f0c, 0x3c090001, 0x8d296f28,
-0x3c0a0001, 0x8d4a6f30, 0x3c0b0001, 0x8d6b6f40,
-0x3c0c0001, 0x8d8c6f14, 0x3c040001, 0x24845d24,
-0x24050400, 0xaf42013c, 0x8f42013c, 0x24060001,
-0x24070001, 0xaf400000, 0xaf4d0138, 0xaf430144,
-0xaf480148, 0xaf49014c, 0xaf4a0150, 0xaf4b0154,
-0xaf4c0158, 0x2442ff80, 0xaf420140, 0x24020001,
-0xafa20010, 0xc002b17, 0xafa00014, 0x8f420138,
-0xafa20010, 0x8f42013c, 0xafa20014, 0x8f460144,
-0x8f470148, 0x3c040001, 0x24845d30, 0xc002b17,
-0x24050500, 0xafb70010, 0xafba0014, 0x8f46014c,
-0x8f470150, 0x3c040001, 0x24845d3c, 0xc002b17,
-0x24050600, 0x3c020001, 0x8c426f18, 0x3603821,
-0x3c060002, 0x24c69090, 0x2448ffff, 0x1061824,
-0xe81024, 0x43102b, 0x10400006, 0x24050900,
-0x3c040001, 0x24845d48, 0xafa80010, 0xc002b17,
-0xafa00014, 0x8f82000c, 0xafa20010, 0x8f82003c,
-0xafa20014, 0x8f860000, 0x8f870004, 0x3c040001,
-0x24845d54, 0xc002b17, 0x24051000, 0x8c020220,
-0x8c030224, 0x8c060218, 0x8c07021c, 0x3c040001,
-0x24845d5c, 0x24051100, 0xafa20010, 0xc002b17,
-0xafa30014, 0xaf800054, 0xaf80011c, 0x8c020218,
-0x30420002, 0x10400009, 0x0, 0x8c020220,
-0x3c030002, 0x34630004, 0x431025, 0xaf42000c,
-0x8c02021c, 0x10000008, 0x34420004, 0x8c020220,
-0x3c030002, 0x34630006, 0x431025, 0xaf42000c,
-0x8c02021c, 0x34420006, 0xaf420014, 0x8c020218,
-0x30420010, 0x1040000a, 0x0, 0x8c02021c,
-0x34420004, 0xaf420010, 0x8c020220, 0x3c03000a,
-0x34630004, 0x431025, 0x10000009, 0xaf420008,
-0x8c020220, 0x3c03000a, 0x34630006, 0x431025,
-0xaf420008, 0x8c02021c, 0x34420006, 0xaf420010,
-0x24020001, 0xaf8200a0, 0xaf8200b0, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
-0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0x8c040208, 0x8c05020c, 0x26e20028, 0xaee20020,
-0x24020490, 0xaee20010, 0xaee40008, 0xaee5000c,
-0x26e40008, 0x8c820000, 0x8c830004, 0xaf820090,
-0xaf830094, 0x8c820018, 0xaf8200b4, 0x9482000a,
-0xaf82009c, 0x8f420014, 0xaf8200b0, 0x8f8200b0,
-0x30420004, 0x1440fffd, 0x0, 0x8f8200b0,
-0x3c03ef00, 0x431024, 0x10400021, 0x0,
-0x8f8200b4, 0xafa20010, 0x8f820090, 0x8f830094,
-0x3c040001, 0x24845d64, 0xafa30014, 0x8f8600b0,
-0x8f87009c, 0x3c050001, 0xc002b17, 0x34a5200d,
-0x3c040001, 0x24845d70, 0x240203ac, 0xafa20010,
-0xafa00014, 0x8f860144, 0x3c070001, 0x24e75d78,
-0xc002b17, 0x3405dead, 0x8f82011c, 0x34420002,
-0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220,
-0x8f820140, 0x3c030001, 0x431025, 0xaf820140,
-0x96e20472, 0x96e60452, 0x96e70462, 0xafa20010,
-0x96e20482, 0x3c040001, 0x24845da4, 0x24051200,
-0xc002b17, 0xafa20014, 0x96f00452, 0x32020001,
-0x10400002, 0xb021, 0x24160001, 0x32020002,
-0x54400001, 0x36d60002, 0x32020008, 0x54400001,
-0x36d60004, 0x32020010, 0x54400001, 0x36d60008,
-0x32020020, 0x54400001, 0x36d60010, 0x32020040,
-0x54400001, 0x36d60020, 0x32020080, 0x54400001,
-0x36d60040, 0x96e60482, 0x30c20200, 0x54400001,
-0x36d64000, 0x96e30472, 0x30620200, 0x10400003,
-0x30620100, 0x10000003, 0x36d62000, 0x54400001,
-0x36d61000, 0x96f00462, 0x32c24000, 0x14400004,
-0x3207009b, 0x30c2009b, 0x14e20007, 0x240e0001,
-0x32c22000, 0x1440000d, 0x32020001, 0x3062009b,
-0x10e20009, 0x240e0001, 0x3c040001, 0x24845db0,
-0x24051300, 0x2003821, 0xa3ae003f, 0xafa30010,
-0xc002b17, 0xafa00014, 0x32020001, 0x54400001,
-0x36d60080, 0x32020002, 0x54400001, 0x36d60100,
-0x32020008, 0x54400001, 0x36d60200, 0x32020010,
-0x54400001, 0x36d60400, 0x32020080, 0x54400001,
-0x36d60800, 0x8c020218, 0x30420200, 0x10400002,
-0x3c020008, 0x2c2b025, 0x8c020218, 0x30420800,
-0x10400002, 0x3c020080, 0x2c2b025, 0x8c020218,
-0x30420400, 0x10400002, 0x3c020100, 0x2c2b025,
-0x8c020218, 0x30420100, 0x10400002, 0x3c020200,
-0x2c2b025, 0x8c020218, 0x30420080, 0x10400002,
-0x3c020400, 0x2c2b025, 0x8c020218, 0x30422000,
-0x10400002, 0x3c020010, 0x2c2b025, 0x8c020218,
-0x30424000, 0x10400002, 0x3c020020, 0x2c2b025,
-0x8c020218, 0x30421000, 0x10400002, 0x3c020040,
-0x2c2b025, 0x8ee20498, 0x8ee3049c, 0xaf420160,
-0xaf430164, 0x8ee204a0, 0x8ee304a4, 0xaf420168,
-0xaf43016c, 0x8ee204a8, 0x8ee304ac, 0xaf420170,
-0xaf430174, 0x8ee20428, 0x8ee3042c, 0xaf420178,
-0xaf43017c, 0x8ee20448, 0x8ee3044c, 0xaf420180,
-0xaf430184, 0x8ee20458, 0x8ee3045c, 0xaf420188,
-0xaf43018c, 0x8ee20468, 0x8ee3046c, 0xaf420190,
-0xaf430194, 0x8ee20478, 0x8ee3047c, 0xaf420198,
-0xaf43019c, 0x8ee20488, 0x8ee3048c, 0xaf4201a0,
-0xaf4301a4, 0x8ee204b0, 0x8ee304b4, 0x24040080,
-0xaf4201a8, 0xaf4301ac, 0xc002b84, 0x24050080,
-0x8c02025c, 0x27440224, 0xaf4201f0, 0x8c020260,
-0x24050200, 0x24060008, 0xc002b9b, 0xaf4201f8,
-0x3c043b9a, 0x3484ca00, 0x3821, 0x24020006,
-0x24030002, 0xaf4201f4, 0x240203e8, 0xaf430204,
-0xaf430200, 0xaf4401fc, 0xaf420294, 0x24020001,
-0xaf430290, 0xaf42029c, 0x3c030001, 0x671821,
-0x90636d58, 0x3471021, 0x24e70001, 0xa043022c,
-0x2ce2000f, 0x1440fff8, 0x3471821, 0x24e70001,
-0x3c080001, 0x350840f8, 0x8f820040, 0x3c040001,
-0x24845dbc, 0x24051400, 0x21702, 0x24420030,
-0xa062022c, 0x3471021, 0xa040022c, 0x8c070218,
-0x2c03021, 0x240205c8, 0xafa20010, 0xc002b17,
-0xafa80014, 0x3c040001, 0x24845dc8, 0x3c050000,
-0x24a55c20, 0x24060010, 0x27b10030, 0x2203821,
-0x27b30034, 0xc00178b, 0xafb30010, 0x3c030001,
-0x8c636d48, 0x1060000a, 0x408021, 0x8fa30030,
-0x2405ff00, 0x8fa20034, 0x246400ff, 0x852024,
-0x831823, 0x431023, 0xafa20034, 0xafa40030,
-0xafb30010, 0x3c040001, 0x24845dd4, 0x3c050000,
-0x24a54100, 0x24060108, 0xc00178b, 0x2203821,
-0x409021, 0x32c20003, 0x50400045, 0x2203821,
-0x8f820050, 0x3c030010, 0x431024, 0x10400016,
-0x0, 0x8c020218, 0x30420040, 0x1040000f,
-0x24020001, 0x8f820050, 0x8c030218, 0x240e0001,
-0x3c040001, 0x24845de0, 0xa3ae003f, 0xafa20010,
-0xafa30014, 0x8f870040, 0x24051500, 0xc002b17,
-0x2c03021, 0x10000004, 0x0, 0x3c010001,
-0x370821, 0xa02240f4, 0x3c040001, 0x24845dec,
-0x3c050001, 0x24a55bd0, 0x3c060001, 0x24c65c3c,
-0xc53023, 0x8f420010, 0x27b30030, 0x2603821,
-0x27b10034, 0x34420a00, 0xaf420010, 0xc00178b,
-0xafb10010, 0x3c040001, 0x24845e00, 0x3c050001,
-0x24a5b604, 0x3c060001, 0x24c6b980, 0xc53023,
-0x2603821, 0xaf420108, 0xc00178b, 0xafb10010,
-0x3c040001, 0x24845e1c, 0x3c050001, 0x24a5bda0,
-0x3c060001, 0x24c6c8a0, 0xc53023, 0x2603821,
-0x3c010001, 0xac226f70, 0xc00178b, 0xafb10010,
-0x3c040001, 0x24845e34, 0x10000024, 0x24051600,
-0x3c040001, 0x24845e3c, 0x3c050001, 0x24a5a07c,
-0x3c060001, 0x24c6a1a8, 0xc53023, 0xc00178b,
-0xafb30010, 0x3c040001, 0x24845e4c, 0x3c050001,
-0x24a5b1a0, 0x3c060001, 0x24c6b5fc, 0xc53023,
-0x2203821, 0xaf420108, 0xc00178b, 0xafb30010,
-0x3c040001, 0x24845e60, 0x3c050001, 0x24a5b988,
-0x3c060001, 0x24c6bd98, 0xc53023, 0x2203821,
-0x3c010001, 0xac226f70, 0xc00178b, 0xafb30010,
-0x3c040001, 0x24845e74, 0x24051650, 0x2c03021,
-0x3821, 0x3c010001, 0xac226f74, 0xafa00010,
-0xc002b17, 0xafa00014, 0x32c20020, 0x10400021,
-0x27a70030, 0x3c040001, 0x24845e80, 0x3c050001,
-0x24a5b02c, 0x3c060001, 0x24c6b198, 0xc53023,
-0x24022000, 0xaf42001c, 0x27a20034, 0xc00178b,
-0xafa20010, 0x21900, 0x31982, 0x3c040800,
-0x641825, 0xae430028, 0x24030010, 0xaf43003c,
-0x96e30450, 0xaf430040, 0x8f430040, 0x3c040001,
-0x24845e94, 0xafa00014, 0xafa30010, 0x8f47001c,
-0x24051660, 0x3c010001, 0xac226f6c, 0x10000025,
-0x32c60020, 0x8ee20448, 0x8ee3044c, 0xaf43001c,
-0x8f42001c, 0x2442e000, 0x2c422001, 0x1440000a,
-0x240e0001, 0x3c040001, 0x24845ea0, 0xa3ae003f,
-0xafa00010, 0xafa00014, 0x8f46001c, 0x24051700,
-0xc002b17, 0x3821, 0x3c020000, 0x24425c5c,
-0x21100, 0x21182, 0x3c030800, 0x431025,
-0xae420028, 0x24020008, 0xaf42003c, 0x96e20450,
-0xaf420040, 0x8f420040, 0x3c040001, 0x24845eac,
-0xafa00014, 0xafa20010, 0x8f47001c, 0x24051800,
-0x32c60020, 0xc002b17, 0x0, 0x3c030001,
-0x8c636f70, 0x3c050fff, 0x34a5ffff, 0x3c020001,
-0x8c426f74, 0x3c040800, 0x651824, 0x31882,
-0x641825, 0x451024, 0x21082, 0x441025,
-0xae420080, 0x32c20180, 0x10400056, 0xae430020,
-0x8f82005c, 0x3c030080, 0x431024, 0x1040000d,
-0x0, 0x8f820050, 0xafa20010, 0x8f82005c,
-0x240e0001, 0x3c040001, 0x24845eb8, 0xa3ae003f,
-0xafa20014, 0x8f870040, 0x24051900, 0xc002b17,
-0x2c03021, 0x8f820050, 0x3c030010, 0x431024,
+0x24030003, 0xaf8300ec, 0x34420004, 0xc002b20,
+0xaf820140, 0x3c0100c0, 0xc001763, 0xac203ffc,
+0x401821, 0x3c020010, 0x3c010001, 0xac236e9c,
+0x10620011, 0x43102b, 0x14400002, 0x3c020020,
+0x3c020008, 0x1062000c, 0x24050100, 0x3c060001,
+0x8cc66e9c, 0x3c040001, 0x24845c74, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020020,
+0x3c010001, 0xac226e9c, 0x24020008, 0x3c010001,
+0xac226eb4, 0x2402001f, 0x3c010001, 0xac226ec4,
+0x24020016, 0x3c010001, 0xac226e98, 0x3c05fffe,
+0x34a56f08, 0x3c020001, 0x8c426e9c, 0x3c030002,
+0x24639010, 0x3c040001, 0x8c846cc4, 0x431023,
+0x14800002, 0x458021, 0x2610fa38, 0x2402f000,
+0x2028024, 0xc001785, 0x2002021, 0x2022823,
+0x3c040020, 0x821823, 0x651823, 0x247bb000,
+0x3c03fffe, 0x3463bf08, 0x363b821, 0x3c0600bf,
+0x34c6f000, 0x3c070001, 0x8ce76cc0, 0x3c0300bf,
+0x3463e000, 0x852023, 0x3c010001, 0xac246ea8,
+0x822023, 0x3c010001, 0xac256e90, 0x52842,
+0x3c010001, 0xac226e84, 0x27620ffc, 0x3c010001,
+0xac226d20, 0x27621ffc, 0xdb3023, 0x7b1823,
+0x3c010001, 0xac246e88, 0x3c010001, 0xac256eac,
+0x3c010001, 0xac226d24, 0xaf860150, 0x10e00011,
+0xaf830250, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021,
+0xc001749, 0x0, 0x3c020001, 0x8c426cd0,
+0x3c030001, 0x8c636cd4, 0x2442fe00, 0x24630200,
+0x3c010001, 0xac226cd0, 0x3c010001, 0x10000004,
+0xac236cd4, 0x3c1d0001, 0x8fbd6d20, 0x3a0f021,
+0x3c020001, 0x8c426cc4, 0x1040000d, 0x26fafa38,
+0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
+0x3c1a0001, 0x8f5a6cd4, 0x2442fa38, 0x246305c8,
+0x3c010001, 0xac226cd0, 0x3c010001, 0xac236cd4,
+0x3c020001, 0x8c426cc8, 0x14400003, 0x0,
+0x3c010001, 0xac206cd0, 0xc001151, 0x0,
+0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
+0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
+0x27bdff98, 0xafb00048, 0x3c100001, 0x8e1066b8,
+0xafb20050, 0x3c120000, 0x26524100, 0xafbf0060,
+0xafbe005c, 0xafb50058, 0xafb30054, 0xafb1004c,
+0xafa20034, 0xafa30030, 0xafa00010, 0xafa00014,
+0x8f860040, 0x3c040001, 0x24845c80, 0x24050200,
+0x3c010001, 0xac326e80, 0xc002b3b, 0x2003821,
+0x8f830040, 0x3c02f000, 0x621824, 0x3c026000,
+0x1062000b, 0xa3a0003f, 0x240e0001, 0x3c040001,
+0x24845c88, 0xa3ae003f, 0xafa00010, 0xafa00014,
+0x8f860040, 0x24050300, 0xc002b3b, 0x2003821,
+0x8f820240, 0x3c030001, 0x431025, 0xaf820240,
+0xaf800048, 0x8f820048, 0x14400005, 0x0,
+0xaf800048, 0x8f820048, 0x10400004, 0x0,
+0xaf800048, 0x10000003, 0x2e02021, 0xaf80004c,
+0x2e02021, 0x3c050001, 0xc002ba8, 0x34a540f8,
+0x3402021, 0xc002ba8, 0x240505c8, 0x3c020001,
+0x8c426ea8, 0x3c0d0001, 0x8dad6e88, 0x3c030001,
+0x8c636e84, 0x3c080001, 0x8d086e90, 0x3c090001,
+0x8d296eac, 0x3c0a0001, 0x8d4a6eb4, 0x3c0b0001,
+0x8d6b6ec4, 0x3c0c0001, 0x8d8c6e98, 0x3c040001,
+0x24845c94, 0x24050400, 0xaf42013c, 0x8f42013c,
+0x24060001, 0x24070001, 0xaf400000, 0xaf4d0138,
+0xaf430144, 0xaf480148, 0xaf49014c, 0xaf4a0150,
+0xaf4b0154, 0xaf4c0158, 0x2442ff80, 0xaf420140,
+0x24020001, 0xafa20010, 0xc002b3b, 0xafa00014,
+0x8f420138, 0xafa20010, 0x8f42013c, 0xafa20014,
+0x8f460144, 0x8f470148, 0x3c040001, 0x24845ca0,
+0xc002b3b, 0x24050500, 0xafb70010, 0xafba0014,
+0x8f46014c, 0x8f470150, 0x3c040001, 0x24845cac,
+0xc002b3b, 0x24050600, 0x3c020001, 0x8c426e9c,
+0x3603821, 0x3c060002, 0x24c69010, 0x2448ffff,
+0x1061824, 0xe81024, 0x43102b, 0x10400006,
+0x24050900, 0x3c040001, 0x24845cb8, 0xafa80010,
+0xc002b3b, 0xafa00014, 0x8f82000c, 0xafa20010,
+0x8f82003c, 0xafa20014, 0x8f860000, 0x8f870004,
+0x3c040001, 0x24845cc4, 0xc002b3b, 0x24051000,
+0x8c020220, 0x8c030224, 0x8c060218, 0x8c07021c,
+0x3c040001, 0x24845ccc, 0x24051100, 0xafa20010,
+0xc002b3b, 0xafa30014, 0xaf800054, 0xaf80011c,
+0x8c020218, 0x30420002, 0x10400009, 0x0,
+0x8c020220, 0x3c030002, 0x34630004, 0x431025,
+0xaf42000c, 0x8c02021c, 0x10000008, 0x34420004,
+0x8c020220, 0x3c030002, 0x34630006, 0x431025,
+0xaf42000c, 0x8c02021c, 0x34420006, 0xaf420014,
+0x8c020218, 0x30420010, 0x1040000a, 0x0,
+0x8c02021c, 0x34420004, 0xaf420010, 0x8c020220,
+0x3c03000a, 0x34630004, 0x431025, 0x10000009,
+0xaf420008, 0x8c020220, 0x3c03000a, 0x34630006,
+0x431025, 0xaf420008, 0x8c02021c, 0x34420006,
+0xaf420010, 0x24020001, 0xaf8200a0, 0xaf8200b0,
+0x8f830054, 0x8f820054, 0xaf8000d0, 0xaf8000c0,
+0x10000002, 0x24630064, 0x8f820054, 0x621023,
+0x2c420065, 0x1440fffc, 0x0, 0x8c040208,
+0x8c05020c, 0x26e20028, 0xaee20020, 0x24020490,
+0xaee20010, 0xaee40008, 0xaee5000c, 0x26e40008,
+0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094,
+0x8c820018, 0xaf8200b4, 0x9482000a, 0xaf82009c,
+0x8f420014, 0xaf8200b0, 0x8f8200b0, 0x30420004,
+0x1440fffd, 0x0, 0x8f8200b0, 0x3c03ef00,
+0x431024, 0x10400021, 0x0, 0x8f8200b4,
+0xafa20010, 0x8f820090, 0x8f830094, 0x3c040001,
+0x24845cd4, 0xafa30014, 0x8f8600b0, 0x8f87009c,
+0x3c050001, 0xc002b3b, 0x34a5200d, 0x3c040001,
+0x24845ce0, 0x240203c0, 0xafa20010, 0xafa00014,
+0x8f860144, 0x3c070001, 0x24e75ce8, 0xc002b3b,
+0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c,
+0x8f820220, 0x34420004, 0xaf820220, 0x8f820140,
+0x3c030001, 0x431025, 0xaf820140, 0x96e20472,
+0x96e60452, 0x96e70462, 0xafa20010, 0x96e20482,
+0x3c040001, 0x24845d14, 0x24051200, 0xc002b3b,
+0xafa20014, 0x96f00452, 0x32020001, 0x10400002,
+0xb021, 0x24160001, 0x32020002, 0x54400001,
+0x36d60002, 0x32020008, 0x54400001, 0x36d60004,
+0x32020010, 0x54400001, 0x36d60008, 0x32020020,
+0x54400001, 0x36d60010, 0x32020040, 0x54400001,
+0x36d60020, 0x32020080, 0x54400001, 0x36d60040,
+0x96e60482, 0x30c20200, 0x54400001, 0x36d64000,
+0x96e30472, 0x30620200, 0x10400003, 0x30620100,
+0x10000003, 0x36d62000, 0x54400001, 0x36d61000,
+0x96f00462, 0x32c24000, 0x14400004, 0x3207009b,
+0x30c2009b, 0x14e20007, 0x240e0001, 0x32c22000,
+0x1440000d, 0x32020001, 0x3062009b, 0x10e20009,
+0x240e0001, 0x3c040001, 0x24845d20, 0x24051300,
+0x2003821, 0xa3ae003f, 0xafa30010, 0xc002b3b,
+0xafa00014, 0x32020001, 0x54400001, 0x36d60080,
+0x32020002, 0x54400001, 0x36d60100, 0x32020008,
+0x54400001, 0x36d60200, 0x32020010, 0x54400001,
+0x36d60400, 0x32020080, 0x54400001, 0x36d60800,
+0x8c020218, 0x30420200, 0x10400002, 0x3c020008,
+0x2c2b025, 0x8c020218, 0x30420800, 0x10400002,
+0x3c020080, 0x2c2b025, 0x8c020218, 0x30420400,
+0x10400002, 0x3c020100, 0x2c2b025, 0x8c020218,
+0x30420100, 0x10400002, 0x3c020200, 0x2c2b025,
+0x8c020218, 0x30420080, 0x10400002, 0x3c020400,
+0x2c2b025, 0x8c020218, 0x30422000, 0x10400002,
+0x3c020010, 0x2c2b025, 0x8c020218, 0x30424000,
+0x10400002, 0x3c020020, 0x2c2b025, 0x8c020218,
+0x30421000, 0x10400002, 0x3c020040, 0x2c2b025,
+0x8ee20498, 0x8ee3049c, 0xaf420160, 0xaf430164,
+0x8ee204a0, 0x8ee304a4, 0xaf420168, 0xaf43016c,
+0x8ee204a8, 0x8ee304ac, 0xaf420170, 0xaf430174,
+0x8ee20428, 0x8ee3042c, 0xaf420178, 0xaf43017c,
+0x8ee20448, 0x8ee3044c, 0xaf420180, 0xaf430184,
+0x8ee20458, 0x8ee3045c, 0xaf420188, 0xaf43018c,
+0x8ee20468, 0x8ee3046c, 0xaf420190, 0xaf430194,
+0x8ee20478, 0x8ee3047c, 0xaf420198, 0xaf43019c,
+0x8ee20488, 0x8ee3048c, 0xaf4201a0, 0xaf4301a4,
+0x8ee204b0, 0x8ee304b4, 0x24040080, 0xaf4201a8,
+0xaf4301ac, 0xc002ba8, 0x24050080, 0x8c02025c,
+0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200,
+0x24060008, 0xc002bbf, 0xaf4201f8, 0x3c043b9a,
+0x3484ca00, 0x3821, 0x24020006, 0x24030002,
+0xaf4201f4, 0x240203e8, 0xaf430204, 0xaf430200,
+0xaf4401fc, 0xaf420294, 0x24020001, 0xaf430290,
+0xaf42029c, 0x3c030001, 0x671821, 0x90636cd8,
+0x3471021, 0x24e70001, 0xa043022c, 0x2ce2000f,
+0x1440fff8, 0x3471821, 0x24e70001, 0x3c080001,
+0x350840f8, 0x8f820040, 0x3c040001, 0x24845d2c,
+0x24051400, 0x21702, 0x24420030, 0xa062022c,
+0x3471021, 0xa040022c, 0x8c070218, 0x2c03021,
+0x240205c8, 0xafa20010, 0xc002b3b, 0xafa80014,
+0x3c040001, 0x24845d38, 0x3c050000, 0x24a55c80,
+0x24060010, 0x27b10030, 0x2203821, 0x27b30034,
+0xc0017a3, 0xafb30010, 0x3c030001, 0x8c636cc8,
+0x1060000a, 0x408021, 0x8fa30030, 0x2405ff00,
+0x8fa20034, 0x246400ff, 0x852024, 0x831823,
+0x431023, 0xafa20034, 0xafa40030, 0x3c040001,
+0x24845d44, 0x3c050000, 0x24a54100, 0x24060108,
+0x2203821, 0xc0017a3, 0xafb30010, 0x409021,
+0x32c20003, 0x3c010001, 0xac326e80, 0x10400045,
+0x2203821, 0x8f820050, 0x3c030010, 0x431024,
0x10400016, 0x0, 0x8c020218, 0x30420040,
0x1040000f, 0x24020001, 0x8f820050, 0x8c030218,
-0x240e0001, 0x3c040001, 0x24845de0, 0xa3ae003f,
-0xafa20010, 0xafa30014, 0x8f870040, 0x24052000,
-0xc002b17, 0x2c03021, 0x10000004, 0x0,
+0x240e0001, 0x3c040001, 0x24845d50, 0xa3ae003f,
+0xafa20010, 0xafa30014, 0x8f870040, 0x24051500,
+0xc002b3b, 0x2c03021, 0x10000004, 0x0,
+0x3c010001, 0x370821, 0xa02240f4, 0x3c040001,
+0x24845d5c, 0x3c050001, 0x24a55b40, 0x3c060001,
+0x24c65bac, 0xc53023, 0x8f420010, 0x27b30030,
+0x2603821, 0x27b10034, 0x34420a00, 0xaf420010,
+0xc0017a3, 0xafb10010, 0x3c040001, 0x24845d70,
+0x3c050001, 0x24a5b714, 0x3c060001, 0x24c6ba90,
+0xc53023, 0x2603821, 0xaf420108, 0xc0017a3,
+0xafb10010, 0x3c040001, 0x24845d8c, 0x3c050001,
+0x24a5be58, 0x3c060001, 0x24c6c900, 0xc53023,
+0x2603821, 0x3c010001, 0xac226ef4, 0xc0017a3,
+0xafb10010, 0x3c040001, 0x24845da4, 0x10000024,
+0x24051600, 0x3c040001, 0x24845dac, 0x3c050001,
+0x24a5a10c, 0x3c060001, 0x24c6a238, 0xc53023,
+0xc0017a3, 0xafb30010, 0x3c040001, 0x24845dbc,
+0x3c050001, 0x24a5b2b0, 0x3c060001, 0x24c6b70c,
+0xc53023, 0x2203821, 0xaf420108, 0xc0017a3,
+0xafb30010, 0x3c040001, 0x24845dd0, 0x3c050001,
+0x24a5ba98, 0x3c060001, 0x24c6be50, 0xc53023,
+0x2203821, 0x3c010001, 0xac226ef4, 0xc0017a3,
+0xafb30010, 0x3c040001, 0x24845de4, 0x24051650,
+0x2c03021, 0x3821, 0x3c010001, 0xac226ef8,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x32c20020,
+0x10400021, 0x27a70030, 0x3c040001, 0x24845df0,
+0x3c050001, 0x24a5b13c, 0x3c060001, 0x24c6b2a8,
+0xc53023, 0x24022000, 0xaf42001c, 0x27a20034,
+0xc0017a3, 0xafa20010, 0x21900, 0x31982,
+0x3c040800, 0x641825, 0xae430028, 0x24030010,
+0xaf43003c, 0x96e30450, 0xaf430040, 0x8f430040,
+0x3c040001, 0x24845e04, 0xafa00014, 0xafa30010,
+0x8f47001c, 0x24051660, 0x3c010001, 0xac226ef0,
+0x10000025, 0x32c60020, 0x8ee20448, 0x8ee3044c,
+0xaf43001c, 0x8f42001c, 0x2442e000, 0x2c422001,
+0x1440000a, 0x240e0001, 0x3c040001, 0x24845e10,
+0xa3ae003f, 0xafa00010, 0xafa00014, 0x8f46001c,
+0x24051700, 0xc002b3b, 0x3821, 0x3c020000,
+0x24425cbc, 0x21100, 0x21182, 0x3c030800,
+0x431025, 0xae420028, 0x24020008, 0xaf42003c,
+0x96e20450, 0xaf420040, 0x8f420040, 0x3c040001,
+0x24845e1c, 0xafa00014, 0xafa20010, 0x8f47001c,
+0x24051800, 0x32c60020, 0xc002b3b, 0x0,
+0x3c050fff, 0x3c030001, 0x8c636ef4, 0x34a5ffff,
+0x2403021, 0x3c020001, 0x8c426ef8, 0x3c040800,
+0x651824, 0x31882, 0x641825, 0x451024,
+0x21082, 0x441025, 0xacc20080, 0x32c20180,
+0x10400056, 0xacc30020, 0x8f82005c, 0x3c030080,
+0x431024, 0x1040000d, 0x0, 0x8f820050,
+0xafa20010, 0x8f82005c, 0x240e0001, 0x3c040001,
+0x24845e28, 0xa3ae003f, 0xafa20014, 0x8f870040,
+0x24051900, 0xc002b3b, 0x2c03021, 0x8f820050,
+0x3c030010, 0x431024, 0x10400016, 0x0,
+0x8c020218, 0x30420040, 0x1040000f, 0x24020001,
+0x8f820050, 0x8c030218, 0x240e0001, 0x3c040001,
+0x24845d50, 0xa3ae003f, 0xafa20010, 0xafa30014,
+0x8f870040, 0x24052000, 0xc002b3b, 0x2c03021,
+0x10000004, 0x0, 0x3c010001, 0x370821,
+0xa02240f4, 0x3c040001, 0x24845e34, 0x3c050001,
+0x24a55ac0, 0x3c060001, 0x24c65b38, 0xc53023,
+0x8f420008, 0x27b30030, 0x2603821, 0x27b10034,
+0x34420e00, 0xaf420008, 0xc0017a3, 0xafb10010,
+0x3c040001, 0x24845e4c, 0x3c050001, 0x24a5d8b4,
+0x3c060001, 0x24c6e3c8, 0xc53023, 0x2603821,
+0xaf42010c, 0xc0017a3, 0xafb10010, 0x3c040001,
+0x24845e64, 0x3c050001, 0x24a5e9ac, 0x3c060001,
+0x24c6f0f0, 0xc53023, 0x2603821, 0x3c010001,
+0xac226f04, 0xc0017a3, 0xafb10010, 0x3c040001,
+0x24845e7c, 0x10000027, 0x24052100, 0x3c040001,
+0x24845e84, 0x3c050001, 0x24a59fc8, 0x3c060001,
+0x24c6a104, 0xc53023, 0x27b10030, 0x2203821,
+0x27b30034, 0xc0017a3, 0xafb30010, 0x3c040001,
+0x24845e94, 0x3c050001, 0x24a5cad4, 0x3c060001,
+0x24c6d8ac, 0xc53023, 0x2203821, 0xaf42010c,
+0xc0017a3, 0xafb30010, 0x3c040001, 0x24845ea4,
+0x3c050001, 0x24a5e84c, 0x3c060001, 0x24c6e9a4,
+0xc53023, 0x2203821, 0x3c010001, 0xac226f04,
+0xc0017a3, 0xafb30010, 0x3c040001, 0x24845eb8,
+0x24052150, 0x2c03021, 0x3821, 0x3c010001,
+0xac226f10, 0xafa00010, 0xc002b3b, 0xafa00014,
+0x3c110fff, 0x3c030001, 0x8c636f04, 0x3631ffff,
+0x2409821, 0x3c020001, 0x8c426f10, 0x3c0e0800,
+0x711824, 0x31882, 0x6e1825, 0x511024,
+0x21082, 0x4e1025, 0xae630038, 0xae620078,
+0x8c020218, 0x30420040, 0x14400004, 0x24020001,
0x3c010001, 0x370821, 0xa02240f4, 0x3c040001,
-0x24845ec4, 0x3c050001, 0x24a55b50, 0x3c060001,
-0x24c65bc8, 0xc53023, 0x8f420008, 0x27b30030,
-0x2603821, 0x27b10034, 0x34420e00, 0xaf420008,
-0xc00178b, 0xafb10010, 0x3c040001, 0x24845edc,
-0x3c050001, 0x24a5d814, 0x3c060001, 0x24c6e328,
-0xc53023, 0x2603821, 0xaf42010c, 0xc00178b,
-0xafb10010, 0x3c040001, 0x24845ef4, 0x3c050001,
-0x24a5e90c, 0x3c060001, 0x24c6f050, 0xc53023,
-0x2603821, 0x3c010001, 0xac226f80, 0xc00178b,
-0xafb10010, 0x3c040001, 0x24845f0c, 0x10000027,
-0x24052100, 0x3c040001, 0x24845f14, 0x3c050001,
-0x24a59f38, 0x3c060001, 0x24c6a074, 0xc53023,
-0x27b10030, 0x2203821, 0x27b30034, 0xc00178b,
-0xafb30010, 0x3c040001, 0x24845f24, 0x3c050001,
-0x24a5ca74, 0x3c060001, 0x24c6d80c, 0xc53023,
-0x2203821, 0xaf42010c, 0xc00178b, 0xafb30010,
-0x3c040001, 0x24845f34, 0x3c050001, 0x24a5e7ac,
-0x3c060001, 0x24c6e904, 0xc53023, 0x2203821,
-0x3c010001, 0xac226f80, 0xc00178b, 0xafb30010,
-0x3c040001, 0x24845f48, 0x24052150, 0x2c03021,
-0x3821, 0x3c010001, 0xac226f8c, 0xafa00010,
-0xc002b17, 0xafa00014, 0x3c030001, 0x8c636f80,
-0x3c110fff, 0x3631ffff, 0x3c020001, 0x8c426f8c,
-0x3c1e0800, 0x711824, 0x31882, 0x7e1825,
-0x511024, 0x21082, 0x5e1025, 0xae430038,
-0xae420078, 0x8c020218, 0x30420040, 0x14400004,
-0x24020001, 0x3c010001, 0x370821, 0xa02240f4,
-0x3c040001, 0x24845f54, 0x3c050001, 0x24a5e330,
-0x3c060001, 0x24c6e48c, 0xc53023, 0x27b50030,
-0x2a03821, 0x27b30034, 0xc00178b, 0xafb30010,
-0x3c010001, 0xac226f78, 0x511024, 0x21082,
-0x5e1025, 0xae420050, 0x32c22000, 0x10400005,
-0x2a03821, 0x3c020000, 0x24425c5c, 0x1000000d,
-0x511024, 0x3c040001, 0x24845f68, 0x3c050001,
-0x24a5e494, 0x3c060001, 0x24c6e644, 0xc53023,
-0xc00178b, 0xafb30010, 0x3c010001, 0xac226f90,
-0x511024, 0x21082, 0x5e1025, 0xae420048,
-0x32c24000, 0x10400005, 0x27a70030, 0x3c020000,
-0x24425c5c, 0x1000000e, 0x21100, 0x3c040001,
-0x24845f80, 0x3c050001, 0x24a5e64c, 0x3c060001,
-0x24c6e7a4, 0xc53023, 0x27a20034, 0xc00178b,
-0xafa20010, 0x3c010001, 0xac226f84, 0x21100,
-0x21182, 0x3c030800, 0x431025, 0xae420060,
-0x3c040001, 0x24845f98, 0x3c050001, 0x24a581d0,
-0x3c060001, 0x24c685f0, 0xc53023, 0x27b10030,
-0x2203821, 0x27b30034, 0xc00178b, 0xafb30010,
-0x3c1e0fff, 0x37deffff, 0x3c040001, 0x24845fa4,
-0x3c050000, 0x24a56408, 0x3c060000, 0x24c66528,
-0xc53023, 0x2203821, 0x3c010001, 0xac226f58,
-0x5e1024, 0x21082, 0x3c150800, 0x551025,
-0xae4200b8, 0xc00178b, 0xafb30010, 0x3c040001,
-0x24845fb0, 0x3c050000, 0x24a56530, 0x3c060000,
-0x24c667a8, 0xc53023, 0x2203821, 0x3c010001,
-0xac226f4c, 0x5e1024, 0x21082, 0x551025,
-0xae4200e8, 0xc00178b, 0xafb30010, 0x3c040001,
-0x24845fc8, 0x3c050000, 0x24a567b0, 0x3c060000,
-0x24c668e0, 0xc53023, 0x2203821, 0x3c010001,
-0xac226f44, 0x5e1024, 0x21082, 0x551025,
-0xae4200c0, 0xc00178b, 0xafb30010, 0x3c040001,
-0x24845fe0, 0x3c050001, 0x24a5fa30, 0x3c060001,
-0x24c6fb08, 0xc53023, 0x2203821, 0x3c010001,
-0xac226f50, 0x5e1024, 0x21082, 0x551025,
-0xae4200c8, 0xc00178b, 0xafb30010, 0x3c040001,
-0x24845fec, 0x3c050001, 0x24a5c8dc, 0x3c060001,
-0x24c6c9c0, 0xc53023, 0x2203821, 0xaf420110,
-0xc00178b, 0xafb30010, 0x3c040001, 0x24845ffc,
-0x3c050001, 0x24a5c8b0, 0x3c060001, 0x24c6c8d4,
-0xc53023, 0x2203821, 0xaf420124, 0xc00178b,
-0xafb30010, 0x3c040001, 0x2484600c, 0x3c050001,
-0x24a55b10, 0x3c060001, 0x24c65b3c, 0xc53023,
-0x2203821, 0xaf420120, 0xaf420114, 0xc00178b,
-0xafb30010, 0x3c040001, 0x24846018, 0x3c050001,
-0x24a5f1f8, 0x3c060001, 0x24c6f614, 0xc53023,
-0x2203821, 0xaf420118, 0xc00178b, 0xafb30010,
-0x3c010001, 0xac226f94, 0x5e1024, 0x21082,
-0x551025, 0xc003f9b, 0xae4200d0, 0xc003c18,
-0x0, 0xc002784, 0x0, 0xac000228,
+0x24845ec4, 0x3c050001, 0x24a5e3d0, 0x3c060001,
+0x24c6e52c, 0xc53023, 0x27be0030, 0x3c03821,
+0x27b50034, 0xc0017a3, 0xafb50010, 0x3c010001,
+0xac226efc, 0x511024, 0x21082, 0x3c0e0800,
+0x4e1025, 0xae620050, 0x32c22000, 0x10400006,
+0x3c03821, 0x3c020000, 0x24425cbc, 0x2221024,
+0x1000000f, 0x21082, 0x3c040001, 0x24845ed8,
+0x3c050001, 0x24a5e534, 0x3c060001, 0x24c6e6e4,
+0xc53023, 0xc0017a3, 0xafb50010, 0x3c010001,
+0xac226f14, 0x511024, 0x21082, 0x3c0e0800,
+0x4e1025, 0xae620048, 0x32c24000, 0x10400005,
+0x27a70030, 0x3c020000, 0x24425cbc, 0x1000000e,
+0x21100, 0x3c040001, 0x24845ef0, 0x3c050001,
+0x24a5e6ec, 0x3c060001, 0x24c6e844, 0xc53023,
+0x27a20034, 0xc0017a3, 0xafa20010, 0x3c010001,
+0xac226f08, 0x21100, 0x21182, 0x3c030800,
+0x431025, 0xae420060, 0x3c040001, 0x24845f08,
+0x3c050001, 0x24a58230, 0x3c060001, 0x24c68650,
+0xc53023, 0x27b10030, 0x2203821, 0x27b30034,
+0xc0017a3, 0xafb30010, 0x3c0e0fff, 0x35ceffff,
+0x3c040001, 0x24845f14, 0x3c050000, 0x24a56468,
+0x3c060000, 0x24c66588, 0xc53023, 0x2203821,
+0x240f021, 0x3c010001, 0xac226edc, 0x4e1024,
+0x21082, 0x3c150800, 0x551025, 0xafae0044,
+0xafc200b8, 0xc0017a3, 0xafb30010, 0x3c040001,
+0x24845f20, 0x3c050000, 0x24a56590, 0x3c060000,
+0x24c66808, 0x8fae0044, 0xc53023, 0x2203821,
+0x3c010001, 0xac226ed0, 0x4e1024, 0x21082,
+0x551025, 0xafc200e8, 0xc0017a3, 0xafb30010,
+0x3c040001, 0x24845f38, 0x3c050000, 0x24a56810,
+0x3c060000, 0x24c66940, 0x8fae0044, 0xc53023,
+0x2203821, 0x3c010001, 0xac226ec8, 0x4e1024,
+0x21082, 0x551025, 0xafc200c0, 0xc0017a3,
+0xafb30010, 0x3c040001, 0x24845f50, 0x3c050001,
+0x24a5fad0, 0x3c060001, 0x24c6fba8, 0x8fae0044,
+0xc53023, 0x2203821, 0x3c010001, 0xac226ed4,
+0x4e1024, 0x21082, 0x551025, 0xafc200c8,
+0xc0017a3, 0xafb30010, 0x3c040001, 0x24845f5c,
+0x3c050001, 0x24a5c93c, 0x3c060001, 0x24c6ca20,
+0xc53023, 0x2203821, 0xaf420110, 0xc0017a3,
+0xafb30010, 0x3c040001, 0x24845f6c, 0x3c050001,
+0x24a5c910, 0x3c060001, 0x24c6c934, 0xc53023,
+0x2203821, 0xaf420124, 0xc0017a3, 0xafb30010,
+0x3c040001, 0x24845f7c, 0x3c050001, 0x24a55a80,
+0x3c060001, 0x24c65aac, 0xc53023, 0x2203821,
+0xaf420120, 0xaf420114, 0xc0017a3, 0xafb30010,
+0x3c040001, 0x24845f88, 0x3c050001, 0x24a5f298,
+0x3c060001, 0x24c6f6b4, 0xc53023, 0x2203821,
+0xaf420118, 0xc0017a3, 0xafb30010, 0x8fae0044,
+0x3c010001, 0xac226f18, 0x4e1024, 0x21082,
+0x551025, 0xc003fc3, 0xafc200d0, 0xc003c40,
+0x0, 0xc0027a8, 0x0, 0xac000228,
0xac00022c, 0x96e20450, 0x2442ffff, 0xaf420038,
0x96e20460, 0xaf420080, 0x32c24000, 0x14400003,
0x0, 0x96e20480, 0xaf420084, 0x96e70490,
0x50e00001, 0x24070800, 0x24e2ffff, 0xaf420088,
0xaf42007c, 0x24020800, 0x10e2000f, 0x32c24000,
0x10400003, 0x24020400, 0x10e2000b, 0x0,
-0x240e0001, 0x3c040001, 0x24846028, 0xa3ae003f,
+0x240e0001, 0x3c040001, 0x24845f98, 0xa3ae003f,
0x96e60490, 0x24052170, 0x2c03821, 0xafa00010,
-0xc002b17, 0xafa00014, 0x8f430138, 0x8f440138,
+0xc002b3b, 0xafa00014, 0x8f430138, 0x8f440138,
0x24020001, 0xa34205c2, 0xaf430094, 0xaf440098,
0xafa00010, 0xafa00014, 0x8f460080, 0x8f470084,
-0x3c040001, 0x24846034, 0xc002b17, 0x24052200,
-0xc002480, 0x3c110800, 0x3c1433d8, 0x3694cb58,
-0x3c020800, 0x34420080, 0x3c040001, 0x24846040,
-0x3c050000, 0x24a55ca0, 0x3c060000, 0x24c65cbc,
+0x3c040001, 0x24845fa4, 0xc002b3b, 0x24052200,
+0xc0024a4, 0x3c110800, 0x3c1433d8, 0x3694cb58,
+0x3c020800, 0x34420080, 0x3c040001, 0x24845fb0,
+0x3c050000, 0x24a55d00, 0x3c060000, 0x24c65d1c,
0xc53023, 0x27a70030, 0xaf820060, 0x2402ffff,
-0xaf820064, 0x27a20034, 0xc00178b, 0xafa20010,
-0x3c010001, 0xac226f34, 0x21100, 0x21182,
-0x511025, 0xc0018e4, 0xae420000, 0x8f820240,
+0xaf820064, 0x27a20034, 0xc0017a3, 0xafa20010,
+0x3c010001, 0xac226eb8, 0x21100, 0x21182,
+0x511025, 0xc0018fc, 0xae420000, 0x8f820240,
0x3c030001, 0x431025, 0xaf820240, 0x3c020000,
0x24424034, 0xaf820244, 0xaf800240, 0x8f820060,
0x511024, 0x14400005, 0x3c030800, 0x8f820060,
-0x431024, 0x1040fffd, 0x0, 0xc003c25,
+0x431024, 0x1040fffd, 0x0, 0xc003c4d,
0x8821, 0x3c020100, 0xafa20020, 0x8f530018,
0x240200ff, 0x56620001, 0x26710001, 0x8c020228,
0x1622000e, 0x1330c0, 0x8f42033c, 0x24420001,
0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x24845cb4, 0x3c050009, 0xafa00014, 0xafa20010,
+0x24845c24, 0x3c050009, 0xafa00014, 0xafa20010,
0x8fa60020, 0x1000003f, 0x34a50100, 0xd71021,
0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
0xc01821, 0x8f440178, 0x8f45017c, 0x1021,
@@ -5004,21 +5005,21 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x24070008, 0xa32821, 0xa3482b, 0x822021,
0x100f809, 0x892021, 0x1440000b, 0x24070008,
0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24845cbc, 0x3c050009, 0xafa20014, 0x8fa60020,
+0x24845c2c, 0x3c050009, 0xafa20014, 0x8fa60020,
0x1000001c, 0x34a50200, 0x8f440160, 0x8f450164,
0x8f43000c, 0xaf510018, 0x8f860120, 0x24020010,
0xafa20010, 0xafb10014, 0xafa30018, 0x8f42010c,
0x40f809, 0x24c6001c, 0x14400010, 0x0,
0x8f420340, 0x24420001, 0xaf420340, 0x8f420340,
0x8f820120, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24845cc4, 0x3c050009, 0xafa20014, 0x8fa60020,
-0x34a50300, 0xc002b17, 0x2603821, 0x8f4202e4,
+0x24845c34, 0x3c050009, 0xafa20014, 0x8fa60020,
+0x34a50300, 0xc002b3b, 0x2603821, 0x8f4202e4,
0x24420001, 0xaf4202e4, 0x8f4202e4, 0x93a2003f,
0x10400069, 0x3c020700, 0x34423000, 0xafa20028,
0x8f530018, 0x240200ff, 0x12620002, 0x8821,
0x26710001, 0x8c020228, 0x1622000e, 0x1330c0,
0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24845cb4, 0x3c050009,
+0x8c020228, 0x3c040001, 0x24845c24, 0x3c050009,
0xafa00014, 0xafa20010, 0x8fa60028, 0x1000003f,
0x34a50100, 0xd71021, 0x8fa30028, 0x8fa4002c,
0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
@@ -5027,18 +5028,18 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
0xa3482b, 0x822021, 0x100f809, 0x892021,
0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24845cbc, 0x3c050009,
+0x8f820124, 0x3c040001, 0x24845c2c, 0x3c050009,
0xafa20014, 0x8fa60028, 0x1000001c, 0x34a50200,
0x8f440160, 0x8f450164, 0x8f43000c, 0xaf510018,
0x8f860120, 0x24020010, 0xafa20010, 0xafb10014,
0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
0x14400010, 0x0, 0x8f420340, 0x24420001,
0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24845cc4, 0x3c050009,
-0xafa20014, 0x8fa60028, 0x34a50300, 0xc002b17,
+0x8f820124, 0x3c040001, 0x24845c34, 0x3c050009,
+0xafa20014, 0x8fa60028, 0x34a50300, 0xc002b3b,
0x2603821, 0x8f4202f0, 0x24420001, 0xaf4202f0,
-0x8f4202f0, 0x3c040001, 0x24846050, 0xafa00010,
-0xafa00014, 0x8fa60028, 0x24052300, 0xc002b17,
+0x8f4202f0, 0x3c040001, 0x24845fc0, 0xafa00010,
+0xafa00014, 0x8fa60028, 0x24052300, 0xc002b3b,
0x3821, 0x10000004, 0x0, 0x8c020264,
0x10400005, 0x0, 0x8f8200a0, 0x30420004,
0x1440fffa, 0x0, 0x8f820044, 0x34420004,
@@ -5049,31 +5050,31 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x431021, 0xaf420090, 0x24020001, 0xaf42008c,
0x32c20008, 0x10400006, 0x0, 0x8f820214,
0x3c038100, 0x3042ffff, 0x431025, 0xaf820214,
-0x3c030001, 0x8c636e14, 0x30620002, 0x10400009,
-0x30620001, 0x3c040001, 0x2484605c, 0x3c050000,
-0x24a56cf0, 0x3c060000, 0x24c67168, 0x10000012,
+0x3c030001, 0x8c636d94, 0x30620002, 0x10400009,
+0x30620001, 0x3c040001, 0x24845fcc, 0x3c050000,
+0x24a56d50, 0x3c060000, 0x24c671c8, 0x10000012,
0xc53023, 0x10400009, 0x0, 0x3c040001,
-0x2484606c, 0x3c050000, 0x24a57170, 0x3c060000,
-0x24c67618, 0x10000008, 0xc53023, 0x3c040001,
-0x2484607c, 0x3c050000, 0x24a568e8, 0x3c060000,
-0x24c66ce8, 0xc53023, 0x27a70030, 0x27a20034,
-0xc00178b, 0xafa20010, 0x3c010001, 0xac226f48,
-0x3c020001, 0x8c426f48, 0x3c030800, 0x21100,
+0x24845fdc, 0x3c050000, 0x24a571d0, 0x3c060000,
+0x24c67678, 0x10000008, 0xc53023, 0x3c040001,
+0x24845fec, 0x3c050000, 0x24a56948, 0x3c060000,
+0x24c66d48, 0xc53023, 0x27a70030, 0x27a20034,
+0xc0017a3, 0xafa20010, 0x3c010001, 0xac226ecc,
+0x3c020001, 0x8c426ecc, 0x3c030800, 0x21100,
0x21182, 0x431025, 0xae420040, 0x8f8200a0,
0xafa20010, 0x8f8200b0, 0xafa20014, 0x8f86005c,
-0x8f87011c, 0x3c040001, 0x2484608c, 0x3c010001,
-0xac366f20, 0x3c010001, 0xac206f10, 0x3c010001,
-0xac3c6f08, 0x3c010001, 0xac3b6f38, 0x3c010001,
-0xac376f3c, 0x3c010001, 0xac3a6f1c, 0xc002b17,
+0x8f87011c, 0x3c040001, 0x24845ffc, 0x3c010001,
+0xac366ea4, 0x3c010001, 0xac206e94, 0x3c010001,
+0xac3c6e8c, 0x3c010001, 0xac3b6ebc, 0x3c010001,
+0xac376ec0, 0x3c010001, 0xac3a6ea0, 0xc002b3b,
0x24052400, 0x8f820200, 0xafa20010, 0x8f820220,
0xafa20014, 0x8f860044, 0x8f870050, 0x3c040001,
-0x24846098, 0xc002b17, 0x24052500, 0x8f830060,
+0x24846008, 0xc002b3b, 0x24052500, 0x8f830060,
0x74100b, 0x242000a, 0x200f821, 0x0,
-0xd, 0x8fbf0058, 0x8fbe0054, 0x8fb50050,
-0x8fb3004c, 0x8fb20048, 0x8fb10044, 0x8fb00040,
-0x3e00008, 0x27bd0060, 0x27bdffe0, 0x3c040001,
-0x248460a4, 0x24052600, 0x3021, 0x3821,
-0xafbf0018, 0xafa00010, 0xc002b17, 0xafa00014,
+0xd, 0x8fbf0060, 0x8fbe005c, 0x8fb50058,
+0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048,
+0x3e00008, 0x27bd0068, 0x27bdffe0, 0x3c040001,
+0x24846014, 0x24052600, 0x3021, 0x3821,
+0xafbf0018, 0xafa00010, 0xc002b3b, 0xafa00014,
0x8fbf0018, 0x3e00008, 0x27bd0020, 0x3e00008,
0x0, 0x3e00008, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0,
@@ -5083,15 +5084,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa40018, 0xa22823, 0xa32824, 0x8ca20000,
0x1044000a, 0x0, 0xafa50010, 0x8ca20000,
0xafa20014, 0x8f860150, 0x8f870250, 0x3c040001,
-0x248460ac, 0xc002b17, 0x24052700, 0x8fbf0218,
+0x2484601c, 0xc002b3b, 0x24052700, 0x8fbf0218,
0x3e00008, 0x27bd0220, 0x27bdffe0, 0x3c06abba,
0x34c6babe, 0xafb00018, 0x3c100004, 0x3c07007f,
0x34e7ffff, 0xafbf001c, 0x102840, 0x8e040000,
0x8ca30000, 0xaca00000, 0xae060000, 0x8ca20000,
0xaca30000, 0x10460005, 0xae040000, 0xa08021,
0xf0102b, 0x1040fff5, 0x102840, 0x3c040001,
-0x248460b8, 0x24052800, 0x2003021, 0x3821,
-0xafa00010, 0xc002b17, 0xafa00014, 0x2001021,
+0x24846028, 0x24052800, 0x2003021, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x2001021,
0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020,
0x8c020224, 0x3047003f, 0x10e00010, 0x803021,
0x2821, 0x24030020, 0xe31024, 0x10400002,
@@ -5106,84 +5107,84 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8ea20000, 0x2403fffc, 0xc38024, 0x50102b,
0x1440001b, 0xe08821, 0x8e330000, 0xafb00010,
0x8ea20000, 0xafa20014, 0x8e270000, 0x24053000,
-0xc002b17, 0x2403021, 0x8e230000, 0x702021,
+0xc002b3b, 0x2403021, 0x8e230000, 0x702021,
0x64102b, 0x10400007, 0x2402821, 0x8ca20000,
0xac620000, 0x24630004, 0x64102b, 0x1440fffb,
0x24a50004, 0x8ea20000, 0x501023, 0xaea20000,
0x8e220000, 0x501021, 0x1000000b, 0xae220000,
0x2402002d, 0xa0820000, 0xafb00010, 0x8ea20000,
0x2409821, 0xafa20014, 0x8e270000, 0x24053100,
-0xc002b17, 0x2603021, 0x2601021, 0x8fbf002c,
+0xc002b3b, 0x2603021, 0x2601021, 0x8fbf002c,
0x8fb50028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
0x8fb00018, 0x3e00008, 0x27bd0030, 0x27bdffe8,
-0x3c1cc000, 0x3c05fffe, 0x3c030001, 0x8c636f00,
-0x3c040001, 0x8c846f0c, 0x34a5bf08, 0x24021ffc,
-0x3c010001, 0xac226d50, 0x3c0200c0, 0x3c010001,
-0xac226d54, 0x3c020020, 0xafbf0010, 0x3c0100c0,
+0x3c1cc000, 0x3c05fffe, 0x3c030001, 0x8c636e84,
+0x3c040001, 0x8c846e90, 0x34a5bf08, 0x24021ffc,
+0x3c010001, 0xac226cd0, 0x3c0200c0, 0x3c010001,
+0xac226cd4, 0x3c020020, 0xafbf0010, 0x3c0100c0,
0xac201ffc, 0x431023, 0x441023, 0x245bb000,
-0x365b821, 0x3c1d0001, 0x8fbd6d4c, 0x3a0f021,
+0x365b821, 0x3c1d0001, 0x8fbd6ccc, 0x3a0f021,
0x3c0400c0, 0x34840200, 0x3c1a00c0, 0x3c0300c0,
-0x346307c8, 0x24021dfc, 0x3c010001, 0xac226d50,
-0x24021834, 0x3c010001, 0xac246d54, 0x3c010001,
-0xac226d50, 0x3c010001, 0xac236d54, 0xc0017f5,
+0x346307c8, 0x24021dfc, 0x3c010001, 0xac226cd0,
+0x24021834, 0x3c010001, 0xac246cd4, 0x3c010001,
+0xac226cd0, 0x3c010001, 0xac236cd4, 0xc00180d,
0x375a0200, 0x8fbf0010, 0x3e00008, 0x27bd0018,
-0x27bdffc8, 0x3c040001, 0x248460c4, 0x24053200,
-0x3c020001, 0x8c426d50, 0x3c030001, 0x8c636d54,
+0x27bdffc8, 0x3c040001, 0x24846034, 0x24053200,
+0x3c020001, 0x8c426cd0, 0x3c030001, 0x8c636cd4,
0x3021, 0x3603821, 0xafbf0030, 0xafb3002c,
0xafb20028, 0xafb10024, 0xafb00020, 0xafa2001c,
-0xafa30018, 0xafb70010, 0xc002b17, 0xafba0014,
-0xc0018fe, 0x0, 0x8f820240, 0x34420004,
+0xafa30018, 0xafb70010, 0xc002b3b, 0xafba0014,
+0xc001916, 0x0, 0x8f820240, 0x34420004,
0xaf820240, 0x24020001, 0xaf420000, 0x3c020001,
0x571021, 0x904240f4, 0x10400092, 0x2403fffc,
-0x3c100001, 0x2610abe3, 0x3c120001, 0x2652a7bc,
+0x3c100001, 0x2610ac73, 0x3c120001, 0x2652a84c,
0x2121023, 0x438024, 0x8fa3001c, 0x3c040001,
-0x248460d0, 0x70102b, 0x1440001a, 0x27b30018,
+0x24846040, 0x70102b, 0x1440001a, 0x27b30018,
0x8fb10018, 0x24053000, 0x2403021, 0xafb00010,
-0xafa30014, 0xc002b17, 0x2203821, 0x8fa30018,
+0xafa30014, 0xc002b3b, 0x2203821, 0x8fa30018,
0x702021, 0x64102b, 0x10400007, 0x2403021,
0x8cc20000, 0xac620000, 0x24630004, 0x64102b,
0x1440fffb, 0x24c60004, 0x8fa2001c, 0x501023,
0xafa2001c, 0x8e620000, 0x501021, 0x1000000a,
0xae620000, 0x2408821, 0x24053100, 0xafb00010,
0xafa30014, 0x8fa70018, 0x2203021, 0x2402002d,
-0xc002b17, 0xa0820000, 0x24070020, 0x8fa3001c,
-0x3c040001, 0x248460ec, 0x24120020, 0x3c010001,
-0xac316f2c, 0x2c620020, 0x1440001d, 0x27b10018,
-0x8fb00018, 0x24053000, 0x3c060001, 0x24c66fd0,
-0xafa70010, 0xafa30014, 0xc002b17, 0x2003821,
-0x8fa30018, 0x3c040001, 0x24846fd0, 0x24650020,
+0xc002b3b, 0xa0820000, 0x24070020, 0x8fa3001c,
+0x3c040001, 0x2484605c, 0x24120020, 0x3c010001,
+0xac316eb0, 0x2c620020, 0x1440001d, 0x27b10018,
+0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f50,
+0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821,
+0x8fa30018, 0x3c040001, 0x24846f50, 0x24650020,
0x65102b, 0x10400007, 0x0, 0x8c820000,
0xac620000, 0x24630004, 0x65102b, 0x1440fffb,
0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c,
0x8e220000, 0x521021, 0x1000000b, 0xae220000,
-0x3c100001, 0x26106fd0, 0x24053100, 0xafa70010,
+0x3c100001, 0x26106f50, 0x24053100, 0xafa70010,
0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d,
-0xc002b17, 0xa0820000, 0x24070020, 0x3c040001,
-0x24846100, 0x8fa3001c, 0x24120020, 0x3c010001,
-0xac306f60, 0x2c620020, 0x1440001d, 0x27b10018,
-0x8fb00018, 0x24053000, 0x3c060001, 0x24c66ff0,
-0xafa70010, 0xafa30014, 0xc002b17, 0x2003821,
-0x8fa30018, 0x3c040001, 0x24846ff0, 0x24650020,
+0xc002b3b, 0xa0820000, 0x24070020, 0x3c040001,
+0x24846070, 0x8fa3001c, 0x24120020, 0x3c010001,
+0xac306ee4, 0x2c620020, 0x1440001d, 0x27b10018,
+0x8fb00018, 0x24053000, 0x3c060001, 0x24c66f70,
+0xafa70010, 0xafa30014, 0xc002b3b, 0x2003821,
+0x8fa30018, 0x3c040001, 0x24846f70, 0x24650020,
0x65102b, 0x10400007, 0x0, 0x8c820000,
0xac620000, 0x24630004, 0x65102b, 0x1440fffb,
0x24840004, 0x8fa2001c, 0x521023, 0xafa2001c,
0x8e220000, 0x521021, 0x1000000b, 0xae220000,
-0x3c100001, 0x26106ff0, 0x24053100, 0xafa70010,
+0x3c100001, 0x26106f70, 0x24053100, 0xafa70010,
0xafa30014, 0x8fa70018, 0x2003021, 0x2402002d,
-0xc002b17, 0xa0820000, 0x3c010001, 0x10000031,
-0xac306f5c, 0x3c100001, 0x261081bf, 0x3c120001,
-0x2652803c, 0x2121023, 0x438024, 0x8fa3001c,
-0x3c040001, 0x24846114, 0x70102b, 0x1440001a,
+0xc002b3b, 0xa0820000, 0x3c010001, 0x10000031,
+0xac306ee0, 0x3c100001, 0x2610821f, 0x3c120001,
+0x2652809c, 0x2121023, 0x438024, 0x8fa3001c,
+0x3c040001, 0x24846084, 0x70102b, 0x1440001a,
0x27b30018, 0x8fb10018, 0x24053000, 0x2403021,
-0xafb00010, 0xafa30014, 0xc002b17, 0x2203821,
+0xafb00010, 0xafa30014, 0xc002b3b, 0x2203821,
0x8fa30018, 0x702021, 0x64102b, 0x10400007,
0x2403021, 0x8cc20000, 0xac620000, 0x24630004,
0x64102b, 0x1440fffb, 0x24c60004, 0x8fa2001c,
0x501023, 0xafa2001c, 0x8e620000, 0x501021,
0x1000000a, 0xae620000, 0x2408821, 0x24053100,
0xafb00010, 0xafa30014, 0x8fa70018, 0x2203021,
-0x2402002d, 0xc002b17, 0xa0820000, 0x3c010001,
-0xac316f2c, 0x3c030001, 0x8c636f2c, 0x24020400,
+0x2402002d, 0xc002b3b, 0xa0820000, 0x3c010001,
+0xac316eb0, 0x3c030001, 0x8c636eb0, 0x24020400,
0x60f809, 0xaf820070, 0x8fbf0030, 0x8fb3002c,
0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
0x27bd0038, 0x0, 0x0, 0x8f820040,
@@ -5197,21 +5198,21 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf820078, 0x27bdffe8, 0xafbf0010, 0x8f820054,
0x244203e8, 0xaf820058, 0x3c020800, 0x2c21024,
0x10400004, 0x3c02f7ff, 0x3442ffff, 0x2c2b024,
-0x36940040, 0x3c020001, 0x8c426e28, 0x10400017,
-0x3c020200, 0x3c030001, 0x8c636f98, 0x10600016,
-0x282a025, 0x3c020001, 0x8c426ec4, 0x14400012,
-0x3c020200, 0x3c020001, 0x8c426e14, 0x30420003,
+0x36940040, 0x3c020001, 0x8c426da8, 0x10400017,
+0x3c020200, 0x3c030001, 0x8c636f1c, 0x10600016,
+0x282a025, 0x3c020001, 0x8c426e44, 0x14400012,
+0x3c020200, 0x3c020001, 0x8c426d94, 0x30420003,
0x1440000d, 0x3c020200, 0x8f830224, 0x3c020002,
-0x8c42906c, 0x10620008, 0x3c020200, 0xc003d87,
-0x0, 0x10000004, 0x3c020200, 0xc004161,
+0x8c428fec, 0x10620008, 0x3c020200, 0xc003daf,
+0x0, 0x10000004, 0x3c020200, 0xc004196,
0x0, 0x3c020200, 0x2c21024, 0x10400003,
-0x0, 0xc001f33, 0x0, 0x8f4200d8,
+0x0, 0xc001f4b, 0x0, 0x8f4200d8,
0x8f4300dc, 0x24420001, 0xaf4200d8, 0x43102b,
0x14400003, 0x0, 0xaf4000d8, 0x36940080,
0x8c030238, 0x1060000c, 0x0, 0x8f4201b0,
0x244203e8, 0xaf4201b0, 0x43102b, 0x14400006,
0x0, 0x934205c5, 0x14400003, 0x0,
-0xc001d88, 0x0, 0x8fbf0010, 0x3e00008,
+0xc001da0, 0x0, 0x8fbf0010, 0x3e00008,
0x27bd0018, 0x3e00008, 0x0, 0x27bdffd8,
0xafbf0020, 0x8f43002c, 0x8f420038, 0x10620059,
0x0, 0x3c020001, 0x571021, 0x904240f0,
@@ -5220,8 +5221,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809,
0x24c6001c, 0x14400011, 0x24020001, 0x3c010001,
0x370821, 0xa02240f0, 0x8f820124, 0xafa20010,
-0x8f820128, 0x3c040001, 0x248461b8, 0xafa20014,
-0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b17,
+0x8f820128, 0x3c040001, 0x24846128, 0xafa20014,
+0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b,
0x34a50900, 0x1000005c, 0x0, 0x8f420300,
0x24420001, 0xaf420300, 0x8f420300, 0x8f42002c,
0xa34005c1, 0x10000027, 0xaf420038, 0x8f440170,
@@ -5230,8 +5231,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
0x24020001, 0x3c010001, 0x370821, 0xa02240f1,
0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x248461c4, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b17, 0x34a51100, 0x10000036,
+0x24846134, 0xafa20014, 0x8f46002c, 0x8f870120,
+0x3c050009, 0xc002b3b, 0x34a51100, 0x10000036,
0x0, 0x8f420300, 0x8f43002c, 0x24420001,
0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
0xaf430038, 0x3c010001, 0x370821, 0xa02040f1,
@@ -5259,8 +5260,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
0x14400011, 0x24020001, 0x3c010001, 0x370821,
0xa02240f2, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x248461cc, 0xafa20014, 0x8f460044,
-0x8f870120, 0x3c050009, 0xc002b17, 0x34a51300,
+0x3c040001, 0x2484613c, 0xafa20014, 0x8f460044,
+0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51300,
0x1000000f, 0x0, 0x8f420304, 0x24420001,
0xaf420304, 0x8f420304, 0x8f420044, 0xaf42007c,
0x3c010001, 0x370821, 0xa02040f2, 0x10000004,
@@ -5272,20 +5273,20 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x431024, 0xaf820060, 0x8f420000, 0x10400003,
0x0, 0x10000002, 0xaf80004c, 0xaf800048,
0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008,
-0x0, 0x3c020001, 0x8c426e28, 0x27bdffa8,
+0x0, 0x3c020001, 0x8c426da8, 0x27bdffa8,
0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044,
0xafb20040, 0xafb1003c, 0xafb00038, 0x104000d5,
0x8f900044, 0x8f4200d0, 0x24430001, 0x2842000b,
0x144000e4, 0xaf4300d0, 0x8f420004, 0x30420002,
0x1440009c, 0xaf4000d0, 0x8f420004, 0x3c030001,
-0x8c636e18, 0x34420002, 0xaf420004, 0x24020001,
+0x8c636d98, 0x34420002, 0xaf420004, 0x24020001,
0x14620003, 0x3c020600, 0x10000002, 0x34423000,
0x34421000, 0xafa20020, 0x8f4a0018, 0xafaa0034,
0x27aa0020, 0xafaa002c, 0x8faa0034, 0x240200ff,
0x11420002, 0x1821, 0x25430001, 0x8c020228,
0x609821, 0x1662000e, 0x3c050009, 0x8f42033c,
0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x8fa70034, 0x3c040001, 0x2484619c, 0xafa00014,
+0x8fa70034, 0x3c040001, 0x2484610c, 0xafa00014,
0xafa20010, 0x8fa60020, 0x10000070, 0x34a50500,
0x8faa0034, 0xa38c0, 0xf71021, 0x8fa30020,
0x8fa40024, 0xac4304c0, 0xac4404c4, 0x8f830054,
@@ -5300,7 +5301,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x32a200ff, 0x54400018, 0xaf530018, 0x8f420378,
0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
0x8faa002c, 0x8fa70034, 0xafa20010, 0x8f820124,
-0x3c040001, 0x248461a8, 0xafa20014, 0x8d460000,
+0x3c040001, 0x24846118, 0xafa20014, 0x8d460000,
0x3c050009, 0x10000035, 0x34a50600, 0x8f420308,
0x24150001, 0x24420001, 0xaf420308, 0x8f420308,
0x1000001e, 0x32a200ff, 0x8f830054, 0x8f820054,
@@ -5313,8 +5314,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1440ffee, 0x0, 0x32a200ff, 0x14400011,
0x3c050009, 0x8f420378, 0x24420001, 0xaf420378,
0x8f420378, 0x8f820120, 0x8faa002c, 0x8fa70034,
-0xafa20010, 0x8f820124, 0x3c040001, 0x248461b0,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b17,
+0xafa20010, 0x8f820124, 0x3c040001, 0x24846120,
+0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
0x0, 0x8f4202ec, 0x24420001, 0xaf4202ec,
0x8f4202ec, 0x8f420004, 0x30420001, 0x50400029,
0x36100040, 0x3c020400, 0x2c21024, 0x10400013,
@@ -5337,19 +5338,19 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8fbf0050, 0x8fbe004c, 0x8fb50048, 0x8fb30044,
0x8fb20040, 0x8fb1003c, 0x8fb00038, 0x3e00008,
0x27bd0058, 0x3e00008, 0x0, 0x3c020001,
-0x8c426e28, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
+0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
0x104000c7, 0xafb00030, 0x8f4200d0, 0x24430001,
0x2842000b, 0x144000da, 0xaf4300d0, 0x8f420004,
0x30420002, 0x14400097, 0xaf4000d0, 0x8f420004,
-0x3c030001, 0x8c636e18, 0x34420002, 0xaf420004,
+0x3c030001, 0x8c636d98, 0x34420002, 0xaf420004,
0x24020001, 0x14620003, 0x3c020600, 0x10000002,
0x34423000, 0x34421000, 0xafa20020, 0x1821,
0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
0xafaa002c, 0x27c30001, 0x8c020228, 0x609021,
0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484619c, 0x3c050009, 0xafa00014, 0xafa20010,
+0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010,
0x8fa60020, 0x1000006d, 0x34a50500, 0xf71021,
0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
@@ -5363,7 +5364,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x326200ff, 0x54400017, 0xaf520018,
0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x248461a8, 0x3c050009, 0xafa20014,
+0x3c040001, 0x24846118, 0x3c050009, 0xafa20014,
0x8d460000, 0x10000035, 0x34a50600, 0x8f420308,
0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
0x1000001e, 0x326200ff, 0x8f830054, 0x8f820054,
@@ -5376,43 +5377,43 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1440ffee, 0x0, 0x326200ff, 0x14400011,
0x0, 0x8f420378, 0x24420001, 0xaf420378,
0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248461b0, 0x3c050009,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b17,
+0x8f820124, 0x3c040001, 0x24846120, 0x3c050009,
+0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
0x3c03821, 0x8f4202ec, 0x24420001, 0xaf4202ec,
0x8f4202ec, 0x8f420004, 0x30420001, 0x10400018,
0x24040001, 0x8f420250, 0x8f430254, 0x8f4501b4,
-0x3c010001, 0x14650006, 0xa0246d71, 0x8f420270,
+0x3c010001, 0x14650006, 0xa0246cf1, 0x8f420270,
0x8f430274, 0x8f4401b8, 0x10640021, 0x0,
-0x8f420250, 0x8f430254, 0x3c040001, 0x90846d70,
+0x8f420250, 0x8f430254, 0x3c040001, 0x90846cf0,
0x8f460270, 0x8f470274, 0x38840001, 0xaf4301b4,
-0xaf4701b8, 0x3c010001, 0x10000025, 0xa0246d70,
-0x8f4200d4, 0x3c010001, 0xa0206d70, 0x24430001,
+0xaf4701b8, 0x3c010001, 0x10000025, 0xa0246cf0,
+0x8f4200d4, 0x3c010001, 0xa0206cf0, 0x24430001,
0x28420033, 0x1440001e, 0xaf4300d4, 0x3c020001,
-0x90426d71, 0xaf4000d4, 0x10000017, 0x38420001,
+0x90426cf1, 0xaf4000d4, 0x10000017, 0x38420001,
0x8f420004, 0x30420001, 0x10400008, 0x0,
-0xc00567e, 0x2021, 0x3c010001, 0xa0206d71,
-0x3c010001, 0x1000000e, 0xa0206d70, 0x8f4200d4,
-0x3c010001, 0xa0206d70, 0x24430001, 0x284201f5,
-0x14400007, 0xaf4300d4, 0x3c020001, 0x90426d71,
-0xaf4000d4, 0x421026, 0x3c010001, 0xa0226d71,
-0x3c030001, 0x8c636e18, 0x24020002, 0x1462000c,
-0x3c030002, 0x3c030001, 0x90636d71, 0x24020001,
-0x5462001f, 0x2021, 0x3c020001, 0x90426d70,
+0xc00565a, 0x2021, 0x3c010001, 0xa0206cf1,
+0x3c010001, 0x1000000e, 0xa0206cf0, 0x8f4200d4,
+0x3c010001, 0xa0206cf0, 0x24430001, 0x284201f5,
+0x14400007, 0xaf4300d4, 0x3c020001, 0x90426cf1,
+0xaf4000d4, 0x421026, 0x3c010001, 0xa0226cf1,
+0x3c030001, 0x8c636d98, 0x24020002, 0x1462000c,
+0x3c030002, 0x3c030001, 0x90636cf1, 0x24020001,
+0x5462001f, 0x2021, 0x3c020001, 0x90426cf0,
0x1443001b, 0x24040005, 0x10000019, 0x24040006,
-0x3c020002, 0x8c429074, 0x431024, 0x1040000b,
-0x24020001, 0x3c030001, 0x90636d71, 0x54620010,
-0x2021, 0x3c020001, 0x90426d70, 0x1443000c,
+0x3c020002, 0x8c428ff4, 0x431024, 0x1040000b,
+0x24020001, 0x3c030001, 0x90636cf1, 0x54620010,
+0x2021, 0x3c020001, 0x90426cf0, 0x1443000c,
0x24040003, 0x1000000a, 0x24040004, 0x3c030001,
-0x90636d71, 0x14620006, 0x2021, 0x3c020001,
-0x90426d70, 0x24040001, 0x50440001, 0x24040002,
-0xc00567e, 0x0, 0x2402ff7f, 0x282a024,
+0x90636cf1, 0x14620006, 0x2021, 0x3c020001,
+0x90426cf0, 0x24040001, 0x50440001, 0x24040002,
+0xc00565a, 0x0, 0x2402ff7f, 0x282a024,
0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
0x27bd0050, 0x3e00008, 0x0, 0x3c020001,
-0x8c426e28, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
+0x8c426da8, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
0x104000de, 0xafb00030, 0x8f4200d0, 0x3c040001,
-0x8c846e18, 0x24430001, 0x2842000b, 0xaf4400e8,
+0x8c846d98, 0x24430001, 0x2842000b, 0xaf4400e8,
0x144000fe, 0xaf4300d0, 0x8f420004, 0x30420002,
0x14400095, 0xaf4000d0, 0x8f420004, 0x34420002,
0xaf420004, 0x24020001, 0x14820003, 0x3c020600,
@@ -5421,7 +5422,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x13c20002, 0xafaa002c, 0x27c30001, 0x8c020228,
0x609021, 0x1642000e, 0x1e38c0, 0x8f42033c,
0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x3c040001, 0x2484619c, 0x3c050009, 0xafa00014,
+0x3c040001, 0x2484610c, 0x3c050009, 0xafa00014,
0xafa20010, 0x8fa60020, 0x1000006d, 0x34a50500,
0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0,
0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8,
@@ -5435,7 +5436,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1440ffe9, 0x0, 0x326200ff, 0x54400017,
0xaf520018, 0x8f420378, 0x24420001, 0xaf420378,
0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248461a8, 0x3c050009,
+0x8f820124, 0x3c040001, 0x24846118, 0x3c050009,
0xafa20014, 0x8d460000, 0x10000035, 0x34a50600,
0x8f420308, 0x24130001, 0x24420001, 0xaf420308,
0x8f420308, 0x1000001e, 0x326200ff, 0x8f830054,
@@ -5448,9 +5449,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2c4203e9, 0x1440ffee, 0x0, 0x326200ff,
0x14400011, 0x0, 0x8f420378, 0x24420001,
0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x248461b0,
+0xafa20010, 0x8f820124, 0x3c040001, 0x24846120,
0x3c050009, 0xafa20014, 0x8d460000, 0x34a50700,
-0xc002b17, 0x3c03821, 0x8f4202ec, 0x24420001,
+0xc002b3b, 0x3c03821, 0x8f4202ec, 0x24420001,
0xaf4202ec, 0x8f4202ec, 0x8f420004, 0x30420001,
0x10400033, 0x3c020400, 0x2c21024, 0x10400017,
0x0, 0x934205c0, 0x8f440250, 0x8f450254,
@@ -5480,7 +5481,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f4300e8, 0x3042007f, 0xa34205c0, 0x24020001,
0x14620005, 0x0, 0x934405c0, 0x42102,
0x10000003, 0x348400f0, 0x934405c0, 0x3484000f,
-0xc005664, 0x0, 0x2402ff7f, 0x282a024,
+0xc005640, 0x0, 0x2402ff7f, 0x282a024,
0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
0x27bd0050, 0x3e00008, 0x0, 0x27bdffb0,
@@ -5533,7 +5534,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafaa002c, 0x27c30001, 0x8c020228, 0x609021,
0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x2484619c, 0x3c050009, 0xafa00014, 0xafa20010,
+0x2484610c, 0x3c050009, 0xafa00014, 0xafa20010,
0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
@@ -5547,7 +5548,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x326200ff, 0x54400017, 0xaf520018,
0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
0x8f820120, 0x8faa002c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x248461a8, 0x3c050009, 0xafa20014,
+0x3c040001, 0x24846118, 0x3c050009, 0xafa20014,
0x8d460000, 0x10000033, 0x34a50600, 0x8f420308,
0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
@@ -5560,13 +5561,13 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x326200ff, 0x54400012, 0x24020001, 0x8f420378,
0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x248461b0, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b17, 0x3c03821, 0x1021,
+0x24846120, 0x3c050009, 0xafa20014, 0x8d460000,
+0x34a50700, 0xc002b3b, 0x3c03821, 0x1021,
0x1440005b, 0x24020001, 0x10000065, 0x0,
0x8f510018, 0x240200ff, 0x12220002, 0x8021,
0x26300001, 0x8c020228, 0x1602000e, 0x1130c0,
0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24846184, 0x3c050009,
+0x8c020228, 0x3c040001, 0x248460f4, 0x3c050009,
0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f,
0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024,
0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
@@ -5575,15 +5576,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
0xa3482b, 0x822021, 0x100f809, 0x892021,
0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x2484618c, 0x3c050009,
+0x8f820124, 0x3c040001, 0x248460fc, 0x3c050009,
0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200,
0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018,
0x8f860120, 0x24020010, 0xafa20010, 0xafb00014,
0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
0x54400011, 0x24020001, 0x8f420340, 0x24420001,
0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846194, 0x3c050009,
-0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b17,
+0x8f820124, 0x3c040001, 0x24846104, 0x3c050009,
+0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b,
0x2203821, 0x1021, 0x1040000d, 0x24020001,
0x8f4202e8, 0xa34005c6, 0xaf4001b0, 0x24420001,
0xaf4202e8, 0x8f4202e8, 0x8ee20150, 0x24420001,
@@ -5603,11 +5604,11 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x14620005, 0x0, 0x8f430130, 0x8f8200b4,
0x10620010, 0x0, 0x8f820104, 0xaf420128,
0x8f8200b4, 0x8f430128, 0xaf420130, 0xafa30010,
-0x8f420130, 0x3c040001, 0x248461d4, 0xafa20014,
+0x8f420130, 0x3c040001, 0x24846144, 0xafa20014,
0x8f86011c, 0x8f8700b0, 0x3c050005, 0x10000031,
0x34a50900, 0x8f420128, 0xafa20010, 0x8f420130,
-0x3c040001, 0x248461e0, 0xafa20014, 0x8f86011c,
-0x8f8700b0, 0x3c050005, 0xc002b17, 0x34a51000,
+0x3c040001, 0x24846150, 0xafa20014, 0x8f86011c,
+0x8f8700b0, 0x3c050005, 0xc002b3b, 0x34a51000,
0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104,
0x8f8200b0, 0x34420001, 0xaf8200b0, 0x24020008,
0xaf830104, 0xafa20010, 0xafa00014, 0x8f42000c,
@@ -5615,9 +5616,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x26e60028, 0x40f809, 0x24070400, 0x8f82011c,
0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc,
0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f420128,
-0xafa20010, 0x8f420130, 0x3c040001, 0x248461ec,
+0xafa20010, 0x8f420130, 0x3c040001, 0x2484615c,
0xafa20014, 0x8f86011c, 0x8f8700b0, 0x3c050005,
-0x34a51100, 0xc002b17, 0x0, 0x8f8200a0,
+0x34a51100, 0xc002b3b, 0x0, 0x8f8200a0,
0x30420004, 0x10400069, 0x0, 0x8f43012c,
0x8f820124, 0x14620005, 0x0, 0x8f430134,
0x8f8200a4, 0x10620006, 0x0, 0x8f820124,
@@ -5630,21 +5631,21 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x8f430134, 0x8f8200a4, 0x10620010,
0x0, 0x8f820124, 0xaf42012c, 0x8f8200a4,
0x8f43012c, 0xaf420134, 0xafa30010, 0x8f420134,
-0x3c040001, 0x248461f8, 0xafa20014, 0x8f86011c,
+0x3c040001, 0x24846168, 0xafa20014, 0x8f86011c,
0x8f8700a0, 0x3c050005, 0x10000032, 0x34a51200,
0x8f42012c, 0xafa20010, 0x8f420134, 0x3c040001,
-0x24846204, 0xafa20014, 0x8f86011c, 0x8f8700a0,
-0x3c050005, 0xc002b17, 0x34a51300, 0x8f82011c,
+0x24846174, 0xafa20014, 0x8f86011c, 0x8f8700a0,
+0x3c050005, 0xc002b3b, 0x34a51300, 0x8f82011c,
0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0,
0x34420001, 0xaf8200a0, 0x24020080, 0xaf830124,
0xafa20010, 0xafa00014, 0x8f420014, 0x8c040208,
0x8c05020c, 0xafa20018, 0x8f420108, 0x3c060001,
-0x24c66f54, 0x40f809, 0x24070004, 0x8f82011c,
+0x24c66ed8, 0x40f809, 0x24070004, 0x8f82011c,
0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201dc,
0x24420001, 0xaee201dc, 0x8ee201dc, 0x8f42012c,
-0xafa20010, 0x8f420134, 0x3c040001, 0x24846210,
+0xafa20010, 0x8f420134, 0x3c040001, 0x24846180,
0xafa20014, 0x8f86011c, 0x8f8700a0, 0x3c050005,
-0x34a51400, 0xc002b17, 0x0, 0x8fbf0020,
+0x34a51400, 0xc002b3b, 0x0, 0x8fbf0020,
0x3e00008, 0x27bd0028, 0x3c081000, 0x24070001,
0x3c060080, 0x3c050100, 0x8f820070, 0x481024,
0x1040fffd, 0x0, 0x8f820054, 0x24420005,
@@ -5712,8 +5713,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf80004c, 0x1000006a, 0xaf800048, 0x30c20001,
0x10400004, 0x24020001, 0xaf820064, 0x10000064,
0x0, 0x30c20002, 0x1440000b, 0x3c050003,
-0x3c040001, 0x248462d4, 0x34a50500, 0x3821,
-0xafa00010, 0xc002b17, 0xafa00014, 0x2402ffc0,
+0x3c040001, 0x24846244, 0x34a50500, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x2402ffc0,
0x10000057, 0xaf820064, 0x8c05022c, 0x8c02010c,
0x10a20048, 0x51080, 0x8c460300, 0x24a20001,
0x3045003f, 0x24020003, 0xac05022c, 0x61e02,
@@ -5732,7 +5733,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
0x8f820060, 0x34420100, 0xaf820060, 0x8f420000,
0x10400003, 0x0, 0x10000006, 0xaf80004c,
-0x10000004, 0xaf800048, 0xc00217e, 0xc02021,
+0x10000004, 0xaf800048, 0xc002196, 0xc02021,
0x402821, 0x8c02010c, 0x14a20002, 0x24020002,
0xaf820064, 0x8f820064, 0x30420002, 0x14400004,
0x0, 0x8c02010c, 0x14a2ffac, 0x0,
@@ -5740,196 +5741,199 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x27bdffa0, 0xafb00040, 0x808021,
0x101602, 0x2442ffff, 0x304300ff, 0x2c620013,
0xafbf0058, 0xafbe0054, 0xafb50050, 0xafb3004c,
-0xafb20048, 0xafb10044, 0x104001ec, 0xafa50034,
-0x31080, 0x3c010001, 0x220821, 0x8c226318,
+0xafb20048, 0xafb10044, 0x104001f3, 0xafa50034,
+0x31080, 0x3c010001, 0x220821, 0x8c226288,
0x400008, 0x0, 0x101302, 0x30440fff,
-0x24020001, 0x10820005, 0x24020002, 0x1082000a,
-0x2402fffe, 0x10000021, 0x3c050003, 0x8f430004,
-0x3c020001, 0x8c426f80, 0xaf440200, 0xaf440204,
-0x10000007, 0x34630001, 0x8f430004, 0xaf440200,
-0xaf440204, 0x621824, 0x3c020001, 0x2442c9c8,
+0x24020001, 0x10820005, 0x24020002, 0x1082000c,
+0x2402fffe, 0x10000024, 0x3c050003, 0x8f430004,
+0x3c020001, 0x8c426f04, 0xaf440200, 0xaf440204,
+0x3c040001, 0x8c846e80, 0x10000009, 0x34630001,
+0x8f430004, 0xaf440200, 0xaf440204, 0x3c040001,
+0x8c846e80, 0x621824, 0x3c020001, 0x2442ca28,
0x21100, 0x21182, 0xaf430004, 0x3c030800,
-0x431025, 0x3c010000, 0xac224138, 0x8f840054,
-0x41442, 0x41c82, 0x431021, 0x41cc2,
-0x431023, 0x41d02, 0x431021, 0x41d42,
-0x431023, 0x10000009, 0xaf420208, 0x3c040001,
-0x248462e0, 0x34a51000, 0x2003021, 0x3821,
-0xafa00010, 0xc002b17, 0xafa00014, 0x8f4202a0,
-0x24420001, 0xaf4202a0, 0x1000021b, 0x8f4202a0,
-0x27b00028, 0x2002021, 0x24050210, 0xc002b9b,
-0x24060008, 0xc0024f4, 0x2002021, 0x10000212,
-0x0, 0x8faa0034, 0x27a40028, 0xa1880,
-0x25420001, 0x3042003f, 0xafa20034, 0x8c650300,
-0x8faa0034, 0x21080, 0x8c430300, 0x25420001,
-0x3042003f, 0xafa20034, 0xac02022c, 0xafa50028,
-0xc0024f4, 0xafa3002c, 0x100001ff, 0x0,
-0x27b00028, 0x2002021, 0x24050210, 0xc002b9b,
-0x24060008, 0xc002633, 0x2002021, 0x100001f6,
-0x0, 0x8faa0034, 0x27a40028, 0xa1880,
-0x25420001, 0x3042003f, 0xafa20034, 0x8c650300,
-0x8faa0034, 0x21080, 0x8c430300, 0x25420001,
-0x3042003f, 0xafa20034, 0xac02022c, 0xafa50028,
-0xc002633, 0xafa3002c, 0x100001e3, 0x0,
-0x101302, 0x30430fff, 0x24020001, 0x10620005,
-0x24020002, 0x1062001e, 0x3c020002, 0x10000033,
-0x3c050003, 0x3c030002, 0x2c31024, 0x54400037,
-0x2c3b025, 0x8f820228, 0x3c010001, 0x370821,
-0xac2238d8, 0x8f82022c, 0x3c010001, 0x370821,
-0xac2238dc, 0x8f820230, 0x3c010001, 0x370821,
-0xac2238e0, 0x8f820234, 0x3c010001, 0x370821,
-0xac2238e4, 0x2402ffff, 0xaf820228, 0xaf82022c,
-0xaf820230, 0xaf820234, 0x10000020, 0x2c3b025,
-0x2c21024, 0x10400012, 0x3c02fffd, 0x3c020001,
-0x571021, 0x8c4238d8, 0xaf820228, 0x3c020001,
-0x571021, 0x8c4238dc, 0xaf82022c, 0x3c020001,
-0x571021, 0x8c4238e0, 0xaf820230, 0x3c020001,
-0x571021, 0x8c4238e4, 0xaf820234, 0x3c02fffd,
-0x3442ffff, 0x10000009, 0x2c2b024, 0x3c040001,
-0x248462ec, 0x34a51100, 0x2003021, 0x3821,
-0xafa00010, 0xc002b17, 0xafa00014, 0x8f4202cc,
-0x24420001, 0xaf4202cc, 0x1000019b, 0x8f4202cc,
-0x101302, 0x30450fff, 0x24020001, 0x10a20005,
-0x24020002, 0x10a2000d, 0x3c0408ff, 0x10000014,
-0x3c050003, 0x3c0208ff, 0x3442ffff, 0x8f830220,
-0x3c040004, 0x2c4b025, 0x621824, 0x34630008,
-0xaf830220, 0x10000012, 0xaf450298, 0x3484fff7,
-0x3c03fffb, 0x8f820220, 0x3463ffff, 0x2c3b024,
-0x441024, 0xaf820220, 0x10000009, 0xaf450298,
-0x3c040001, 0x248462f8, 0x34a51200, 0x2003021,
-0x3821, 0xafa00010, 0xc002b17, 0xafa00014,
-0x8f4202bc, 0x24420001, 0xaf4202bc, 0x10000172,
-0x8f4202bc, 0x27840208, 0x24050200, 0xc002b9b,
-0x24060008, 0x27440224, 0x24050200, 0xc002b9b,
-0x24060008, 0x8f4202c4, 0x24420001, 0xaf4202c4,
-0x10000165, 0x8f4202c4, 0x101302, 0x30430fff,
-0x24020001, 0x10620011, 0x28620002, 0x50400005,
-0x24020002, 0x10600007, 0x0, 0x10000017,
-0x0, 0x1062000f, 0x0, 0x10000013,
-0x0, 0x8c060248, 0x2021, 0xc005134,
-0x24050004, 0x10000007, 0x0, 0x8c060248,
-0x2021, 0xc005134, 0x24050004, 0x10000010,
-0x0, 0x8c06024c, 0x2021, 0xc005134,
-0x24050001, 0x1000000a, 0x0, 0x3c040001,
-0x24846304, 0x3c050003, 0x34a51300, 0x2003021,
-0x3821, 0xafa00010, 0xc002b17, 0xafa00014,
-0x8f4202c0, 0x24420001, 0xaf4202c0, 0x10000136,
-0x8f4202c0, 0xc002407, 0x0, 0x10000132,
-0x0, 0x24020001, 0xa34205c5, 0x24100100,
-0x8f4401a8, 0x8f4501ac, 0xafb00010, 0xafa00014,
-0x8f420014, 0xafa20018, 0x8f420108, 0x26e60028,
-0x40f809, 0x24070400, 0x1040fff5, 0x0,
-0x10000121, 0x0, 0x3c02ffff, 0x34427fff,
-0x2c2b024, 0x1821, 0x3c020900, 0xaf400058,
-0xaf40005c, 0xaf400060, 0xaf400064, 0xaf400360,
-0xafa20020, 0x8f5e0018, 0x27aa0020, 0x240200ff,
-0x13c20002, 0xafaa003c, 0x27c30001, 0x8c020228,
-0x609021, 0x1642000e, 0x1e38c0, 0x8f42033c,
-0x24420001, 0xaf42033c, 0x8f42033c, 0x8c020228,
-0x3c040001, 0x2484629c, 0x3c050009, 0xafa00014,
-0xafa20010, 0x8fa60020, 0x1000006b, 0x34a50500,
-0xf71021, 0x8fa30020, 0x8fa40024, 0xac4304c0,
-0xac4404c4, 0x8f830054, 0x8f820054, 0x247003e8,
-0x2021023, 0x2c4203e9, 0x1040001b, 0x9821,
-0xe08821, 0x263504c0, 0x8f440178, 0x8f45017c,
-0x2201821, 0x240a0004, 0xafaa0010, 0xafb20014,
-0x8f48000c, 0x1021, 0x2f53021, 0xafa80018,
-0x8f48010c, 0x24070008, 0xa32821, 0xa3482b,
-0x822021, 0x100f809, 0x892021, 0x54400006,
-0x24130001, 0x8f820054, 0x2021023, 0x2c4203e9,
-0x1440ffe9, 0x0, 0x326200ff, 0x54400017,
-0xaf520018, 0x8f420378, 0x24420001, 0xaf420378,
-0x8f420378, 0x8f820120, 0x8faa003c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x248462a8, 0x3c050009,
-0xafa20014, 0x8d460000, 0x10000033, 0x34a50600,
-0x8f420308, 0x24130001, 0x24420001, 0xaf420308,
-0x8f420308, 0x1000001c, 0x326200ff, 0x8f830054,
-0x8f820054, 0x247003e8, 0x2021023, 0x2c4203e9,
-0x10400014, 0x9821, 0x24110010, 0x8f42000c,
-0x8f440160, 0x8f450164, 0x8f860120, 0xafb10010,
-0xafb20014, 0xafa20018, 0x8f42010c, 0x24070008,
-0x40f809, 0x24c6001c, 0x1440ffe5, 0x0,
-0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffef,
-0x0, 0x326200ff, 0x14400011, 0x0,
+0x431025, 0xac820038, 0x8f840054, 0x41442,
+0x41c82, 0x431021, 0x41cc2, 0x431023,
+0x41d02, 0x431021, 0x41d42, 0x431023,
+0x10000009, 0xaf420208, 0x3c040001, 0x24846250,
+0x34a51000, 0x2003021, 0x3821, 0xafa00010,
+0xc002b3b, 0xafa00014, 0x8f4202a0, 0x24420001,
+0xaf4202a0, 0x1000021f, 0x8f4202a0, 0x27b00028,
+0x2002021, 0x24050210, 0xc002bbf, 0x24060008,
+0xc002518, 0x2002021, 0x10000216, 0x0,
+0x8faa0034, 0x27a40028, 0xa1880, 0x25420001,
+0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034,
+0x21080, 0x8c430300, 0x25420001, 0x3042003f,
+0xafa20034, 0xac02022c, 0xafa50028, 0xc002518,
+0xafa3002c, 0x10000203, 0x0, 0x27b00028,
+0x2002021, 0x24050210, 0xc002bbf, 0x24060008,
+0xc002657, 0x2002021, 0x100001fa, 0x0,
+0x8faa0034, 0x27a40028, 0xa1880, 0x25420001,
+0x3042003f, 0xafa20034, 0x8c650300, 0x8faa0034,
+0x21080, 0x8c430300, 0x25420001, 0x3042003f,
+0xafa20034, 0xac02022c, 0xafa50028, 0xc002657,
+0xafa3002c, 0x100001e7, 0x0, 0x101302,
+0x30430fff, 0x24020001, 0x10620005, 0x24020002,
+0x1062001e, 0x3c020002, 0x10000033, 0x3c050003,
+0x3c030002, 0x2c31024, 0x54400037, 0x2c3b025,
+0x8f820228, 0x3c010001, 0x370821, 0xac2238d8,
+0x8f82022c, 0x3c010001, 0x370821, 0xac2238dc,
+0x8f820230, 0x3c010001, 0x370821, 0xac2238e0,
+0x8f820234, 0x3c010001, 0x370821, 0xac2238e4,
+0x2402ffff, 0xaf820228, 0xaf82022c, 0xaf820230,
+0xaf820234, 0x10000020, 0x2c3b025, 0x2c21024,
+0x10400012, 0x3c02fffd, 0x3c020001, 0x571021,
+0x8c4238d8, 0xaf820228, 0x3c020001, 0x571021,
+0x8c4238dc, 0xaf82022c, 0x3c020001, 0x571021,
+0x8c4238e0, 0xaf820230, 0x3c020001, 0x571021,
+0x8c4238e4, 0xaf820234, 0x3c02fffd, 0x3442ffff,
+0x10000009, 0x2c2b024, 0x3c040001, 0x2484625c,
+0x34a51100, 0x2003021, 0x3821, 0xafa00010,
+0xc002b3b, 0xafa00014, 0x8f4202cc, 0x24420001,
+0xaf4202cc, 0x1000019f, 0x8f4202cc, 0x101302,
+0x30450fff, 0x24020001, 0x10a20005, 0x24020002,
+0x10a2000d, 0x3c0408ff, 0x10000014, 0x3c050003,
+0x3c0208ff, 0x3442ffff, 0x8f830220, 0x3c040004,
+0x2c4b025, 0x621824, 0x34630008, 0xaf830220,
+0x10000012, 0xaf450298, 0x3484fff7, 0x3c03fffb,
+0x8f820220, 0x3463ffff, 0x2c3b024, 0x441024,
+0xaf820220, 0x10000009, 0xaf450298, 0x3c040001,
+0x24846268, 0x34a51200, 0x2003021, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202bc,
+0x24420001, 0xaf4202bc, 0x10000176, 0x8f4202bc,
+0x27840208, 0x24050200, 0xc002bbf, 0x24060008,
+0x27440224, 0x24050200, 0xc002bbf, 0x24060008,
+0x8f4202c4, 0x24420001, 0xaf4202c4, 0x10000169,
+0x8f4202c4, 0x101302, 0x30430fff, 0x24020001,
+0x10620011, 0x28620002, 0x50400005, 0x24020002,
+0x10600007, 0x0, 0x10000017, 0x0,
+0x1062000f, 0x0, 0x10000013, 0x0,
+0x8c060248, 0x2021, 0xc005104, 0x24050004,
+0x10000007, 0x0, 0x8c060248, 0x2021,
+0xc005104, 0x24050004, 0x10000010, 0x0,
+0x8c06024c, 0x2021, 0xc005104, 0x24050001,
+0x1000000a, 0x0, 0x3c040001, 0x24846274,
+0x3c050003, 0x34a51300, 0x2003021, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x8f4202c0,
+0x24420001, 0xaf4202c0, 0x1000013a, 0x8f4202c0,
+0xc002426, 0x0, 0x10000136, 0x0,
+0x24020001, 0xa34205c5, 0x24100100, 0x8f4401a8,
+0x8f4501ac, 0xafb00010, 0xafa00014, 0x8f420014,
+0xafa20018, 0x8f420108, 0x26e60028, 0x40f809,
+0x24070400, 0x1040fff5, 0x0, 0x10000125,
+0x0, 0x3c03ffff, 0x34637fff, 0x8f420368,
+0x8f440360, 0x2c3b024, 0x1821, 0xaf400058,
+0xaf40005c, 0xaf400060, 0xaf400064, 0x441023,
+0xaf420368, 0x3c020900, 0xaf400360, 0xafa20020,
+0x8f5e0018, 0x27aa0020, 0x240200ff, 0x13c20002,
+0xafaa003c, 0x27c30001, 0x8c020228, 0x609021,
+0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
+0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
+0x2484620c, 0x3c050009, 0xafa00014, 0xafa20010,
+0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
+0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
+0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
+0x2c4203e9, 0x1040001b, 0x9821, 0xe08821,
+0x263504c0, 0x8f440178, 0x8f45017c, 0x2201821,
+0x240a0004, 0xafaa0010, 0xafb20014, 0x8f48000c,
+0x1021, 0x2f53021, 0xafa80018, 0x8f48010c,
+0x24070008, 0xa32821, 0xa3482b, 0x822021,
+0x100f809, 0x892021, 0x54400006, 0x24130001,
+0x8f820054, 0x2021023, 0x2c4203e9, 0x1440ffe9,
+0x0, 0x326200ff, 0x54400017, 0xaf520018,
0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
0x8f820120, 0x8faa003c, 0xafa20010, 0x8f820124,
-0x3c040001, 0x248462b0, 0x3c050009, 0xafa20014,
-0x8d460000, 0x34a50700, 0xc002b17, 0x3c03821,
-0x8f4202b0, 0x24420001, 0xaf4202b0, 0x8f4202b0,
-0x8f4202f8, 0x24420001, 0xaf4202f8, 0x1000008a,
-0x8f4202f8, 0x8c02025c, 0x27440224, 0xaf4201f0,
-0x8c020260, 0x24050200, 0x24060008, 0xc002b9b,
-0xaf4201f8, 0x8f820220, 0x30420008, 0x14400002,
-0x24020001, 0x24020002, 0xaf420298, 0x8f4202ac,
-0x24420001, 0xaf4202ac, 0x10000077, 0x8f4202ac,
-0x3c0200ff, 0x3442ffff, 0x2021824, 0x32c20180,
-0x14400006, 0x3402fffb, 0x43102b, 0x14400003,
-0x0, 0x1000006c, 0xaf4300bc, 0x3c040001,
-0x24846310, 0x3c050003, 0x34a51500, 0x2003021,
-0x3821, 0xafa00010, 0xc002b17, 0xafa00014,
-0x3c020700, 0x34421000, 0x101e02, 0x621825,
-0xafa30020, 0x8f510018, 0x240200ff, 0x12220002,
-0x8021, 0x26300001, 0x8c020228, 0x1602000e,
-0x1130c0, 0x8f42033c, 0x24420001, 0xaf42033c,
-0x8f42033c, 0x8c020228, 0x3c040001, 0x24846284,
-0x3c050009, 0xafa00014, 0xafa20010, 0x8fa60020,
-0x1000003f, 0x34a50100, 0xd71021, 0x8fa30020,
-0x8fa40024, 0xac4304c0, 0xac4404c4, 0xc01821,
-0x8f440178, 0x8f45017c, 0x1021, 0x24070004,
-0xafa70010, 0xafb00014, 0x8f48000c, 0x24c604c0,
-0x2e63021, 0xafa80018, 0x8f48010c, 0x24070008,
-0xa32821, 0xa3482b, 0x822021, 0x100f809,
-0x892021, 0x1440000b, 0x24070008, 0x8f820120,
-0xafa20010, 0x8f820124, 0x3c040001, 0x2484628c,
-0x3c050009, 0xafa20014, 0x8fa60020, 0x1000001c,
-0x34a50200, 0x8f440160, 0x8f450164, 0x8f43000c,
-0xaf500018, 0x8f860120, 0x24020010, 0xafa20010,
-0xafb00014, 0xafa30018, 0x8f42010c, 0x40f809,
-0x24c6001c, 0x14400010, 0x0, 0x8f420340,
-0x24420001, 0xaf420340, 0x8f420340, 0x8f820120,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846294,
-0x3c050009, 0xafa20014, 0x8fa60020, 0x34a50300,
-0xc002b17, 0x2203821, 0x8f4202e0, 0x24420001,
-0xaf4202e0, 0x8f4202e0, 0x8f4202f0, 0x24420001,
-0xaf4202f0, 0x8f4202f0, 0x8fa20034, 0x8fbf0058,
-0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048,
-0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060,
-0x27bdfff8, 0x2408ffff, 0x10a00014, 0x4821,
-0x3c0aedb8, 0x354a8320, 0x90870000, 0x24840001,
-0x3021, 0x1071026, 0x30420001, 0x10400002,
-0x81842, 0x6a1826, 0x604021, 0x24c60001,
-0x2cc20008, 0x1440fff7, 0x73842, 0x25290001,
-0x125102b, 0x1440fff0, 0x0, 0x1001021,
-0x3e00008, 0x27bd0008, 0x27bdffb8, 0xafbf0040,
-0xafbe003c, 0xafb50038, 0xafb30034, 0xafb20030,
-0xafb1002c, 0xafb00028, 0x8f870220, 0xafa7001c,
-0x8f870200, 0xafa70024, 0x8f820220, 0x3c0308ff,
-0x3463ffff, 0x431024, 0x34420004, 0xaf820220,
-0x8f820200, 0x3c03c0ff, 0x3463ffff, 0x431024,
-0x34420004, 0xaf820200, 0x8f53035c, 0x8f550360,
-0x8f5e0364, 0x8f470368, 0xafa70014, 0x8f4202d0,
-0x274401c0, 0x24420001, 0xaf4202d0, 0x8f5002d0,
-0x8f510204, 0x8f520200, 0xc002b84, 0x24050400,
-0xaf53035c, 0xaf550360, 0xaf5e0364, 0x8fa70014,
-0xaf470368, 0xaf5002d0, 0xaf510204, 0xaf520200,
+0x3c040001, 0x24846218, 0x3c050009, 0xafa20014,
+0x8d460000, 0x10000033, 0x34a50600, 0x8f420308,
+0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
+0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
+0x247003e8, 0x2021023, 0x2c4203e9, 0x10400014,
+0x9821, 0x24110010, 0x8f42000c, 0x8f440160,
+0x8f450164, 0x8f860120, 0xafb10010, 0xafb20014,
+0xafa20018, 0x8f42010c, 0x24070008, 0x40f809,
+0x24c6001c, 0x1440ffe5, 0x0, 0x8f820054,
+0x2021023, 0x2c4203e9, 0x1440ffef, 0x0,
+0x326200ff, 0x14400011, 0x0, 0x8f420378,
+0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
+0x8faa003c, 0xafa20010, 0x8f820124, 0x3c040001,
+0x24846220, 0x3c050009, 0xafa20014, 0x8d460000,
+0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b0,
+0x24420001, 0xaf4202b0, 0x8f4202b0, 0x8f4202f8,
+0x24420001, 0xaf4202f8, 0x1000008a, 0x8f4202f8,
0x8c02025c, 0x27440224, 0xaf4201f0, 0x8c020260,
-0x24050200, 0x24060008, 0xaf4201f8, 0x24020006,
-0xc002b9b, 0xaf4201f4, 0x3c023b9a, 0x3442ca00,
-0xaf4201fc, 0x240203e8, 0x24040002, 0x24030001,
-0xaf420294, 0xaf440290, 0xaf43029c, 0x8f820220,
-0x30420008, 0x10400004, 0x0, 0xaf430298,
-0x10000003, 0x3021, 0xaf440298, 0x3021,
-0x3c030001, 0x661821, 0x90636d80, 0x3461021,
-0x24c60001, 0xa043022c, 0x2cc2000f, 0x1440fff8,
-0x3461821, 0x24c60001, 0x8f820040, 0x24040080,
-0x24050080, 0x21702, 0x24420030, 0xa062022c,
-0x3461021, 0xc002b84, 0xa040022c, 0x8fa7001c,
-0x30e20004, 0x14400006, 0x0, 0x8f820220,
-0x3c0308ff, 0x3463fffb, 0x431024, 0xaf820220,
-0x8fa70024, 0x30e20004, 0x14400006, 0x0,
-0x8f820200, 0x3c03c0ff, 0x3463fffb, 0x431024,
-0xaf820200, 0x8fbf0040, 0x8fbe003c, 0x8fb50038,
-0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028,
-0x3e00008, 0x27bd0048, 0x0, 0xaf400104,
+0x24050200, 0x24060008, 0xc002bbf, 0xaf4201f8,
+0x8f820220, 0x30420008, 0x14400002, 0x24020001,
+0x24020002, 0xaf420298, 0x8f4202ac, 0x24420001,
+0xaf4202ac, 0x10000077, 0x8f4202ac, 0x3c0200ff,
+0x3442ffff, 0x2021824, 0x32c20180, 0x14400006,
+0x3402fffb, 0x43102b, 0x14400003, 0x0,
+0x1000006c, 0xaf4300bc, 0x3c040001, 0x24846280,
+0x3c050003, 0x34a51500, 0x2003021, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x3c020700,
+0x34421000, 0x101e02, 0x621825, 0xafa30020,
+0x8f510018, 0x240200ff, 0x12220002, 0x8021,
+0x26300001, 0x8c020228, 0x1602000e, 0x1130c0,
+0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
+0x8c020228, 0x3c040001, 0x248461f4, 0x3c050009,
+0xafa00014, 0xafa20010, 0x8fa60020, 0x1000003f,
+0x34a50100, 0xd71021, 0x8fa30020, 0x8fa40024,
+0xac4304c0, 0xac4404c4, 0xc01821, 0x8f440178,
+0x8f45017c, 0x1021, 0x24070004, 0xafa70010,
+0xafb00014, 0x8f48000c, 0x24c604c0, 0x2e63021,
+0xafa80018, 0x8f48010c, 0x24070008, 0xa32821,
+0xa3482b, 0x822021, 0x100f809, 0x892021,
+0x1440000b, 0x24070008, 0x8f820120, 0xafa20010,
+0x8f820124, 0x3c040001, 0x248461fc, 0x3c050009,
+0xafa20014, 0x8fa60020, 0x1000001c, 0x34a50200,
+0x8f440160, 0x8f450164, 0x8f43000c, 0xaf500018,
+0x8f860120, 0x24020010, 0xafa20010, 0xafb00014,
+0xafa30018, 0x8f42010c, 0x40f809, 0x24c6001c,
+0x14400010, 0x0, 0x8f420340, 0x24420001,
+0xaf420340, 0x8f420340, 0x8f820120, 0xafa20010,
+0x8f820124, 0x3c040001, 0x24846204, 0x3c050009,
+0xafa20014, 0x8fa60020, 0x34a50300, 0xc002b3b,
+0x2203821, 0x8f4202e0, 0x24420001, 0xaf4202e0,
+0x8f4202e0, 0x8f4202f0, 0x24420001, 0xaf4202f0,
+0x8f4202f0, 0x8fa20034, 0x8fbf0058, 0x8fbe0054,
+0x8fb50050, 0x8fb3004c, 0x8fb20048, 0x8fb10044,
+0x8fb00040, 0x3e00008, 0x27bd0060, 0x27bdfff8,
+0x2408ffff, 0x10a00014, 0x4821, 0x3c0aedb8,
+0x354a8320, 0x90870000, 0x24840001, 0x3021,
+0x1071026, 0x30420001, 0x10400002, 0x81842,
+0x6a1826, 0x604021, 0x24c60001, 0x2cc20008,
+0x1440fff7, 0x73842, 0x25290001, 0x125102b,
+0x1440fff0, 0x0, 0x1001021, 0x3e00008,
+0x27bd0008, 0x27bdffb0, 0xafbf0048, 0xafbe0044,
+0xafb50040, 0xafb3003c, 0xafb20038, 0xafb10034,
+0xafb00030, 0x8f870220, 0xafa70024, 0x8f870200,
+0xafa7002c, 0x8f820220, 0x3c0308ff, 0x3463ffff,
+0x431024, 0x34420004, 0xaf820220, 0x8f820200,
+0x3c03c0ff, 0x3463ffff, 0x431024, 0x34420004,
+0xaf820200, 0x8f530358, 0x8f55035c, 0x8f5e0360,
+0x8f470364, 0xafa70014, 0x8f470368, 0xafa7001c,
+0x8f4202d0, 0x274401c0, 0x24420001, 0xaf4202d0,
+0x8f5002d0, 0x8f510204, 0x8f520200, 0xc002ba8,
+0x24050400, 0xaf530358, 0xaf55035c, 0xaf5e0360,
+0x8fa70014, 0xaf470364, 0x8fa7001c, 0xaf470368,
+0xaf5002d0, 0xaf510204, 0xaf520200, 0x8c02025c,
+0x27440224, 0xaf4201f0, 0x8c020260, 0x24050200,
+0x24060008, 0xaf4201f8, 0x24020006, 0xc002bbf,
+0xaf4201f4, 0x3c023b9a, 0x3442ca00, 0xaf4201fc,
+0x240203e8, 0x24040002, 0x24030001, 0xaf420294,
+0xaf440290, 0xaf43029c, 0x8f820220, 0x30420008,
+0x10400004, 0x0, 0xaf430298, 0x10000003,
+0x3021, 0xaf440298, 0x3021, 0x3c030001,
+0x661821, 0x90636d00, 0x3461021, 0x24c60001,
+0xa043022c, 0x2cc2000f, 0x1440fff8, 0x3461821,
+0x24c60001, 0x8f820040, 0x24040080, 0x24050080,
+0x21702, 0x24420030, 0xa062022c, 0x3461021,
+0xc002ba8, 0xa040022c, 0x8fa70024, 0x30e20004,
+0x14400006, 0x0, 0x8f820220, 0x3c0308ff,
+0x3463fffb, 0x431024, 0xaf820220, 0x8fa7002c,
+0x30e20004, 0x14400006, 0x0, 0x8f820200,
+0x3c03c0ff, 0x3463fffb, 0x431024, 0xaf820200,
+0x8fbf0048, 0x8fbe0044, 0x8fb50040, 0x8fb3003c,
+0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008,
+0x27bd0050, 0x0, 0x0, 0xaf400104,
0x24040001, 0x410c0, 0x2e21821, 0x24820001,
0x3c010001, 0x230821, 0xa42234d0, 0x402021,
0x2c820080, 0x1440fff8, 0x410c0, 0x24020001,
@@ -5946,7 +5950,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2c450001, 0xa01021, 0x14400009, 0x24840008,
0x86102b, 0x1440fff0, 0x1021, 0x304200ff,
0x14400030, 0x24020001, 0x1000002e, 0x1021,
-0x1000fffa, 0x24020001, 0x2002021, 0xc0023ed,
+0x1000fffa, 0x24020001, 0x2002021, 0xc00240c,
0x24050006, 0x3042007f, 0x218c0, 0x2e31021,
0x3c010001, 0x220821, 0x942230d0, 0x1040fff2,
0x2e31021, 0x3c060001, 0xc23021, 0x94c630d0,
@@ -5961,7 +5965,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x27bd0018, 0x3e00008, 0x0, 0x27bdffb0,
0x801021, 0xafb00030, 0x24500002, 0x2002021,
0x24050006, 0xafb10034, 0x408821, 0xafbf0048,
-0xafbe0044, 0xafb50040, 0xafb3003c, 0xc0023ed,
+0xafbe0044, 0xafb50040, 0xafb3003c, 0xc00240c,
0xafb20038, 0x3047007f, 0x710c0, 0x2e21021,
0x3c050001, 0xa22821, 0x94a530d0, 0x50a0001c,
0xa03021, 0x3c090001, 0x352934d2, 0x96280002,
@@ -5974,15 +5978,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x10c00014, 0x610c0, 0x571821, 0x3c010001,
0x230821, 0x8c2334d0, 0x571021, 0xafa30010,
0x3c010001, 0x220821, 0x8c2234d4, 0x3c040001,
-0x24846424, 0xafa20014, 0x8e260000, 0x8e270004,
-0x3c050004, 0xc002b17, 0x34a50400, 0x10000063,
+0x24846394, 0xafa20014, 0x8e260000, 0x8e270004,
+0x3c050004, 0xc002b3b, 0x34a50400, 0x10000063,
0x3c020800, 0x8f450100, 0x10a00006, 0x510c0,
0x2e21021, 0x3c010001, 0x220821, 0x942234d0,
0xaf420100, 0xa03021, 0x14c00011, 0x628c0,
0x710c0, 0x2e21021, 0xafa70010, 0x3c010001,
-0x220821, 0x942230d0, 0x3c040001, 0x24846430,
+0x220821, 0x942230d0, 0x3c040001, 0x248463a0,
0xafa20014, 0x8e260000, 0x8e270004, 0x3c050004,
-0xc002b17, 0x34a50500, 0x10000048, 0x3c020800,
+0xc002b3b, 0x34a50500, 0x10000048, 0x3c020800,
0xb71821, 0x3c020001, 0x96040000, 0x344234d2,
0x621821, 0xa4640000, 0x8e020002, 0x720c0,
0xac620002, 0x2e41021, 0x3c030001, 0x621821,
@@ -6005,7 +6009,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x240200ff, 0x13c20002, 0xafaa002c, 0x27c30001,
0x8c020228, 0x609021, 0x1642000e, 0x1e38c0,
0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x248463ec, 0x3c050009,
+0x8c020228, 0x3c040001, 0x2484635c, 0x3c050009,
0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006b,
0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024,
0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
@@ -6019,7 +6023,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff,
0x54400017, 0xaf520018, 0x8f420378, 0x24420001,
0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x248463f8,
+0xafa20010, 0x8f820124, 0x3c040001, 0x24846368,
0x3c050009, 0xafa20014, 0x8d460000, 0x10000033,
0x34a50600, 0x8f420308, 0x24130001, 0x24420001,
0xaf420308, 0x8f420308, 0x1000001c, 0x326200ff,
@@ -6032,8 +6036,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1440ffef, 0x0, 0x326200ff, 0x14400011,
0x0, 0x8f420378, 0x24420001, 0xaf420378,
0x8f420378, 0x8f820120, 0x8faa002c, 0xafa20010,
-0x8f820124, 0x3c040001, 0x24846400, 0x3c050009,
-0xafa20014, 0x8d460000, 0x34a50700, 0xc002b17,
+0x8f820124, 0x3c040001, 0x24846370, 0x3c050009,
+0xafa20014, 0x8d460000, 0x34a50700, 0xc002b3b,
0x3c03821, 0x8f4202b4, 0x24420001, 0xaf4202b4,
0x8f4202b4, 0x8f4202f4, 0x24420001, 0xaf4202f4,
0x8f4202f4, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
@@ -6041,7 +6045,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x3e00008, 0x27bd0050, 0x27bdffa0, 0x801021,
0xafb00040, 0x24500002, 0x2002021, 0x24050006,
0xafb10044, 0x408821, 0xafbf0058, 0xafbe0054,
-0xafb50050, 0xafb3004c, 0xc0023ed, 0xafb20048,
+0xafb50050, 0xafb3004c, 0xc00240c, 0xafb20048,
0x3048007f, 0x810c0, 0x2e21021, 0x3c060001,
0xc23021, 0x94c630d0, 0x10c0001c, 0x3821,
0x3c0a0001, 0x354a34d2, 0x96290002, 0x610c0,
@@ -6053,8 +6057,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x94c634d0, 0x14c0ffea, 0x610c0, 0x14c00011,
0xafa70028, 0x810c0, 0x2e21021, 0xafa80010,
0x3c010001, 0x220821, 0x942230d0, 0x3c040001,
-0x2484643c, 0xafa20014, 0x8e260000, 0x8e270004,
-0x3c050004, 0xc002b17, 0x34a50900, 0x10000075,
+0x248463ac, 0xafa20014, 0x8e260000, 0x8e270004,
+0x3c050004, 0xc002b3b, 0x34a50900, 0x10000075,
0x3c020800, 0x10e0000c, 0x610c0, 0x2e21021,
0x3c030001, 0x621821, 0x946334d0, 0x710c0,
0x2e21021, 0x3c010001, 0x220821, 0xa42334d0,
@@ -6089,7 +6093,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafab0034, 0x27c30001, 0x8c020228, 0x609021,
0x1642000e, 0x1e38c0, 0x8f42033c, 0x24420001,
0xaf42033c, 0x8f42033c, 0x8c020228, 0x3c040001,
-0x248463ec, 0x3c050009, 0xafa00014, 0xafa20010,
+0x2484635c, 0x3c050009, 0xafa00014, 0xafa20010,
0x8fa60020, 0x1000006b, 0x34a50500, 0xf71021,
0x8fa30020, 0x8fa40024, 0xac4304c0, 0xac4404c4,
0x8f830054, 0x8f820054, 0x247003e8, 0x2021023,
@@ -6103,7 +6107,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x0, 0x326200ff, 0x54400017, 0xaf520018,
0x8f420378, 0x24420001, 0xaf420378, 0x8f420378,
0x8f820120, 0x8fab0034, 0xafa20010, 0x8f820124,
-0x3c040001, 0x248463f8, 0x3c050009, 0xafa20014,
+0x3c040001, 0x24846368, 0x3c050009, 0xafa20014,
0x8d660000, 0x10000033, 0x34a50600, 0x8f420308,
0x24130001, 0x24420001, 0xaf420308, 0x8f420308,
0x1000001c, 0x326200ff, 0x8f830054, 0x8f820054,
@@ -6116,14 +6120,14 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x326200ff, 0x14400011, 0x0, 0x8f420378,
0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
0x8fab0034, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846400, 0x3c050009, 0xafa20014, 0x8d660000,
-0x34a50700, 0xc002b17, 0x3c03821, 0x8f4202b8,
+0x24846370, 0x3c050009, 0xafa20014, 0x8d660000,
+0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202b8,
0x24420001, 0xaf4202b8, 0x8f4202b8, 0x8f4202f4,
0x24420001, 0xaf4202f4, 0x8f4202f4, 0x8fbf0058,
0x8fbe0054, 0x8fb50050, 0x8fb3004c, 0x8fb20048,
0x8fb10044, 0x8fb00040, 0x3e00008, 0x27bd0060,
0x0, 0x0, 0x0, 0x27bdffe0,
-0x27644000, 0xafbf0018, 0xc002b84, 0x24051000,
+0x27644000, 0xafbf0018, 0xc002ba8, 0x24051000,
0x3c030001, 0x34632cc0, 0x3c040001, 0x34842ec8,
0x24020020, 0xaf82011c, 0x2e31021, 0xaf800100,
0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114,
@@ -6132,15 +6136,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2e31021, 0xaf4200f0, 0x2e41021, 0xaf4200f4,
0x2e41021, 0xaf4200f8, 0x3c020001, 0x571021,
0x904240f4, 0x1440001c, 0x3c050001, 0x8f82011c,
-0x3c040001, 0x24846500, 0x3c050001, 0x34420001,
+0x3c040001, 0x24846470, 0x3c050001, 0x34420001,
0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c,
-0x34a50100, 0xc002b17, 0x3821, 0x8c020218,
+0x34a50100, 0xc002b3b, 0x3821, 0x8c020218,
0x30420040, 0x10400014, 0x0, 0x8f82011c,
-0x3c040001, 0x2484650c, 0x3c050001, 0x34420004,
+0x3c040001, 0x2484647c, 0x3c050001, 0x34420004,
0xaf82011c, 0xafa00010, 0xafa00014, 0x8f86011c,
-0x10000007, 0x34a50200, 0x3c040001, 0x24846514,
+0x10000007, 0x34a50200, 0x3c040001, 0x24846484,
0xafa00010, 0xafa00014, 0x8f86011c, 0x34a50300,
-0xc002b17, 0x3821, 0x8fbf0018, 0x3e00008,
+0xc002b3b, 0x3821, 0x8fbf0018, 0x3e00008,
0x27bd0020, 0x8fa90010, 0x8f83012c, 0x8faa0014,
0x8fab0018, 0x1060000a, 0x27624fe0, 0x14620002,
0x24680020, 0x27684800, 0x8f820128, 0x11020004,
@@ -6181,55 +6185,55 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2e21021, 0x402021, 0x24020001, 0xaf4400ec,
0xac890000, 0xac820004, 0x24020001, 0x3e00008,
0x0, 0x3e00008, 0x0, 0x27bdffd8,
-0x3c040001, 0x2484651c, 0x3c050001, 0xafbf0024,
+0x3c040001, 0x2484648c, 0x3c050001, 0xafbf0024,
0xafb20020, 0xafb1001c, 0xafb00018, 0x8f900104,
0x8f9100b0, 0x8f92011c, 0x34a52500, 0x8f820100,
-0x2403021, 0x2203821, 0xafa20010, 0xc002b17,
+0x2403021, 0x2203821, 0xafa20010, 0xc002b3b,
0xafb00014, 0x8e020008, 0xafa20010, 0x8e02000c,
-0x3c040001, 0x24846528, 0xafa20014, 0x8e060000,
-0x8e070004, 0x3c050001, 0xc002b17, 0x34a52510,
+0x3c040001, 0x24846498, 0xafa20014, 0x8e060000,
+0x8e070004, 0x3c050001, 0xc002b3b, 0x34a52510,
0x8e020018, 0xafa20010, 0x8e02001c, 0x3c040001,
-0x24846534, 0xafa20014, 0x8e060010, 0x8e070014,
-0x3c050001, 0xc002b17, 0x34a52520, 0x3c027f00,
+0x248464a4, 0xafa20014, 0x8e060010, 0x8e070014,
+0x3c050001, 0xc002b3b, 0x34a52520, 0x3c027f00,
0x2221024, 0x3c030800, 0x54430016, 0x3c030200,
0x8f82009c, 0x3042ffff, 0x14400012, 0x3c030200,
-0x3c040001, 0x24846540, 0x3c050002, 0x34a5f030,
+0x3c040001, 0x248464b0, 0x3c050002, 0x34a5f030,
0x3021, 0x3821, 0x36420002, 0xaf82011c,
0x36220001, 0xaf8200b0, 0xaf900104, 0xaf92011c,
-0xafa00010, 0xc002b17, 0xafa00014, 0x10000024,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x10000024,
0x0, 0x2c31024, 0x1040000d, 0x2231024,
0x1040000b, 0x36420002, 0xaf82011c, 0x36220001,
0xaf8200b0, 0xaf900104, 0xaf92011c, 0x8f420330,
0x24420001, 0xaf420330, 0x10000015, 0x8f420330,
-0x3c040001, 0x24846548, 0x240202a9, 0xafa20010,
-0xafa00014, 0x8f860144, 0x3c070001, 0x24e76550,
-0xc002b17, 0x3405dead, 0x8f82011c, 0x34420002,
+0x3c040001, 0x248464b8, 0x240202a9, 0xafa20010,
+0xafa00014, 0x8f860144, 0x3c070001, 0x24e764c0,
+0xc002b3b, 0x3405dead, 0x8f82011c, 0x34420002,
0xaf82011c, 0x8f820220, 0x34420004, 0xaf820220,
0x8f820140, 0x3c030001, 0x431025, 0xaf820140,
0x8fbf0024, 0x8fb20020, 0x8fb1001c, 0x8fb00018,
0x3e00008, 0x27bd0028, 0x27bdffd8, 0x3c040001,
-0x24846578, 0x3c050001, 0xafbf0024, 0xafb20020,
+0x248464e8, 0x3c050001, 0xafbf0024, 0xafb20020,
0xafb1001c, 0xafb00018, 0x8f900124, 0x8f9100a0,
0x8f92011c, 0x34a52600, 0x8f820120, 0x2403021,
-0x2203821, 0xafa20010, 0xc002b17, 0xafb00014,
+0x2203821, 0xafa20010, 0xc002b3b, 0xafb00014,
0x8e020008, 0xafa20010, 0x8e02000c, 0x3c040001,
-0x24846584, 0xafa20014, 0x8e060000, 0x8e070004,
-0x3c050001, 0xc002b17, 0x34a52610, 0x8e020018,
-0xafa20010, 0x8e02001c, 0x3c040001, 0x24846590,
+0x248464f4, 0xafa20014, 0x8e060000, 0x8e070004,
+0x3c050001, 0xc002b3b, 0x34a52610, 0x8e020018,
+0xafa20010, 0x8e02001c, 0x3c040001, 0x24846500,
0xafa20014, 0x8e060010, 0x8e070014, 0x3c050001,
-0xc002b17, 0x34a52620, 0x3c027f00, 0x2221024,
+0xc002b3b, 0x34a52620, 0x3c027f00, 0x2221024,
0x3c030800, 0x54430016, 0x3c030200, 0x8f8200ac,
0x3042ffff, 0x14400012, 0x3c030200, 0x3c040001,
-0x2484659c, 0x3c050001, 0x34a5f030, 0x3021,
+0x2484650c, 0x3c050001, 0x34a5f030, 0x3021,
0x3821, 0x36420002, 0xaf82011c, 0x36220001,
0xaf8200a0, 0xaf900124, 0xaf92011c, 0xafa00010,
-0xc002b17, 0xafa00014, 0x10000024, 0x0,
+0xc002b3b, 0xafa00014, 0x10000024, 0x0,
0x2c31024, 0x1040000d, 0x2231024, 0x1040000b,
0x36420002, 0xaf82011c, 0x36220001, 0xaf8200a0,
0xaf900124, 0xaf92011c, 0x8f42032c, 0x24420001,
0xaf42032c, 0x10000015, 0x8f42032c, 0x3c040001,
-0x24846548, 0x240202e2, 0xafa20010, 0xafa00014,
-0x8f860144, 0x3c070001, 0x24e76550, 0xc002b17,
+0x248464b8, 0x240202e2, 0xafa20010, 0xafa00014,
+0x8f860144, 0x3c070001, 0x24e764c0, 0xc002b3b,
0x3405dead, 0x8f82011c, 0x34420002, 0xaf82011c,
0x8f820220, 0x34420004, 0xaf820220, 0x8f820140,
0x3c030001, 0x431025, 0xaf820140, 0x8fbf0024,
@@ -6238,24 +6242,24 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2821, 0x6821, 0x4821, 0x7821,
0x7021, 0x8f880124, 0x8f870104, 0x1580002e,
0x8f8b011c, 0x11a00014, 0x31620800, 0x8f820120,
-0x10460029, 0x0, 0x3c040001, 0x8c846f60,
+0x10460029, 0x0, 0x3c040001, 0x8c846ee4,
0x8cc20000, 0x8cc30004, 0xac820000, 0xac830004,
0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e,
0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014,
0x10000012, 0x24c60020, 0x10400017, 0x0,
-0x3c040001, 0x8c846f60, 0x8d020000, 0x8d030004,
+0x3c040001, 0x8c846ee4, 0x8d020000, 0x8d030004,
0xac820000, 0xac830004, 0x8d020008, 0xac820008,
0x9502000e, 0xa482000e, 0x8d020010, 0x25060020,
0xac820010, 0x8d020014, 0x240c0001, 0xc01821,
0xac820014, 0x27624fe0, 0x43102b, 0x54400001,
0x27634800, 0x603021, 0x1540002f, 0x31620100,
0x11200014, 0x31628000, 0x8f820100, 0x1045002a,
-0x31620100, 0x3c040001, 0x8c846f5c, 0x8ca20000,
+0x31620100, 0x3c040001, 0x8c846ee0, 0x8ca20000,
0x8ca30004, 0xac820000, 0xac830004, 0x8ca20008,
0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010,
0x240a0001, 0xac820010, 0x8ca20014, 0x10000012,
0x24a50020, 0x10400018, 0x31620100, 0x3c040001,
-0x8c846f5c, 0x8ce20000, 0x8ce30004, 0xac820000,
+0x8c846ee0, 0x8ce20000, 0x8ce30004, 0xac820000,
0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e,
0xa482000e, 0x8ce20010, 0x24e50020, 0xac820010,
0x8ce20014, 0x240a0001, 0xa01821, 0xac820014,
@@ -6264,7 +6268,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x11a00009, 0x31a20800, 0x10400004, 0x25020020,
0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124,
0x8f880124, 0x6821, 0x11800011, 0x31621000,
-0x3c040001, 0x8c846f60, 0x8c820000, 0x8c830004,
+0x3c040001, 0x8c846ee4, 0x8c820000, 0x8c830004,
0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4,
0x9482000e, 0xaf8200ac, 0x8c820010, 0x6021,
0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31621000,
@@ -6273,7 +6277,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x3c020002, 0x1221024, 0x10400004, 0x24e20020,
0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104,
0x8f870104, 0x4821, 0x1140ff70, 0x0,
-0x3c040001, 0x8c846f5c, 0x8c820000, 0x8c830004,
+0x3c040001, 0x8c846ee0, 0x8c820000, 0x8c830004,
0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4,
0x9482000e, 0xaf82009c, 0x8c820010, 0x5021,
0xaf8200b0, 0x8c890010, 0x1000ff60, 0x8c8e0014,
@@ -6282,11 +6286,11 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x7821, 0x7021, 0x8f880124, 0x8f870104,
0x3c180100, 0x1580002e, 0x8f89011c, 0x11a00014,
0x31220800, 0x8f820120, 0x10460029, 0x0,
-0x3c040001, 0x8c846f60, 0x8cc20000, 0x8cc30004,
+0x3c040001, 0x8c846ee4, 0x8cc20000, 0x8cc30004,
0xac820000, 0xac830004, 0x8cc20008, 0xac820008,
0x94c2000e, 0xa482000e, 0x8cc20010, 0x240c0001,
0xac820010, 0x8cc20014, 0x10000012, 0x24c60020,
-0x10400017, 0x0, 0x3c040001, 0x8c846f60,
+0x10400017, 0x0, 0x3c040001, 0x8c846ee4,
0x8d020000, 0x8d030004, 0xac820000, 0xac830004,
0x8d020008, 0xac820008, 0x9502000e, 0xa482000e,
0x8d020010, 0x25060020, 0xac820010, 0x8d020014,
@@ -6294,11 +6298,11 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x43102b, 0x54400001, 0x27634800, 0x603021,
0x1560002f, 0x31220100, 0x11400014, 0x31228000,
0x8f820100, 0x1045002a, 0x31220100, 0x3c040001,
-0x8c846f5c, 0x8ca20000, 0x8ca30004, 0xac820000,
+0x8c846ee0, 0x8ca20000, 0x8ca30004, 0xac820000,
0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e,
0xa482000e, 0x8ca20010, 0x240b0001, 0xac820010,
0x8ca20014, 0x10000012, 0x24a50020, 0x10400018,
-0x31220100, 0x3c040001, 0x8c846f5c, 0x8ce20000,
+0x31220100, 0x3c040001, 0x8c846ee0, 0x8ce20000,
0x8ce30004, 0xac820000, 0xac830004, 0x8ce20008,
0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010,
0x24e50020, 0xac820010, 0x8ce20014, 0x240b0001,
@@ -6307,7 +6311,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x5440001d, 0x31221000, 0x11a00009, 0x31a20800,
0x10400004, 0x25020020, 0x8f8200a8, 0xa5e20000,
0x25020020, 0xaf820124, 0x8f880124, 0x6821,
-0x11800011, 0x31221000, 0x3c040001, 0x8c846f60,
+0x11800011, 0x31221000, 0x3c040001, 0x8c846ee4,
0x8c820000, 0x8c830004, 0xaf820080, 0xaf830084,
0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac,
0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010,
@@ -6316,7 +6320,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1421024,
0x10400004, 0x24e20020, 0x8f8200b4, 0xaf8200d4,
0x24e20020, 0xaf820104, 0x8f870104, 0x5021,
-0x11600010, 0x0, 0x3c040001, 0x8c846f5c,
+0x11600010, 0x0, 0x3c040001, 0x8c846ee0,
0x8c820000, 0x8c830004, 0xaf820090, 0xaf830094,
0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c,
0x8c820010, 0x5821, 0xaf8200b0, 0x8c8a0010,
@@ -6345,37 +6349,37 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f420000, 0x10400003, 0x0, 0x1000ff05,
0xaf80004c, 0x1000ff03, 0xaf800048, 0x3e00008,
0x0, 0x0, 0x0, 0x3c020001,
-0x8c426da8, 0x27bdffe8, 0xafbf0014, 0x14400012,
-0xafb00010, 0x3c100001, 0x26107010, 0x2002021,
-0xc002b84, 0x24052000, 0x26021fe0, 0x3c010001,
-0xac226f68, 0x3c010001, 0xac226f64, 0xac020250,
+0x8c426d28, 0x27bdffe8, 0xafbf0014, 0x14400012,
+0xafb00010, 0x3c100001, 0x26106f90, 0x2002021,
+0xc002ba8, 0x24052000, 0x26021fe0, 0x3c010001,
+0xac226eec, 0x3c010001, 0xac226ee8, 0xac020250,
0x24022000, 0xac100254, 0xac020258, 0x24020001,
-0x3c010001, 0xac226da8, 0x8fbf0014, 0x8fb00010,
-0x3e00008, 0x27bd0018, 0x3c090001, 0x8d296f68,
+0x3c010001, 0xac226d28, 0x8fbf0014, 0x8fb00010,
+0x3e00008, 0x27bd0018, 0x3c090001, 0x8d296eec,
0x8c820000, 0x8fa30010, 0x8fa80014, 0xad220000,
0x8c820004, 0xad250008, 0xad220004, 0x8f820054,
0xad260010, 0xad270014, 0xad230018, 0xad28001c,
-0xad22000c, 0x2529ffe0, 0x3c020001, 0x24427010,
+0xad22000c, 0x2529ffe0, 0x3c020001, 0x24426f90,
0x122102b, 0x10400003, 0x0, 0x3c090001,
-0x8d296f64, 0x3c020001, 0x8c426d90, 0xad220000,
-0x3c020001, 0x8c426d90, 0x3c010001, 0xac296f68,
+0x8d296ee8, 0x3c020001, 0x8c426d10, 0xad220000,
+0x3c020001, 0x8c426d10, 0x3c010001, 0xac296eec,
0xad220004, 0xac090250, 0x3e00008, 0x0,
-0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e106f68,
-0x3c020001, 0x8c426d90, 0xafb10014, 0x808821,
+0x27bdffd0, 0xafb00010, 0x3c100001, 0x8e106eec,
+0x3c020001, 0x8c426d10, 0xafb10014, 0x808821,
0xafbe0024, 0x8fbe0040, 0x8fa40048, 0xafb20018,
0xa09021, 0xafbf0028, 0xafb50020, 0xafb3001c,
-0xae020000, 0x3c020001, 0x8c426d90, 0xc09821,
+0xae020000, 0x3c020001, 0x8c426d10, 0xc09821,
0xe0a821, 0x10800006, 0xae020004, 0x26050008,
-0xc002b8f, 0x24060018, 0x10000005, 0x2610ffe0,
-0x26040008, 0xc002b84, 0x24050018, 0x2610ffe0,
-0x3c030001, 0x24637010, 0x203102b, 0x10400003,
-0x0, 0x3c100001, 0x8e106f64, 0x8e220000,
+0xc002bb3, 0x24060018, 0x10000005, 0x2610ffe0,
+0x26040008, 0xc002ba8, 0x24050018, 0x2610ffe0,
+0x3c030001, 0x24636f90, 0x203102b, 0x10400003,
+0x0, 0x3c100001, 0x8e106ee8, 0x8e220000,
0xae020000, 0x8e220004, 0xae120008, 0xae020004,
0x8f820054, 0xae130010, 0xae150014, 0xae1e0018,
0x8fa80044, 0xae08001c, 0xae02000c, 0x2610ffe0,
0x203102b, 0x10400003, 0x0, 0x3c100001,
-0x8e106f64, 0x3c020001, 0x8c426d90, 0xae020000,
-0x3c020001, 0x8c426d90, 0x3c010001, 0xac306f68,
+0x8e106ee8, 0x3c020001, 0x8c426d10, 0xae020000,
+0x3c020001, 0x8c426d10, 0x3c010001, 0xac306eec,
0xae020004, 0xac100250, 0x8fbf0028, 0x8fbe0024,
0x8fb50020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
0x8fb00010, 0x3e00008, 0x27bd0030, 0x851821,
@@ -6390,28 +6394,36 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x3e00008, 0x0, 0x63080, 0x861821,
0x83102b, 0x10400006, 0x0, 0xac850000,
0x24840004, 0x83102b, 0x5440fffd, 0xac850000,
-0x3e00008, 0x0, 0x0, 0x3c0208ff,
-0x3442ffff, 0x3c03c0ff, 0x8f850220, 0x3463ffff,
-0x8f860200, 0xa21024, 0x34420004, 0xc31824,
-0x34630004, 0xaf820220, 0xaf830200, 0x8c820214,
-0xac020084, 0x8c820218, 0xac020088, 0x8c82021c,
-0xac02008c, 0x8c820220, 0xac020090, 0x8c820224,
-0xac020094, 0x8c820228, 0xac020098, 0x8c82022c,
-0xac02009c, 0x8c820230, 0xac0200a0, 0x8c820234,
-0xac0200a4, 0x8c820238, 0xac0200a8, 0x8c82023c,
-0xac0200ac, 0x8c820240, 0xac0200b0, 0x8c820244,
-0xac0200b4, 0x8c820248, 0xac0200b8, 0x8c82024c,
-0xac0200bc, 0x8c82001c, 0xac020080, 0x8c820018,
-0xac0200c0, 0x8c820020, 0xac0200cc, 0x8c820024,
-0xac0200d0, 0x8c8201d0, 0xac0200e0, 0x8c8201d4,
-0xac0200e4, 0x8c8201d8, 0xac0200e8, 0x8c8201dc,
-0xac0200ec, 0x8c8201e0, 0xac0200f0, 0x8c820098,
-0x8c83009c, 0xac0300fc, 0x8c8200a8, 0x8c8300ac,
-0xac0300f4, 0x8c8200a0, 0x8c8300a4, 0x30a50004,
-0xac0300f8, 0x14a00007, 0x30c20004, 0x8f820220,
-0x3c0308ff, 0x3463fffb, 0x431024, 0xaf820220,
-0x30c20004, 0x14400006, 0x0, 0x8f820200,
-0x3c03c0ff, 0x3463fffb, 0x431024, 0xaf820200,
+0x3e00008, 0x0, 0x0, 0x26e50028,
+0xa03021, 0x274301c0, 0x8f4d0358, 0x8f47035c,
+0x8f480360, 0x8f490364, 0x8f4a0368, 0x8f4b0204,
+0x8f4c0200, 0x24640400, 0x64102b, 0x10400008,
+0x3c0208ff, 0x8cc20000, 0xac620000, 0x24630004,
+0x64102b, 0x1440fffb, 0x24c60004, 0x3c0208ff,
+0x3442ffff, 0x3c03c0ff, 0xaf4d0358, 0xaf47035c,
+0xaf480360, 0xaf490364, 0xaf4a0368, 0xaf4b0204,
+0xaf4c0200, 0x8f840220, 0x3463ffff, 0x8f860200,
+0x821024, 0x34420004, 0xc31824, 0x34630004,
+0xaf820220, 0xaf830200, 0x8ca20214, 0xac020084,
+0x8ca20218, 0xac020088, 0x8ca2021c, 0xac02008c,
+0x8ca20220, 0xac020090, 0x8ca20224, 0xac020094,
+0x8ca20228, 0xac020098, 0x8ca2022c, 0xac02009c,
+0x8ca20230, 0xac0200a0, 0x8ca20234, 0xac0200a4,
+0x8ca20238, 0xac0200a8, 0x8ca2023c, 0xac0200ac,
+0x8ca20240, 0xac0200b0, 0x8ca20244, 0xac0200b4,
+0x8ca20248, 0xac0200b8, 0x8ca2024c, 0xac0200bc,
+0x8ca2001c, 0xac020080, 0x8ca20018, 0xac0200c0,
+0x8ca20020, 0xac0200cc, 0x8ca20024, 0xac0200d0,
+0x8ca201d0, 0xac0200e0, 0x8ca201d4, 0xac0200e4,
+0x8ca201d8, 0xac0200e8, 0x8ca201dc, 0xac0200ec,
+0x8ca201e0, 0xac0200f0, 0x8ca20098, 0x8ca3009c,
+0xac0300fc, 0x8ca200a8, 0x8ca300ac, 0xac0300f4,
+0x8ca200a0, 0x8ca300a4, 0x30840004, 0xac0300f8,
+0x14800007, 0x30c20004, 0x8f820220, 0x3c0308ff,
+0x3463fffb, 0x431024, 0xaf820220, 0x30c20004,
+0x14400006, 0x0, 0x8f820200, 0x3c03c0ff,
+0x3463fffb, 0x431024, 0xaf820200, 0x8f4202dc,
+0xa34005c5, 0x24420001, 0xaf4202dc, 0x8f4202dc,
0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
0xafb00020, 0x8f430024, 0x8f420020, 0x10620038,
0x0, 0x8f430020, 0x8f420024, 0x622023,
@@ -6443,7 +6455,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8e040000, 0x8e050004, 0x96120008, 0x8f420090,
0x9611000a, 0x3246ffff, 0x46102a, 0x10400017,
0x0, 0x8f8200d8, 0x8f430098, 0x431023,
-0x2442fff8, 0xaf420090, 0x8f420090, 0x2842fff9,
+0x2442dcbe, 0xaf420090, 0x8f420090, 0x2842dcbf,
0x10400005, 0x0, 0x8f420090, 0x8f430144,
0x431021, 0xaf420090, 0x8f420090, 0x46102a,
0x10400006, 0x0, 0x8f420348, 0x24420001,
@@ -6513,7 +6525,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8e040000, 0x8e050004, 0x96110008, 0x8f420090,
0x9607000a, 0x3226ffff, 0x46102a, 0x10400017,
0x0, 0x8f8200d8, 0x8f430098, 0x431023,
-0x2442ff80, 0xaf420090, 0x8f420090, 0x2842ff81,
+0x2442dc46, 0xaf420090, 0x8f420090, 0x2842dc47,
0x10400005, 0x0, 0x8f420090, 0x8f430144,
0x431021, 0xaf420090, 0x8f420090, 0x46102a,
0x10400006, 0x0, 0x8f420348, 0x24420001,
@@ -6575,15 +6587,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x30a20001, 0x8c82001c, 0x8f430040, 0x8f440034,
0x24420001, 0x2463ffff, 0x431024, 0x862021,
0xaf42002c, 0x30a20030, 0x14400006, 0xaf440034,
-0x8f420034, 0x8c03023c, 0x43102b, 0x144000ca,
+0x8f420034, 0x8c03023c, 0x43102b, 0x144000b4,
0x0, 0x32c20010, 0x10400028, 0x24070008,
0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c,
0x8f860120, 0x24020080, 0xafa20010, 0xafa30014,
0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
0x14400011, 0x24020001, 0x3c010001, 0x370821,
0xa02240f1, 0x8f820124, 0xafa20010, 0x8f820128,
-0x3c040001, 0x24846854, 0xafa20014, 0x8f46002c,
-0x8f870120, 0x3c050009, 0xc002b17, 0x34a51100,
+0x3c040001, 0x248467c4, 0xafa20014, 0x8f46002c,
+0x8f870120, 0x3c050009, 0xc002b3b, 0x34a51100,
0x10000036, 0x0, 0x8f420300, 0x8f43002c,
0x24420001, 0xaf420300, 0x8f420300, 0x24020001,
0xa34205c1, 0x10000026, 0xaf430038, 0x8f440170,
@@ -6592,13 +6604,13 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
0x24020001, 0x3c010001, 0x370821, 0xa02240f0,
0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x24846848, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b17, 0x34a50900, 0x1000000f,
+0x248467b8, 0xafa20014, 0x8f46002c, 0x8f870120,
+0x3c050009, 0xc002b3b, 0x34a50900, 0x1000000f,
0x0, 0x8f420300, 0x24420001, 0xaf420300,
0x8f420300, 0x8f42002c, 0xa34005c1, 0xaf420038,
0x3c010001, 0x370821, 0xa02040f1, 0x3c010001,
0x370821, 0xa02040f0, 0xaf400034, 0x8f420314,
-0x24420001, 0xaf420314, 0x1000006f, 0x8f420314,
+0x24420001, 0xaf420314, 0x10000059, 0x8f420314,
0x10400022, 0x30a27000, 0x8c85001c, 0x8f420028,
0xa22023, 0x4810003, 0x0, 0x8f420040,
0x822021, 0x8f420358, 0x8f430000, 0xaf450028,
@@ -6606,8 +6618,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
0x0, 0x8f820060, 0x34420008, 0xaf820060,
-0x8f420000, 0x10400003, 0x0, 0x1000004e,
-0xaf80004c, 0x1000004c, 0xaf800048, 0x1040002f,
+0x8f420000, 0x10400003, 0x0, 0x10000038,
+0xaf80004c, 0x10000036, 0xaf800048, 0x1040002f,
0x30a21000, 0x1040000c, 0x30a24000, 0x8c83001c,
0x8f420050, 0x622023, 0x4820001, 0x24840200,
0x8f42035c, 0x441021, 0xaf42035c, 0x8f420368,
@@ -6618,190 +6630,179 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x3c020800, 0x8c83001c, 0x8f420060, 0x622023,
0x4820001, 0x24840100, 0x8f420360, 0x441021,
0xaf420360, 0x8f420368, 0xaf430060, 0x441021,
-0xaf420368, 0x3c020800, 0x2c21024, 0x5040001e,
-0x36940040, 0x1000001c, 0x0, 0x30a20100,
-0x10400019, 0x0, 0x3c020001, 0x8c426d44,
-0x1040000d, 0x274301c0, 0x24650400, 0x65102b,
-0x10400007, 0x26e40028, 0x8c820000, 0xac620000,
-0x24630004, 0x65102b, 0x1440fffb, 0x24840004,
-0x10000002, 0x274401c0, 0x26e40028, 0xc002bb4,
-0x0, 0x8f4202dc, 0xa34005c5, 0x24420001,
-0xaf4202dc, 0x8f4202dc, 0x8fbf0020, 0x3e00008,
-0x27bd0028, 0x3e00008, 0x0, 0x27bdffa8,
-0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044,
-0xafb20040, 0xafb1003c, 0xafb00038, 0x8f910108,
-0x26220020, 0xaf820108, 0x8e320018, 0xa821,
-0x32420024, 0x104001ba, 0xf021, 0x8e26001c,
-0x8f43001c, 0x61100, 0x621821, 0x8c70000c,
-0x9604000c, 0x962d0016, 0x9473000a, 0x2c8305dd,
-0x38828870, 0x2c420001, 0x621825, 0x10600015,
-0x2821, 0x32c20040, 0x10400015, 0x24020800,
-0x96030014, 0x14620012, 0x3402aaaa, 0x9603000e,
-0x14620007, 0x2021, 0x96030010, 0x24020300,
-0x14620004, 0x801021, 0x96020012, 0x2c440001,
-0x801021, 0x54400006, 0x24050016, 0x10000004,
-0x0, 0x24020800, 0x50820001, 0x2405000e,
-0x934205c3, 0x14400008, 0x5821, 0x240b0001,
-0x32620180, 0xaf4500a8, 0xaf5000a0, 0x10400002,
-0xaf4600a4, 0xa34b05c3, 0x10a00085, 0x2054021,
-0x91020000, 0x3821, 0x3042000f, 0x25080,
-0x32c20002, 0x10400012, 0x10a1821, 0x32620002,
-0x10400010, 0x32c20001, 0x1002021, 0x94820000,
-0x24840002, 0xe23821, 0x83102b, 0x1440fffb,
-0x30e2ffff, 0x71c02, 0x623821, 0x71c02,
-0x30e2ffff, 0x623821, 0x71027, 0xa502000a,
-0x32c20001, 0x1040006a, 0x32620001, 0x10400068,
-0x0, 0x8f4200a8, 0x10400065, 0x0,
-0x8f4200a0, 0x8f4300a8, 0x431021, 0x904c0009,
-0x318900ff, 0x39230006, 0x3182b, 0x39220011,
-0x2102b, 0x621824, 0x1060000c, 0x3c050006,
-0x8f4200a4, 0x3c040001, 0x24846864, 0xafa20010,
-0x8f4200a0, 0x34a54600, 0x1203821, 0xc002b17,
-0xafa20014, 0x1000004e, 0x0, 0x32c20004,
-0x14400013, 0x2821, 0x316200ff, 0x14400004,
-0x0, 0x95020002, 0x1000000d, 0x4a2823,
-0x9505000c, 0x9502000e, 0x95030010, 0xa22821,
-0xa32821, 0x95030012, 0x91040009, 0x95020002,
-0xa32821, 0xa42821, 0x4a1023, 0xa22821,
-0x2002021, 0x94820000, 0x24840002, 0xe23821,
-0x88102b, 0x1440fffb, 0x71c02, 0x30e2ffff,
+0xaf420368, 0x3c020800, 0x2c21024, 0x50400008,
+0x36940040, 0x10000006, 0x0, 0x30a20100,
+0x10400003, 0x0, 0xc002bd8, 0x0,
+0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3e00008,
+0x0, 0x27bdffa8, 0xafbf0050, 0xafbe004c,
+0xafb50048, 0xafb30044, 0xafb20040, 0xafb1003c,
+0xafb00038, 0x8f910108, 0x26220020, 0xaf820108,
+0x8e320018, 0xa821, 0x32420024, 0x104001ba,
+0xf021, 0x8e26001c, 0x8f43001c, 0x61100,
+0x621821, 0x8c70000c, 0x9604000c, 0x962d0016,
+0x9473000a, 0x2c8305dd, 0x38828870, 0x2c420001,
+0x621825, 0x10600015, 0x2821, 0x32c20040,
+0x10400015, 0x24020800, 0x96030014, 0x14620012,
+0x3402aaaa, 0x9603000e, 0x14620007, 0x2021,
+0x96030010, 0x24020300, 0x14620004, 0x801021,
+0x96020012, 0x2c440001, 0x801021, 0x54400006,
+0x24050016, 0x10000004, 0x0, 0x24020800,
+0x50820001, 0x2405000e, 0x934205c3, 0x14400008,
+0x5821, 0x240b0001, 0x32620180, 0xaf4500a8,
+0xaf5000a0, 0x10400002, 0xaf4600a4, 0xa34b05c3,
+0x10a00085, 0x2054021, 0x91020000, 0x3821,
+0x3042000f, 0x25080, 0x32c20002, 0x10400012,
+0x10a1821, 0x32620002, 0x10400010, 0x32c20001,
+0x1002021, 0x94820000, 0x24840002, 0xe23821,
+0x83102b, 0x1440fffb, 0x30e2ffff, 0x71c02,
0x623821, 0x71c02, 0x30e2ffff, 0x623821,
-0x1a52821, 0x51c02, 0x30a2ffff, 0x622821,
-0x51c02, 0x30a2ffff, 0x622821, 0xa72823,
-0x51402, 0xa22821, 0x30a5ffff, 0x50a00001,
-0x3405ffff, 0x316200ff, 0x14400008, 0x318300ff,
-0x8f4300a0, 0x8f4200a8, 0x624021, 0x91020000,
-0x3042000f, 0x25080, 0x318300ff, 0x24020006,
-0x14620003, 0x10a1021, 0x10000002, 0x24440010,
-0x24440006, 0x316200ff, 0x14400006, 0x0,
-0x94820000, 0xa22821, 0x51c02, 0x30a2ffff,
-0x622821, 0x934205c3, 0x10400003, 0x32620100,
-0x50400003, 0xa4850000, 0x52827, 0xa4850000,
-0x9622000e, 0x8f43009c, 0x621821, 0x32a200ff,
-0x10400007, 0xaf43009c, 0x3c024000, 0x2021025,
-0xafa20020, 0x8f42009c, 0x10000003, 0x5e1025,
-0xafb00020, 0x8f42009c, 0xafa20024, 0x32620080,
-0x10400010, 0x32620100, 0x8f4200b4, 0x24430001,
-0x210c0, 0x571021, 0xaf4300b4, 0x8fa30020,
-0x8fa40024, 0x3c010001, 0x220821, 0xac2338e8,
-0x3c010001, 0x220821, 0xac2438ec, 0x100000a5,
-0x32c20020, 0x10400064, 0x0, 0x8f4200b4,
-0x24430001, 0x210c0, 0x571021, 0xaf4300b4,
-0x8fa30020, 0x8fa40024, 0x3c010001, 0x220821,
-0xac2338e8, 0x3c010001, 0x220821, 0xac2438ec,
-0x8f4200b4, 0x10400051, 0x3821, 0x3c090001,
-0x352938e8, 0x3c08001f, 0x3508ffff, 0x240bffff,
-0x340affff, 0x710c0, 0x571021, 0x491021,
-0x8c430000, 0x8c440004, 0xafa30028, 0xafa4002c,
-0x8f8200fc, 0x8fa30028, 0x8fa4002c, 0xac430000,
-0xac440004, 0x24420008, 0xaf8200f0, 0x8f42008c,
-0x2442ffff, 0xaf42008c, 0x97a2002e, 0x8f440270,
-0x8f450274, 0x401821, 0x1021, 0xa32821,
-0xa3302b, 0x822021, 0x862021, 0xaf440270,
-0xaf450274, 0x8fa20028, 0x481024, 0x90430000,
-0x30630001, 0x1460000b, 0x402021, 0x8f420278,
-0x8f43027c, 0x24630001, 0x2c640001, 0x441021,
-0xaf420278, 0xaf43027c, 0x8f420278, 0x1000001a,
-0x8f43027c, 0x8c820000, 0x144b000e, 0x0,
-0x94820004, 0x144a000b, 0x0, 0x8f420288,
-0x8f43028c, 0x24630001, 0x2c640001, 0x441021,
-0xaf420288, 0xaf43028c, 0x8f420288, 0x1000000a,
-0x8f43028c, 0x8f420280, 0x8f430284, 0x24630001,
-0x2c640001, 0x441021, 0xaf420280, 0xaf430284,
-0x8f420280, 0x8f430284, 0x8f4200b4, 0x24e70001,
-0xe2102b, 0x1440ffb8, 0x710c0, 0xa34005c3,
-0x1000003f, 0xaf4000b4, 0x8f8200fc, 0x8fa30020,
-0x8fa40024, 0xac430000, 0xac440004, 0x24420008,
-0xaf8200f0, 0x8f42009c, 0x8f46008c, 0x8f440270,
-0x8f450274, 0x401821, 0x1021, 0x24c6ffff,
-0xaf46008c, 0xa32821, 0xa3302b, 0x822021,
-0x862021, 0xaf440270, 0xaf450274, 0x92020000,
-0x30420001, 0x1440000c, 0x2402ffff, 0x8f420278,
-0x8f43027c, 0x24630001, 0x2c640001, 0x441021,
-0xaf420278, 0xaf43027c, 0x8f420278, 0x8f43027c,
-0x1000001c, 0x32c20020, 0x8e030000, 0x1462000f,
-0x3402ffff, 0x96030004, 0x1462000c, 0x0,
-0x8f420288, 0x8f43028c, 0x24630001, 0x2c640001,
-0x441021, 0xaf420288, 0xaf43028c, 0x8f420288,
-0x8f43028c, 0x1000000b, 0x32c20020, 0x8f420280,
+0x71027, 0xa502000a, 0x32c20001, 0x1040006a,
+0x32620001, 0x10400068, 0x0, 0x8f4200a8,
+0x10400065, 0x0, 0x8f4200a0, 0x8f4300a8,
+0x431021, 0x904c0009, 0x318900ff, 0x39230006,
+0x3182b, 0x39220011, 0x2102b, 0x621824,
+0x1060000c, 0x3c050006, 0x8f4200a4, 0x3c040001,
+0x248467d4, 0xafa20010, 0x8f4200a0, 0x34a54600,
+0x1203821, 0xc002b3b, 0xafa20014, 0x1000004e,
+0x0, 0x32c20004, 0x14400013, 0x2821,
+0x316200ff, 0x14400004, 0x0, 0x95020002,
+0x1000000d, 0x4a2823, 0x9505000c, 0x9502000e,
+0x95030010, 0xa22821, 0xa32821, 0x95030012,
+0x91040009, 0x95020002, 0xa32821, 0xa42821,
+0x4a1023, 0xa22821, 0x2002021, 0x94820000,
+0x24840002, 0xe23821, 0x88102b, 0x1440fffb,
+0x71c02, 0x30e2ffff, 0x623821, 0x71c02,
+0x30e2ffff, 0x623821, 0x1a52821, 0x51c02,
+0x30a2ffff, 0x622821, 0x51c02, 0x30a2ffff,
+0x622821, 0xa72823, 0x51402, 0xa22821,
+0x30a5ffff, 0x50a00001, 0x3405ffff, 0x316200ff,
+0x14400008, 0x318300ff, 0x8f4300a0, 0x8f4200a8,
+0x624021, 0x91020000, 0x3042000f, 0x25080,
+0x318300ff, 0x24020006, 0x14620003, 0x10a1021,
+0x10000002, 0x24440010, 0x24440006, 0x316200ff,
+0x14400006, 0x0, 0x94820000, 0xa22821,
+0x51c02, 0x30a2ffff, 0x622821, 0x934205c3,
+0x10400003, 0x32620100, 0x50400003, 0xa4850000,
+0x52827, 0xa4850000, 0x9622000e, 0x8f43009c,
+0x621821, 0x32a200ff, 0x10400007, 0xaf43009c,
+0x3c024000, 0x2021025, 0xafa20020, 0x8f42009c,
+0x10000003, 0x5e1025, 0xafb00020, 0x8f42009c,
+0xafa20024, 0x32620080, 0x10400010, 0x32620100,
+0x8f4200b4, 0x24430001, 0x210c0, 0x571021,
+0xaf4300b4, 0x8fa30020, 0x8fa40024, 0x3c010001,
+0x220821, 0xac2338e8, 0x3c010001, 0x220821,
+0xac2438ec, 0x100000a5, 0x32c20020, 0x10400064,
+0x0, 0x8f4200b4, 0x24430001, 0x210c0,
+0x571021, 0xaf4300b4, 0x8fa30020, 0x8fa40024,
+0x3c010001, 0x220821, 0xac2338e8, 0x3c010001,
+0x220821, 0xac2438ec, 0x8f4200b4, 0x10400051,
+0x3821, 0x3c090001, 0x352938e8, 0x3c08001f,
+0x3508ffff, 0x240bffff, 0x340affff, 0x710c0,
+0x571021, 0x491021, 0x8c430000, 0x8c440004,
+0xafa30028, 0xafa4002c, 0x8f8200fc, 0x8fa30028,
+0x8fa4002c, 0xac430000, 0xac440004, 0x24420008,
+0xaf8200f0, 0x8f42008c, 0x2442ffff, 0xaf42008c,
+0x97a2002e, 0x8f440270, 0x8f450274, 0x401821,
+0x1021, 0xa32821, 0xa3302b, 0x822021,
+0x862021, 0xaf440270, 0xaf450274, 0x8fa20028,
+0x481024, 0x90430000, 0x30630001, 0x1460000b,
+0x402021, 0x8f420278, 0x8f43027c, 0x24630001,
+0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
+0x8f420278, 0x1000001a, 0x8f43027c, 0x8c820000,
+0x144b000e, 0x0, 0x94820004, 0x144a000b,
+0x0, 0x8f420288, 0x8f43028c, 0x24630001,
+0x2c640001, 0x441021, 0xaf420288, 0xaf43028c,
+0x8f420288, 0x1000000a, 0x8f43028c, 0x8f420280,
0x8f430284, 0x24630001, 0x2c640001, 0x441021,
0xaf420280, 0xaf430284, 0x8f420280, 0x8f430284,
-0x32c20020, 0x10400005, 0xaf40009c, 0x8f420358,
+0x8f4200b4, 0x24e70001, 0xe2102b, 0x1440ffb8,
+0x710c0, 0xa34005c3, 0x1000003f, 0xaf4000b4,
+0x8f8200fc, 0x8fa30020, 0x8fa40024, 0xac430000,
+0xac440004, 0x24420008, 0xaf8200f0, 0x8f42009c,
+0x8f46008c, 0x8f440270, 0x8f450274, 0x401821,
+0x1021, 0x24c6ffff, 0xaf46008c, 0xa32821,
+0xa3302b, 0x822021, 0x862021, 0xaf440270,
+0xaf450274, 0x92020000, 0x30420001, 0x1440000c,
+0x2402ffff, 0x8f420278, 0x8f43027c, 0x24630001,
+0x2c640001, 0x441021, 0xaf420278, 0xaf43027c,
+0x8f420278, 0x8f43027c, 0x1000001c, 0x32c20020,
+0x8e030000, 0x1462000f, 0x3402ffff, 0x96030004,
+0x1462000c, 0x0, 0x8f420288, 0x8f43028c,
+0x24630001, 0x2c640001, 0x441021, 0xaf420288,
+0xaf43028c, 0x8f420288, 0x8f43028c, 0x1000000b,
+0x32c20020, 0x8f420280, 0x8f430284, 0x24630001,
+0x2c640001, 0x441021, 0xaf420280, 0xaf430284,
+0x8f420280, 0x8f430284, 0x32c20020, 0x10400005,
+0xaf40009c, 0x8f420358, 0x2442ffff, 0xaf420358,
+0x8f420358, 0x8e22001c, 0x8f430040, 0x24420001,
+0x2463ffff, 0x431024, 0xaf42002c, 0x32420060,
+0x14400008, 0x32c20010, 0x8f420034, 0x24420001,
+0xaf420034, 0x8c03023c, 0x43102b, 0x14400102,
+0x32c20010, 0x10400018, 0x24070008, 0x8f440170,
+0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
+0x24020080, 0xafa20010, 0xafa30014, 0xafa80018,
+0x8f42010c, 0x40f809, 0x24c6001c, 0x10400047,
+0x24020001, 0x8f420300, 0x8f43002c, 0x24420001,
+0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
+0x1000007c, 0xaf430038, 0x8f440170, 0x8f450174,
+0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020020,
+0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
+0x40f809, 0x24c6001c, 0x10400057, 0x24020001,
+0x10000065, 0x0, 0x32420012, 0x10400075,
+0x32420001, 0x9622000e, 0x8f43009c, 0x621821,
+0x32c20020, 0x10400005, 0xaf43009c, 0x8f420358,
0x2442ffff, 0xaf420358, 0x8f420358, 0x8e22001c,
0x8f430040, 0x24420001, 0x2463ffff, 0x431024,
-0xaf42002c, 0x32420060, 0x14400008, 0x32c20010,
+0xaf42002c, 0x32420010, 0x14400008, 0x32c20010,
0x8f420034, 0x24420001, 0xaf420034, 0x8c03023c,
-0x43102b, 0x14400118, 0x32c20010, 0x10400018,
+0x43102b, 0x144000bc, 0x32c20010, 0x10400028,
0x24070008, 0x8f440170, 0x8f450174, 0x8f43002c,
0x8f48000c, 0x8f860120, 0x24020080, 0xafa20010,
0xafa30014, 0xafa80018, 0x8f42010c, 0x40f809,
-0x24c6001c, 0x10400047, 0x24020001, 0x8f420300,
+0x24c6001c, 0x14400011, 0x24020001, 0x3c010001,
+0x370821, 0xa02240f1, 0x8f820124, 0xafa20010,
+0x8f820128, 0x3c040001, 0x248467c4, 0xafa20014,
+0x8f46002c, 0x8f870120, 0x3c050009, 0xc002b3b,
+0x34a51100, 0x10000036, 0x0, 0x8f420300,
0x8f43002c, 0x24420001, 0xaf420300, 0x8f420300,
-0x24020001, 0xa34205c1, 0x1000007c, 0xaf430038,
+0x24020001, 0xa34205c1, 0x10000026, 0xaf430038,
0x8f440170, 0x8f450174, 0x8f43002c, 0x8f48000c,
0x8f860120, 0x24020020, 0xafa20010, 0xafa30014,
0xafa80018, 0x8f42010c, 0x40f809, 0x24c6001c,
-0x10400057, 0x24020001, 0x10000065, 0x0,
-0x32420012, 0x10400075, 0x32420001, 0x9622000e,
-0x8f43009c, 0x621821, 0x32c20020, 0x10400005,
-0xaf43009c, 0x8f420358, 0x2442ffff, 0xaf420358,
-0x8f420358, 0x8e22001c, 0x8f430040, 0x24420001,
-0x2463ffff, 0x431024, 0xaf42002c, 0x32420010,
-0x14400008, 0x32c20010, 0x8f420034, 0x24420001,
-0xaf420034, 0x8c03023c, 0x43102b, 0x144000d2,
-0x32c20010, 0x10400028, 0x24070008, 0x8f440170,
-0x8f450174, 0x8f43002c, 0x8f48000c, 0x8f860120,
-0x24020080, 0xafa20010, 0xafa30014, 0xafa80018,
-0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
-0x24020001, 0x3c010001, 0x370821, 0xa02240f1,
-0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x24846854, 0xafa20014, 0x8f46002c, 0x8f870120,
-0x3c050009, 0xc002b17, 0x34a51100, 0x10000036,
-0x0, 0x8f420300, 0x8f43002c, 0x24420001,
-0xaf420300, 0x8f420300, 0x24020001, 0xa34205c1,
-0x10000026, 0xaf430038, 0x8f440170, 0x8f450174,
-0x8f43002c, 0x8f48000c, 0x8f860120, 0x24020020,
-0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
-0x40f809, 0x24c6001c, 0x14400011, 0x24020001,
-0x3c010001, 0x370821, 0xa02240f0, 0x8f820124,
-0xafa20010, 0x8f820128, 0x3c040001, 0x24846848,
-0xafa20014, 0x8f46002c, 0x8f870120, 0x3c050009,
-0xc002b17, 0x34a50900, 0x1000000f, 0x0,
-0x8f420300, 0x24420001, 0xaf420300, 0x8f420300,
-0x8f42002c, 0xa34005c1, 0xaf420038, 0x3c010001,
-0x370821, 0xa02040f1, 0x3c010001, 0x370821,
-0xa02040f0, 0xaf400034, 0x8f420314, 0x24420001,
-0xaf420314, 0x10000078, 0x8f420314, 0x10400022,
-0x32427000, 0x8e25001c, 0x8f420028, 0xa22023,
-0x4810003, 0x0, 0x8f420040, 0x822021,
-0x8f420358, 0x8f430000, 0xaf450028, 0x441021,
-0x10600007, 0xaf420358, 0xaf80004c, 0x8f82004c,
-0x1040fffd, 0x0, 0x10000005, 0x0,
-0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
-0x8f820060, 0x34420008, 0xaf820060, 0x8f420000,
-0x10400003, 0x0, 0x10000057, 0xaf80004c,
-0x10000055, 0xaf800048, 0x1040002f, 0x32421000,
-0x1040000c, 0x32424000, 0x8e23001c, 0x8f420050,
-0x622023, 0x4820001, 0x24840200, 0x8f42035c,
-0x441021, 0xaf42035c, 0x8f420368, 0x1000001a,
-0xaf430050, 0x1040000c, 0x32c28000, 0x8e23001c,
-0x8f420070, 0x622023, 0x4820001, 0x24840400,
-0x8f420364, 0x441021, 0xaf420364, 0x8f420368,
-0x1000000d, 0xaf430070, 0x1040000e, 0x3c020800,
-0x8e23001c, 0x8f420060, 0x622023, 0x4820001,
-0x24840100, 0x8f420360, 0x441021, 0xaf420360,
-0x8f420368, 0xaf430060, 0x441021, 0xaf420368,
-0x3c020800, 0x2c21024, 0x50400027, 0x36940040,
-0x10000025, 0x0, 0x32420048, 0x10400007,
-0x24150001, 0x8e22001c, 0x3c03ffff, 0x43f024,
-0x3042ffff, 0x1000fd75, 0xae22001c, 0x32420100,
-0x10400019, 0x0, 0x3c020001, 0x8c426d44,
-0x1040000d, 0x274301c0, 0x24650400, 0x65102b,
-0x10400007, 0x26e40028, 0x8c820000, 0xac620000,
-0x24630004, 0x65102b, 0x1440fffb, 0x24840004,
-0x10000002, 0x274401c0, 0x26e40028, 0xc002bb4,
-0x0, 0x8f4202dc, 0xa34005c5, 0x24420001,
-0xaf4202dc, 0x8f4202dc, 0x8fbf0050, 0x8fbe004c,
+0x14400011, 0x24020001, 0x3c010001, 0x370821,
+0xa02240f0, 0x8f820124, 0xafa20010, 0x8f820128,
+0x3c040001, 0x248467b8, 0xafa20014, 0x8f46002c,
+0x8f870120, 0x3c050009, 0xc002b3b, 0x34a50900,
+0x1000000f, 0x0, 0x8f420300, 0x24420001,
+0xaf420300, 0x8f420300, 0x8f42002c, 0xa34005c1,
+0xaf420038, 0x3c010001, 0x370821, 0xa02040f1,
+0x3c010001, 0x370821, 0xa02040f0, 0xaf400034,
+0x8f420314, 0x24420001, 0xaf420314, 0x10000062,
+0x8f420314, 0x10400022, 0x32427000, 0x8e25001c,
+0x8f420028, 0xa22023, 0x4810003, 0x0,
+0x8f420040, 0x822021, 0x8f420358, 0x8f430000,
+0xaf450028, 0x441021, 0x10600007, 0xaf420358,
+0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
+0x10000005, 0x0, 0xaf800048, 0x8f820048,
+0x1040fffd, 0x0, 0x8f820060, 0x34420008,
+0xaf820060, 0x8f420000, 0x10400003, 0x0,
+0x10000041, 0xaf80004c, 0x1000003f, 0xaf800048,
+0x1040002f, 0x32421000, 0x1040000c, 0x32424000,
+0x8e23001c, 0x8f420050, 0x622023, 0x4820001,
+0x24840200, 0x8f42035c, 0x441021, 0xaf42035c,
+0x8f420368, 0x1000001a, 0xaf430050, 0x1040000c,
+0x32c28000, 0x8e23001c, 0x8f420070, 0x622023,
+0x4820001, 0x24840400, 0x8f420364, 0x441021,
+0xaf420364, 0x8f420368, 0x1000000d, 0xaf430070,
+0x1040000e, 0x3c020800, 0x8e23001c, 0x8f420060,
+0x622023, 0x4820001, 0x24840100, 0x8f420360,
+0x441021, 0xaf420360, 0x8f420368, 0xaf430060,
+0x441021, 0xaf420368, 0x3c020800, 0x2c21024,
+0x50400011, 0x36940040, 0x1000000f, 0x0,
+0x32420048, 0x10400007, 0x24150001, 0x8e22001c,
+0x3c03ffff, 0x43f024, 0x3042ffff, 0x1000fd75,
+0xae22001c, 0x32420100, 0x10400003, 0x0,
+0xc002bd8, 0x0, 0x8fbf0050, 0x8fbe004c,
0x8fb50048, 0x8fb30044, 0x8fb20040, 0x8fb1003c,
0x8fb00038, 0x3e00008, 0x27bd0058, 0x3e00008,
0x0, 0x0, 0x0, 0x8f8300e4,
@@ -6818,7 +6819,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x10400003, 0x0, 0x8f420148, 0x621821,
0x94a20006, 0x24420050, 0x62102b, 0x1440000f,
0xa01021, 0xafa40010, 0xafa30014, 0x8ca60000,
-0x8ca70004, 0x3c040001, 0xc002b17, 0x24846924,
+0x8ca70004, 0x3c040001, 0xc002b3b, 0x24846894,
0x8f42020c, 0x24420001, 0xaf42020c, 0x8f42020c,
0x1021, 0xaf9000e8, 0xaf9000e4, 0x8fbf001c,
0x8fb00018, 0x3e00008, 0x27bd0020, 0x3e00008,
@@ -6840,15 +6841,15 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f4b00c4, 0xafab0064, 0x8f4a00c0, 0xafaa006c,
0x8f4b00cc, 0xafab0074, 0x8f4a00c8, 0x10000129,
0xafaa007c, 0x8f420114, 0x40f809, 0x0,
-0x403021, 0x10c0033f, 0x0, 0x8cc20000,
+0x403021, 0x10c0034f, 0x0, 0x8cc20000,
0x8cc30004, 0xafa20020, 0xafa30024, 0x8fab0024,
0x8faa0020, 0x3162ffff, 0x2442fffc, 0xafa2006c,
0x3c020006, 0x2c21024, 0xafab007c, 0x14400015,
0xafaa0064, 0x91420000, 0x30420001, 0x10400011,
0x2402ffff, 0x8d430000, 0x14620004, 0x3402ffff,
-0x95430004, 0x1062000b, 0x0, 0xc002497,
+0x95430004, 0x1062000b, 0x0, 0xc0024bb,
0x8fa40064, 0x304200ff, 0x14400006, 0x0,
-0x8f420118, 0x40f809, 0x0, 0x1000031d,
+0x8f420118, 0x40f809, 0x0, 0x1000032d,
0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
0x431024, 0x3c03ffff, 0x431824, 0x14600003,
0xafa20024, 0x10000040, 0x1821, 0x3c020080,
@@ -6871,13 +6872,13 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x4b102b, 0x10400014, 0x307000ff, 0x8f4201e8,
0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8faa007c,
0x8f8200e0, 0x354a0100, 0xafaa007c, 0xafa20010,
-0x8f8200e4, 0x24100001, 0x3c040001, 0x24846930,
+0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0,
0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007,
-0xc002b17, 0x34a50800, 0x12000010, 0x3c020080,
+0xc002b3b, 0x34a50800, 0x12000010, 0x3c020080,
0x2c21024, 0x1440000e, 0x32c20400, 0x8fab007c,
0x3c020080, 0x34420100, 0x1621024, 0x10400005,
0x0, 0x8f42020c, 0x24420001, 0xaf42020c,
-0x8f42020c, 0x100002a0, 0x8fa3006c, 0x32c20400,
+0x8f42020c, 0x100002b0, 0x8fa3006c, 0x32c20400,
0x10400015, 0x34028100, 0x8faa0064, 0x9543000c,
0x14620012, 0x3c020100, 0x240b0200, 0xa7ab008e,
0x9542000e, 0x8d430008, 0x8d440004, 0x8d450000,
@@ -6892,66 +6893,66 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x10400056, 0x32c28000, 0x1040005e, 0x240a0003,
0x32c21000, 0x1040005b, 0xafaa005c, 0x10000058,
0x240b0004, 0x8f420350, 0x2403ffbf, 0x283a024,
-0x24420001, 0xaf420350, 0x1000023f, 0x8f420350,
+0x24420001, 0xaf420350, 0x1000024f, 0x8f420350,
0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128,
-0x3c040001, 0x24846960, 0x26620001, 0xafa20014,
+0x3c040001, 0x248468d0, 0x26620001, 0xafa20014,
0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007,
-0xc002b17, 0x34a52250, 0x1000022f, 0x0,
+0xc002b3b, 0x34a52250, 0x1000023f, 0x0,
0x2c2b025, 0x2402ffbf, 0x282a024, 0x8f830128,
-0x3c040001, 0x24846960, 0x24020002, 0xafa20014,
+0x3c040001, 0x248468d0, 0x24020002, 0xafa20014,
0xafa30010, 0x8f860120, 0x8f870124, 0x3c050007,
-0xc002b17, 0x34a52450, 0x1000021f, 0x0,
-0x8ea20000, 0x8ea30004, 0x3c040001, 0x24846978,
+0xc002b3b, 0x34a52450, 0x1000022f, 0x0,
+0x8ea20000, 0x8ea30004, 0x3c040001, 0x248468e8,
0xafb00010, 0xafbe0014, 0x8ea70018, 0x34a52800,
-0xc002b17, 0x603021, 0x10000213, 0x0,
-0xa6b1000a, 0x8f820124, 0x3c040001, 0x24846980,
+0xc002b3b, 0x603021, 0x10000223, 0x0,
+0xa6b1000a, 0x8f820124, 0x3c040001, 0x248468f0,
0xafbe0014, 0xafa20010, 0x8f460044, 0x8f870120,
-0x3c050007, 0xc002b17, 0x34a53000, 0x10000206,
+0x3c050007, 0xc002b3b, 0x34a53000, 0x10000216,
0x0, 0xa6b1000a, 0xa6b2000e, 0x8f820124,
-0x3c040001, 0x2484698c, 0xafbe0014, 0xafa20010,
-0x8f460044, 0x8f870120, 0x3c050007, 0xc002b17,
-0x34a53200, 0x100001f8, 0x0, 0x8f420084,
+0x3c040001, 0x248468fc, 0xafbe0014, 0xafa20010,
+0x8f460044, 0x8f870120, 0x3c050007, 0xc002b3b,
+0x34a53200, 0x10000208, 0x0, 0x8f420084,
0x8faa006c, 0x4a102b, 0x14400007, 0x3c020001,
0x2c21024, 0x10400004, 0x0, 0x240b0002,
-0xafab005c, 0x8faa006c, 0x1140020b, 0x27ab0020,
+0xafab005c, 0x8faa006c, 0x1140021b, 0x27ab0020,
0xafab00a4, 0x3c0a001f, 0x354affff, 0xafaa009c,
-0x8fab005c, 0x240a0001, 0x156a0021, 0x24020002,
+0x8fab005c, 0x240a0001, 0x556a0021, 0x240a0002,
0x8f430054, 0x8f420050, 0x1062000b, 0x274b0054,
0x8f5e0054, 0x3403ecc0, 0xafab004c, 0x27c20001,
0x304201ff, 0xafa20054, 0x1e1140, 0x431021,
0x1000006b, 0x2e2a821, 0x8f420044, 0x8faa006c,
-0x3c040001, 0x2484693c, 0xafaa0014, 0xafa20010,
-0x8f460054, 0x8f470050, 0x3c050007, 0xc002b17,
+0x3c040001, 0x248468ac, 0xafaa0014, 0xafa20010,
+0x8f460054, 0x8f470050, 0x3c050007, 0xc002b3b,
0x34a51300, 0x8f430350, 0x2402ffbf, 0x282a024,
-0x24630001, 0xaf430350, 0x100001c3, 0x8f420350,
-0x1562001d, 0x0, 0x8f430074, 0x8f420070,
-0x1062000a, 0x274a0074, 0x8f5e0074, 0xafaa004c,
+0x24630001, 0xaf430350, 0x100001d3, 0x8f420350,
+0x156a001d, 0x0, 0x8f430074, 0x8f420070,
+0x1062000a, 0x274b0074, 0x8f5e0074, 0xafab004c,
0x27c20001, 0x304203ff, 0xafa20054, 0x1e1140,
0x24426cc0, 0x1000004a, 0x2e2a821, 0x8f420044,
-0x8fab006c, 0x3c040001, 0x24846948, 0x3c050007,
-0xafab0014, 0xafa20010, 0x8f460074, 0x8f470070,
-0x34a51500, 0x240a0001, 0xc002b17, 0xafaa005c,
+0x8faa006c, 0x3c040001, 0x248468b8, 0x3c050007,
+0xafaa0014, 0xafa20010, 0x8f460074, 0x8f470070,
+0x34a51500, 0x240b0001, 0xc002b3b, 0xafab005c,
0x1000ffc3, 0x0, 0x8f430064, 0x8f420060,
-0x1062001a, 0x274b0064, 0x8f5e0064, 0x8faa005c,
-0xafab004c, 0x27c20001, 0x304200ff, 0xafa20054,
-0x24020004, 0x1542000e, 0x1e1140, 0x1e1180,
+0x1062001a, 0x274a0064, 0x8f5e0064, 0x8fab005c,
+0xafaa004c, 0x27c20001, 0x304200ff, 0xafa20054,
+0x24020004, 0x1562000e, 0x1e1140, 0x1e1180,
0x24420cc0, 0x2e21021, 0xafa20044, 0x9442002a,
-0x8fab0044, 0x8faa006c, 0x4a102b, 0x10400024,
-0x25750020, 0x240b0001, 0x10000021, 0xa3ab0097,
+0x8faa0044, 0x8fab006c, 0x4b102b, 0x10400024,
+0x25550020, 0x240a0001, 0x10000021, 0xa3aa0097,
0x24424cc0, 0x1000001e, 0x2e2a821, 0x8f420044,
-0x8faa006c, 0x3c040001, 0x24846954, 0xafaa0014,
+0x8fab006c, 0x3c040001, 0x248468c4, 0xafab0014,
0xafa20010, 0x8f460064, 0x8f470060, 0x3c050007,
-0xc002b17, 0x34a51800, 0x3c020008, 0x2c21024,
-0x1440ff34, 0x0, 0x8f420370, 0x240b0001,
-0xafab005c, 0x24420001, 0xaf420370, 0x1000ff90,
+0xc002b3b, 0x34a51800, 0x3c020008, 0x2c21024,
+0x1440ff34, 0x0, 0x8f420370, 0x240a0001,
+0xafaa005c, 0x24420001, 0xaf420370, 0x1000ff90,
0x8f420370, 0x27a30036, 0x131040, 0x621821,
0x94620000, 0x441021, 0x10000020, 0xa4620000,
-0x8faa0064, 0xaeaa0018, 0x93a20097, 0x10400072,
-0x9821, 0x8fab0044, 0x8fa4006c, 0x8fa300a4,
-0x25620020, 0xafa20028, 0x25620008, 0xafa20030,
-0x25620010, 0xafab002c, 0xafa20034, 0x9562002a,
-0xa7a20038, 0x95620018, 0xa7a2003a, 0x9562001a,
-0xa7a2003c, 0x9562001c, 0xa7a2003e, 0x94620018,
+0x8fab0064, 0xaeab0018, 0x93a20097, 0x10400072,
+0x9821, 0x8faa0044, 0x8fa4006c, 0x8fa300a4,
+0x25420020, 0xafa20028, 0x25420008, 0xafa20030,
+0x25420010, 0xafaa002c, 0xafa20034, 0x9542002a,
+0xa7a20038, 0x95420018, 0xa7a2003a, 0x9542001a,
+0xa7a2003c, 0x9542001c, 0xa7a2003e, 0x94620018,
0x24630002, 0x822023, 0x1880ffde, 0x26730001,
0x2e620004, 0x1440fff9, 0x0, 0x8f4200fc,
0x26650001, 0xa2102a, 0x1440002b, 0x24030001,
@@ -6960,20 +6961,20 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f820128, 0x431023, 0x21943, 0x58600001,
0x24630040, 0x64102a, 0x54400001, 0x602021,
0xaf4400fc, 0x8f4200fc, 0xa2102a, 0x10400011,
-0x24030001, 0x10000015, 0x306200ff, 0x8faa0064,
-0x96070018, 0xafaa0010, 0x8e220008, 0x3c040001,
-0x2484696c, 0x8c430004, 0x8c420000, 0x34a52400,
-0x2403021, 0xc002b17, 0xafa30014, 0x1000002b,
+0x24030001, 0x10000015, 0x306200ff, 0x8fab0064,
+0x96070018, 0xafab0010, 0x8e220008, 0x3c040001,
+0x248468dc, 0x8c430004, 0x8c420000, 0x34a52400,
+0x2403021, 0xc002b3b, 0xafa30014, 0x1000002b,
0x0, 0x8f420334, 0x1821, 0x24420001,
0xaf420334, 0x8f420334, 0x306200ff, 0x5040fedc,
0x3c020800, 0x12600021, 0x9021, 0x8fb100a4,
0x2208021, 0x8e220008, 0x96070018, 0x8fa60064,
-0x8c440000, 0x8c450004, 0x240b0001, 0xafab0010,
+0x8c440000, 0x8c450004, 0x240a0001, 0xafaa0010,
0xafbe0014, 0x8f420008, 0xafa20018, 0x8f42010c,
0x40f809, 0x0, 0x1040ffd8, 0x3c050007,
-0x96020018, 0x8faa0064, 0x8fab009c, 0x1425021,
-0x16a102b, 0x10400004, 0xafaa0064, 0x8f420148,
-0x1425023, 0xafaa0064, 0x26100002, 0x26520001,
+0x96020018, 0x8fab0064, 0x8faa009c, 0x1625821,
+0x14b102b, 0x10400004, 0xafab0064, 0x8f420148,
+0x1625823, 0xafab0064, 0x26100002, 0x26520001,
0x253102b, 0x1440ffe3, 0x26310004, 0x8fb0006c,
0x10000036, 0x97b10038, 0x8f4200fc, 0x24050002,
0xa2102a, 0x1440001b, 0x24030001, 0x8f83012c,
@@ -6986,42 +6987,42 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f420334, 0x306200ff, 0x1040fea5, 0x3c020800,
0x96b1000a, 0x8fb0006c, 0x3223ffff, 0x70102b,
0x54400001, 0x608021, 0x8ea40000, 0x8ea50004,
-0x240a0001, 0xafaa0010, 0xafbe0014, 0x8f420008,
+0x240b0001, 0xafab0010, 0xafbe0014, 0x8f420008,
0x8fa60064, 0xafa20018, 0x8f42010c, 0x40f809,
0x2003821, 0x1040fea2, 0x3c050007, 0x96a3000e,
-0x97ab008e, 0x11600007, 0x609021, 0x934205c4,
-0x14400004, 0x0, 0x97aa0086, 0x6b1825,
-0xa6aa0016, 0x8fab007c, 0x3c02ffff, 0x1621024,
-0x10400003, 0xb1402, 0x34630400, 0xa6a20014,
-0x8faa006c, 0x560a0072, 0xa6a3000e, 0x34620004,
-0xa6a2000e, 0x8fab0074, 0x14b1021, 0xa6a2000a,
+0x97aa008e, 0x11400007, 0x609021, 0x934205c4,
+0x14400004, 0x0, 0x97ab0086, 0x6a1825,
+0xa6ab0016, 0x8faa007c, 0x3c02ffff, 0x1421024,
+0x10400003, 0xa1402, 0x34630400, 0xa6a20014,
+0x8fab006c, 0x560b0072, 0xa6a3000e, 0x34620004,
+0xa6a2000e, 0x8faa0074, 0x16a1021, 0xa6a2000a,
0x8f430044, 0x8f4401a0, 0x8f4501a4, 0x34028000,
0xafa20010, 0x8f420044, 0x2a03021, 0x24070020,
0xafa20014, 0x8f42000c, 0x31940, 0x604821,
0xafa20018, 0x8f42010c, 0x4021, 0xa92821,
0xa9182b, 0x882021, 0x40f809, 0x832021,
0x5040fe7f, 0xa6b2000e, 0x8f420368, 0xafa0006c,
-0xa34005c4, 0x2442ffff, 0xaf420368, 0x8faa005c,
-0x240b0001, 0x8f420368, 0x154b0006, 0x24020002,
+0xa34005c4, 0x2442ffff, 0xaf420368, 0x8fab005c,
+0x240a0001, 0x8f420368, 0x156a0006, 0x240a0002,
0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c,
-0x8f42035c, 0x15420006, 0x0, 0x8f420364,
+0x8f42035c, 0x156a0006, 0x0, 0x8f420364,
0x2442ffff, 0xaf420364, 0x10000005, 0x8f420364,
0x8f420360, 0x2442ffff, 0xaf420360, 0x8f420360,
0x8faa0054, 0x8fab004c, 0xad6a0000, 0x8f420044,
0x8f440088, 0x8f430078, 0x24420001, 0x441024,
0x24630001, 0xaf420044, 0xaf430078, 0x8c020240,
-0x62182b, 0x14600065, 0x24070008, 0x8f440168,
+0x62182b, 0x14600075, 0x24070008, 0x8f440168,
0x8f45016c, 0x8f430044, 0x8f48000c, 0x8f860120,
0x24020040, 0xafa20010, 0xafa30014, 0xafa80018,
0x8f42010c, 0x40f809, 0x24c6001c, 0x14400011,
0x240b0001, 0x3c010001, 0x370821, 0xa02b40f2,
0x8f820124, 0xafa20010, 0x8f820128, 0x3c040001,
-0x2484691c, 0xafa20014, 0x8f460044, 0x8f870120,
-0x3c050009, 0xc002b17, 0x34a51300, 0x1000000b,
+0x2484688c, 0xafa20014, 0x8f460044, 0x8f870120,
+0x3c050009, 0xc002b3b, 0x34a51300, 0x1000000b,
0x0, 0x8f420304, 0x24420001, 0xaf420304,
0x8f420304, 0x8f420044, 0xaf42007c, 0x3c010001,
0x370821, 0xa02040f2, 0xaf400078, 0x8f420318,
-0x24420001, 0xaf420318, 0x10000038, 0x8f420318,
+0x24420001, 0xaf420318, 0x10000048, 0x8f420318,
0xa6b0000a, 0x8f430044, 0x8f4401a0, 0x8f4501a4,
0x34028000, 0xafa20010, 0x8f420044, 0x2a03021,
0x24070020, 0xafa20014, 0x8f42000c, 0x31940,
@@ -7031,12 +7032,16 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8fab006c, 0x8faa0064, 0x1705823, 0xafab006c,
0x8fab009c, 0x1505021, 0x16a102b, 0x10400004,
0xafaa0064, 0x8f420148, 0x1425023, 0xafaa0064,
-0x8f420368, 0x2442ffff, 0xaf420368, 0x8f420368,
-0x8f42035c, 0x2442ffff, 0xaf42035c, 0x8fab0054,
-0x8faa004c, 0x8f42035c, 0xad4b0000, 0x8f420044,
+0x8f420368, 0x2442ffff, 0xaf420368, 0x8faa005c,
+0x240b0001, 0x8f420368, 0x154b0006, 0x240b0002,
+0x8f42035c, 0x2442ffff, 0xaf42035c, 0x1000000c,
+0x8f42035c, 0x114b0006, 0x0, 0x8f420360,
+0x2442ffff, 0xaf420360, 0x10000005, 0x8f420360,
+0x8f420364, 0x2442ffff, 0xaf420364, 0x8f420364,
+0x8fab0054, 0x8faa004c, 0xad4b0000, 0x8f420044,
0x8f440088, 0x8f430078, 0x24420001, 0x441024,
0x24630001, 0xaf420044, 0xaf430078, 0x8faa006c,
-0x1540fe1b, 0x0, 0x8fab006c, 0x1160001e,
+0x1540fe0b, 0x0, 0x8fab006c, 0x1160001e,
0x0, 0x934205c4, 0x10400009, 0x0,
0x8faa0064, 0xaf4a00c4, 0xaf4b00c0, 0x8fab007c,
0xaf4b00c8, 0x8faa0074, 0x1000000e, 0xaf4a00cc,
@@ -7063,7 +7068,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa20064, 0x3c020006, 0x2c21024, 0x14400015,
0xafac006c, 0x93c20000, 0x30420001, 0x10400011,
0x2402ffff, 0x8fc30000, 0x14620004, 0x3402ffff,
-0x97c30004, 0x1062000b, 0x0, 0xc002497,
+0x97c30004, 0x1062000b, 0x0, 0xc0024bb,
0x3c02021, 0x304200ff, 0x14400006, 0x0,
0x8f420118, 0x40f809, 0x0, 0x10000280,
0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
@@ -7088,9 +7093,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x4b102b, 0x10400015, 0x320200ff, 0x8f4201e8,
0x24420001, 0xaf4201e8, 0x8f4201e8, 0x8fac006c,
0x8f8200e0, 0x358c0100, 0xafac006c, 0xafa20010,
-0x8f8200e4, 0x24100001, 0x3c040001, 0x24846930,
+0x8f8200e4, 0x24100001, 0x3c040001, 0x248468a0,
0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050007,
-0xc002b17, 0x34a53600, 0x320200ff, 0x10400010,
+0xc002b3b, 0x34a53600, 0x320200ff, 0x10400010,
0x3c020080, 0x2c21024, 0x1440000e, 0x32c20400,
0x8fab006c, 0x3c020080, 0x34420100, 0x1621024,
0x10400005, 0x0, 0x8f42020c, 0x24420001,
@@ -7115,8 +7120,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2c420001, 0x621825, 0x10600004, 0x3c020100,
0x94820002, 0x453821, 0x3c020100, 0x2c21024,
0x5040000e, 0xafa70064, 0x8fac0064, 0x10ec0008,
-0x3c050007, 0x3c040001, 0x24846998, 0x8fa60064,
-0x34a54000, 0xafa00010, 0xc002b17, 0xafa00014,
+0x3c050007, 0x3c040001, 0x24846908, 0x8fa60064,
+0x34a54000, 0xafa00010, 0xc002b3b, 0xafa00014,
0x8fab0064, 0x256b0004, 0xafab0064, 0x8f420080,
0x8fac0064, 0x4c102b, 0x1040002c, 0x32c28000,
0x10400034, 0x240b0003, 0x32c21000, 0x10400031,
@@ -7124,11 +7129,11 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2403ffbf, 0x283a024, 0x24420001, 0xaf420350,
0x10000173, 0x8f420350, 0x3c020800, 0x2c2b025,
0x2402ffbf, 0x282a024, 0x8f830128, 0x3c040001,
-0x24846960, 0x26620001, 0xafa20014, 0xafa30010,
-0x8f860120, 0x8f870124, 0x3c050007, 0xc002b17,
+0x248468d0, 0x26620001, 0xafa20014, 0xafa30010,
+0x8f860120, 0x8f870124, 0x3c050007, 0xc002b3b,
0x34a55300, 0x10000162, 0x0, 0x8ea20000,
-0x8ea30004, 0x3c040001, 0x24846978, 0xafb00010,
-0xafb10014, 0x8ea70018, 0x34a55900, 0xc002b17,
+0x8ea30004, 0x3c040001, 0x248468e8, 0xafb00010,
+0xafb10014, 0x8ea70018, 0x34a55900, 0xc002b3b,
0x603021, 0x10000156, 0x0, 0x8f420084,
0x8fab0064, 0x4b102b, 0x14400007, 0x3c020001,
0x2c21024, 0x10400004, 0x0, 0x240c0002,
@@ -7138,17 +7143,17 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x274b0054, 0x8f510054, 0x3403ecc0, 0xafab004c,
0x26220001, 0x304201ff, 0xafa20054, 0x111140,
0x431021, 0x1000006b, 0x2e2a821, 0x8f420044,
-0x8fac0064, 0x3c040001, 0x2484693c, 0xafac0014,
+0x8fac0064, 0x3c040001, 0x248468ac, 0xafac0014,
0xafa20010, 0x8f460054, 0x8f470050, 0x3c050007,
-0xc002b17, 0x34a54300, 0x8f430350, 0x2402ffbf,
+0xc002b3b, 0x34a54300, 0x8f430350, 0x2402ffbf,
0x282a024, 0x24630001, 0xaf430350, 0x10000124,
0x8f420350, 0x156c001d, 0x0, 0x8f430074,
0x8f420070, 0x1062000a, 0x274b0074, 0x8f510074,
0xafab004c, 0x26220001, 0x304203ff, 0xafa20054,
0x111140, 0x24426cc0, 0x1000004a, 0x2e2a821,
-0x8f420044, 0x8fac0064, 0x3c040001, 0x24846948,
+0x8f420044, 0x8fac0064, 0x3c040001, 0x248468b8,
0x3c050007, 0xafac0014, 0xafa20010, 0x8f460074,
-0x8f470070, 0x34a54500, 0x240b0001, 0xc002b17,
+0x8f470070, 0x34a54500, 0x240b0001, 0xc002b3b,
0xafab005c, 0x1000ffc3, 0x0, 0x8f430064,
0x8f420060, 0x1062001a, 0x274c0064, 0x8f510064,
0x8fab005c, 0xafac004c, 0x26220001, 0x304200ff,
@@ -7157,9 +7162,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x9442002a, 0x8fac0044, 0x8fab0064, 0x4b102b,
0x10400024, 0x25950020, 0x240c0001, 0x10000021,
0xa3ac0087, 0x24424cc0, 0x1000001e, 0x2e2a821,
-0x8f420044, 0x8fab0064, 0x3c040001, 0x24846954,
+0x8f420044, 0x8fab0064, 0x3c040001, 0x248468c4,
0xafab0014, 0xafa20010, 0x8f460064, 0x8f470060,
-0x3c050007, 0xc002b17, 0x34a54800, 0x3c020008,
+0x3c050007, 0xc002b3b, 0x34a54800, 0x3c020008,
0x2c21024, 0x1440ff61, 0x0, 0x8f420370,
0x240c0001, 0xafac005c, 0x24420001, 0xaf420370,
0x1000ff90, 0x8f420370, 0x27a30036, 0x131040,
@@ -7180,9 +7185,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x8f4200fc, 0x262102a, 0x10400016, 0x24030001,
0x1000001a, 0x306200ff, 0x8fac008c, 0x101040,
0x4c1021, 0x94470018, 0x101080, 0x4c1021,
-0xafbe0010, 0x8c420008, 0x3c040001, 0x2484696c,
+0xafbe0010, 0x8c420008, 0x3c040001, 0x248468dc,
0x3c050007, 0x8c430004, 0x8c420000, 0x34a55500,
-0x2003021, 0xc002b17, 0xafa30014, 0x10000039,
+0x2003021, 0xc002b3b, 0xafa30014, 0x10000039,
0x0, 0x8f420334, 0x1821, 0x24420001,
0xaf420334, 0x8f420334, 0x306200ff, 0x1040ff06,
0x8021, 0x8f430008, 0x2402fbff, 0x1260002d,
@@ -7399,7 +7404,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x822023, 0x94820000, 0x2028021, 0x3c020100,
0x2c21024, 0x1040000e, 0x0, 0x8faa002c,
0x31420004, 0x1040000a, 0x0, 0x9504000e,
-0x2642021, 0xc003ec4, 0x2484fffc, 0x3042ffff,
+0x2642021, 0xc003eec, 0x2484fffc, 0x3042ffff,
0x2228821, 0x111c02, 0x3222ffff, 0x628821,
0x8faa0024, 0x1518823, 0x111402, 0x2228821,
0x2308821, 0x111402, 0x2228821, 0x3231ffff,
@@ -7412,8 +7417,8 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa80018, 0x8f48010c, 0x1021, 0xa32821,
0xa3482b, 0x822021, 0x100f809, 0x892021,
0x1440000b, 0x0, 0x8f820128, 0x3c040001,
-0x248469a4, 0xafbe0014, 0xafa20010, 0x8f860124,
-0x8f870120, 0x3c050007, 0xc002b17, 0x34a59920,
+0x24846914, 0xafbe0014, 0xafa20010, 0x8f860124,
+0x8f870120, 0x3c050007, 0xc002b3b, 0x34a59920,
0x8f420368, 0x2442ffff, 0xaf420368, 0x8f420044,
0x8f430088, 0x24420001, 0x431024, 0xaf420044,
0x8faa0034, 0x8f440368, 0x24020001, 0x15420006,
@@ -7430,9 +7435,9 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xafa20010, 0xafa30014, 0xafa80018, 0x8f42010c,
0x40f809, 0x24c6001c, 0x14400011, 0x24020001,
0x3c010001, 0x370821, 0xa02240f2, 0x8f820124,
-0xafa20010, 0x8f820128, 0x3c040001, 0x2484691c,
+0xafa20010, 0x8f820128, 0x3c040001, 0x2484688c,
0xafa20014, 0x8f460044, 0x8f870120, 0x3c050009,
-0xc002b17, 0x34a51300, 0x1000000b, 0x0,
+0xc002b3b, 0x34a51300, 0x1000000b, 0x0,
0x8f420304, 0x24420001, 0xaf420304, 0x8f420304,
0x8f420044, 0xaf42007c, 0x3c010001, 0x370821,
0xa02040f2, 0xaf400078, 0x8f420318, 0x24420001,
@@ -7444,32 +7449,32 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf8200c8, 0x8f420138, 0xaf8200d0, 0x8f420138,
0xaf8200d4, 0x8f420138, 0x3e00008, 0xaf8200d8,
0x27bdffe0, 0x27840208, 0x24050200, 0xafbf0018,
-0xc002b9b, 0x24060008, 0x8c020204, 0xc003fea,
-0xaf820210, 0x3c020001, 0x8c426e14, 0x30420002,
+0xc002bbf, 0x24060008, 0x8c020204, 0xc004012,
+0xaf820210, 0x3c020001, 0x8c426d94, 0x30420002,
0x1040000e, 0x2021, 0x8c060248, 0x24020002,
-0x3c010001, 0xac226e18, 0xc005134, 0x24050002,
+0x3c010001, 0xac226d98, 0xc005104, 0x24050002,
0x2021, 0x8c060248, 0x24020001, 0x3c010001,
-0xac226e18, 0x10000011, 0x24050001, 0x8c060248,
-0x24020004, 0x3c010001, 0xac226e18, 0xc005134,
-0x24050004, 0x3c020001, 0x8c426e14, 0x30420001,
-0x10400008, 0x24020001, 0x3c010001, 0xac226e18,
-0x2021, 0x24050001, 0x3c06601b, 0xc005134,
-0x0, 0x3c040001, 0x24846a60, 0x8f420150,
+0xac226d98, 0x10000011, 0x24050001, 0x8c060248,
+0x24020004, 0x3c010001, 0xac226d98, 0xc005104,
+0x24050004, 0x3c020001, 0x8c426d94, 0x30420001,
+0x10400008, 0x24020001, 0x3c010001, 0xac226d98,
+0x2021, 0x24050001, 0x3c06601b, 0xc005104,
+0x0, 0x3c040001, 0x248469d0, 0x8f420150,
0x8f430154, 0x3c050008, 0x8f460158, 0x21640,
0x31940, 0x34630403, 0x431025, 0x633c0,
0x461025, 0xaf82021c, 0xafa00010, 0xafa00014,
-0x8f86021c, 0x34a50200, 0xc002b17, 0x3821,
-0x3c010001, 0xac206e10, 0x3c010001, 0xac206e28,
+0x8f86021c, 0x34a50200, 0xc002b3b, 0x3821,
+0x3c010001, 0xac206d90, 0x3c010001, 0xac206da8,
0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0,
0x3c050008, 0x34a50300, 0xafbf0018, 0xafa00010,
-0xafa00014, 0x8f860200, 0x3c040001, 0x24846a6c,
-0xc002b17, 0x3821, 0x8f420410, 0x24420001,
+0xafa00014, 0x8f860200, 0x3c040001, 0x248469dc,
+0xc002b3b, 0x3821, 0x8f420410, 0x24420001,
0xaf420410, 0x8f420410, 0x8fbf0018, 0x3e00008,
0x27bd0020, 0x27bdffd8, 0xafbf0020, 0xafb1001c,
0xafb00018, 0x8f4203a4, 0x24420001, 0xaf4203a4,
0x8f4203a4, 0x8f900220, 0x8f8200e0, 0xafa20010,
0x8f8200e4, 0xafa20014, 0x8f8600c4, 0x8f8700c8,
-0x3c040001, 0x24846a78, 0xc002b17, 0x2002821,
+0x3c040001, 0x248469e8, 0xc002b3b, 0x2002821,
0x3c044000, 0x2041024, 0x504000b4, 0x3c040100,
0x8f4203bc, 0x24420001, 0xaf4203bc, 0x8f4203bc,
0x8f8700c4, 0x8f8300c8, 0x8f420148, 0x671823,
@@ -7518,26 +7523,26 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0xaf4303cc, 0x10000039, 0x8f4203cc, 0x2041024,
0x1040000e, 0x3c110200, 0x8f4203a8, 0x24420001,
0xaf4203a8, 0x8f4203a8, 0x8f820220, 0x3c0308ff,
-0x3463ffff, 0x431024, 0x441025, 0xc003d87,
+0x3463ffff, 0x431024, 0x441025, 0xc003daf,
0xaf820220, 0x10000029, 0x0, 0x2111024,
0x50400008, 0x3c110400, 0x8f4203ac, 0x24420001,
-0xaf4203ac, 0xc003d87, 0x8f4203ac, 0x10000019,
+0xaf4203ac, 0xc003daf, 0x8f4203ac, 0x10000019,
0x0, 0x2111024, 0x1040001c, 0x0,
0x8f830224, 0x24021402, 0x14620009, 0x3c050008,
-0x3c040001, 0x24846a84, 0xafa00010, 0xafa00014,
-0x8f860224, 0x34a50500, 0xc002b17, 0x3821,
+0x3c040001, 0x248469f4, 0xafa00010, 0xafa00014,
+0x8f860224, 0x34a50500, 0xc002b3b, 0x3821,
0x8f4203b0, 0x24420001, 0xaf4203b0, 0x8f4203b0,
-0x8f820220, 0x2002021, 0x34420002, 0xc004ecc,
+0x8f820220, 0x2002021, 0x34420002, 0xc004e9c,
0xaf820220, 0x8f820220, 0x3c0308ff, 0x3463ffff,
0x431024, 0x511025, 0xaf820220, 0x8fbf0020,
0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0028,
-0x3e00008, 0x0, 0x3c020001, 0x8c426e28,
+0x3e00008, 0x0, 0x3c020001, 0x8c426da8,
0x27bdffb0, 0xafbf0048, 0xafbe0044, 0xafb50040,
0xafb3003c, 0xafb20038, 0xafb10034, 0x1040000f,
-0xafb00030, 0x3c040001, 0x24846a90, 0x3c050008,
+0xafb00030, 0x3c040001, 0x24846a00, 0x3c050008,
0xafa00010, 0xafa00014, 0x8f860220, 0x34a50600,
-0x24020001, 0x3c010001, 0xac206e28, 0x3c010001,
-0xac226e1c, 0xc002b17, 0x3821, 0x3c037fff,
+0x24020001, 0x3c010001, 0xac206da8, 0x3c010001,
+0xac226d9c, 0xc002b3b, 0x3821, 0x3c037fff,
0x8c020268, 0x3463ffff, 0x3c04fdff, 0x431024,
0xac020268, 0x8f420004, 0x3484ffff, 0x30420002,
0x10400092, 0x284a024, 0x3c040600, 0x34842000,
@@ -7546,7 +7551,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x240200ff, 0x13c20002, 0xafaa002c, 0x27c50001,
0x8c020228, 0xa09021, 0x1642000e, 0x1e38c0,
0x8f42033c, 0x24420001, 0xaf42033c, 0x8f42033c,
-0x8c020228, 0x3c040001, 0x24846a28, 0x3c050009,
+0x8c020228, 0x3c040001, 0x24846998, 0x3c050009,
0xafa00014, 0xafa20010, 0x8fa60020, 0x1000006d,
0x34a50500, 0xf71021, 0x8fa30020, 0x8fa40024,
0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
@@ -7560,7 +7565,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x2c4203e9, 0x1440ffe9, 0x0, 0x326200ff,
0x54400017, 0xaf520018, 0x8f420378, 0x24420001,
0xaf420378, 0x8f420378, 0x8f820120, 0x8faa002c,
-0xafa20010, 0x8f820124, 0x3c040001, 0x24846a34,
+0xafa20010, 0x8f820124, 0x3c040001, 0x248469a4,
0x3c050009, 0xafa20014, 0x8d460000, 0x10000035,
0x34a50600, 0x8f420308, 0x24130001, 0x24420001,
0xaf420308, 0x8f420308, 0x1000001e, 0x326200ff,
@@ -7574,21 +7579,21 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x326200ff, 0x14400011, 0x0, 0x8f420378,
0x24420001, 0xaf420378, 0x8f420378, 0x8f820120,
0x8faa002c, 0xafa20010, 0x8f820124, 0x3c040001,
-0x24846a3c, 0x3c050009, 0xafa20014, 0x8d460000,
-0x34a50700, 0xc002b17, 0x3c03821, 0x8f4202ec,
+0x248469ac, 0x3c050009, 0xafa20014, 0x8d460000,
+0x34a50700, 0xc002b3b, 0x3c03821, 0x8f4202ec,
0x24420001, 0xaf4202ec, 0x8f4202ec, 0x8fbf0048,
0x8fbe0044, 0x8fb50040, 0x8fb3003c, 0x8fb20038,
0x8fb10034, 0x8fb00030, 0x3e00008, 0x27bd0050,
-0x3c020001, 0x8c426e28, 0x27bdffe0, 0x1440000d,
-0xafbf0018, 0x3c040001, 0x24846a9c, 0x3c050008,
+0x3c020001, 0x8c426da8, 0x27bdffe0, 0x1440000d,
+0xafbf0018, 0x3c040001, 0x24846a0c, 0x3c050008,
0xafa00010, 0xafa00014, 0x8f860220, 0x34a50700,
-0x24020001, 0x3c010001, 0xac226e28, 0xc002b17,
+0x24020001, 0x3c010001, 0xac226da8, 0xc002b3b,
0x3821, 0x3c020004, 0x2c21024, 0x10400007,
0x0, 0x8f820220, 0x3c0308ff, 0x3463ffff,
0x431024, 0x34420008, 0xaf820220, 0x3c050001,
-0x8ca56e18, 0x24020001, 0x14a20007, 0x2021,
-0xc0052c7, 0x24050001, 0xac02026c, 0x8c03026c,
-0x10000006, 0x3c020007, 0xc0052c7, 0x2021,
+0x8ca56d98, 0x24020001, 0x14a20007, 0x2021,
+0xc00529b, 0x24050001, 0xac02026c, 0x8c03026c,
+0x10000006, 0x3c020007, 0xc00529b, 0x2021,
0xac020268, 0x8c030268, 0x3c020007, 0x621824,
0x3c020002, 0x5062000d, 0x3c0205f5, 0x43102b,
0x14400006, 0x3c020004, 0x3c020001, 0x10620009,
@@ -7636,7 +7641,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x90a20000, 0x822021, 0x41c02, 0x3082ffff,
0x622021, 0x41c02, 0x3082ffff, 0x622021,
0x3e00008, 0x3082ffff, 0x0, 0x8f820220,
-0x34420002, 0xaf820220, 0x3c020002, 0x8c429078,
+0x34420002, 0xaf820220, 0x3c020002, 0x8c428ff8,
0x30424000, 0x10400054, 0x24040001, 0x8f820200,
0x24067fff, 0x8f830200, 0x30450002, 0x2402fffd,
0x621824, 0xaf830200, 0xaf840204, 0x8f830054,
@@ -7683,1091 +7688,1069 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x43102b, 0x14400006, 0x3c026000, 0x3c024000,
0x10620008, 0x24020800, 0x10000008, 0x0,
0x10620004, 0x24020800, 0x10000004, 0x0,
-0x24020700, 0x3c010001, 0xac226e2c, 0x3e00008,
-0x0, 0x3c020001, 0x8c426e3c, 0x27bdffc8,
-0xafbf0034, 0xafb20030, 0xafb1002c, 0xafb00028,
-0x3c010001, 0x10400005, 0xac206e14, 0xc004dd1,
-0x0, 0x3c010001, 0xac206e3c, 0x8f830054,
+0x24020700, 0x3c010001, 0xac226dac, 0x3e00008,
+0x0, 0x3c020001, 0x8c426dbc, 0x27bdffd0,
+0xafbf002c, 0xafb20028, 0xafb10024, 0xafb00020,
+0x3c010001, 0x10400005, 0xac206d94, 0xc004d9e,
+0x0, 0x3c010001, 0xac206dbc, 0x8f830054,
0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
0x621023, 0x2c420065, 0x1440fffc, 0x0,
-0xc004dec, 0x0, 0x24040001, 0x2821,
-0x27a60020, 0x34028000, 0xc00450e, 0xa7a20020,
+0xc004db9, 0x0, 0x24040001, 0x2821,
+0x27a60018, 0x34028000, 0xc0045be, 0xa7a20018,
0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc0044cc, 0x27a60020,
+0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050001, 0xc0044cc, 0x27a60020,
+0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050002, 0xc0044cc, 0x27a60018,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
-0x24040001, 0x24050003, 0xc0044cc, 0x27a6001a,
-0x3c040001, 0x24846b70, 0x97a60020, 0x97a70018,
-0x97a2001a, 0x3c05000d, 0x34a50100, 0xafa00014,
-0xc002b17, 0xafa20010, 0x97a20020, 0x10400046,
-0x24036040, 0x97a2001a, 0x3042fff0, 0x1443000b,
-0x24020020, 0x97a30018, 0x1462000a, 0x24027830,
-0x24020003, 0x3c010001, 0xac226e14, 0x24020005,
-0x3c010001, 0x10000039, 0xac226fac, 0x97a30018,
-0x24027830, 0x1462000b, 0x24030010, 0x97a2001a,
-0x3042fff0, 0x14430007, 0x24020003, 0x3c010001,
-0xac226e14, 0x24020006, 0x3c010001, 0x1000002b,
-0xac226fac, 0x3c020001, 0x8c426e14, 0x97a30018,
-0x34420001, 0x3c010001, 0xac226e14, 0x24020015,
-0x1462000a, 0x0, 0x97a2001a, 0x3042fff0,
-0x3843f420, 0x2c630001, 0x3842f430, 0x2c420001,
-0x621825, 0x14600019, 0x24020003, 0x97a30018,
-0x24027810, 0x14620015, 0x24020002, 0x97a2001a,
-0x3042fff0, 0x14400011, 0x24020002, 0x1000000f,
-0x24020004, 0x3c020001, 0x8c426e14, 0x34420008,
-0x3c010001, 0xac226e14, 0x1000005e, 0x24020004,
-0x3c020001, 0x8c426e14, 0x34420004, 0x3c010001,
-0x100000af, 0xac226e14, 0x24020001, 0x3c010001,
-0xac226fb8, 0x3c020001, 0x8c426e14, 0x30420002,
-0x144000b2, 0x3c09fff0, 0x24020e00, 0xaf820238,
-0x8f840054, 0x8f820054, 0x24030008, 0x3c010001,
-0xac236e18, 0x10000002, 0x248401f4, 0x8f820054,
-0x821023, 0x2c4201f5, 0x1440fffc, 0x3c0200c8,
-0x344201fb, 0xaf820238, 0x8f830054, 0x8f820054,
-0x10000002, 0x246301f4, 0x8f820054, 0x621023,
-0x2c4201f5, 0x1440fffc, 0x8021, 0x24120001,
-0x24110009, 0xc0043d3, 0x0, 0x3c010001,
-0xac326e34, 0xc004498, 0x0, 0x3c020001,
-0x8c426e34, 0x1451fffb, 0x3c0200c8, 0x344201f6,
+0x24040001, 0x3c060001, 0x24c66f24, 0xc00457c,
+0x24050002, 0x8f830054, 0x8f820054, 0x10000002,
+0x24630064, 0x8f820054, 0x621023, 0x2c420065,
+0x1440fffc, 0x24040001, 0x24050003, 0x3c100001,
+0x26106f26, 0xc00457c, 0x2003021, 0x97a60018,
+0x3c070001, 0x94e76f24, 0x3c040001, 0x24846ae0,
+0xafa00014, 0x96020000, 0x3c05000d, 0x34a50100,
+0xc002b3b, 0xafa20010, 0x97a20018, 0x1040004d,
+0x24036040, 0x96020000, 0x3042fff0, 0x1443000c,
+0x24020020, 0x3c030001, 0x94636f24, 0x1462000b,
+0x24027830, 0x24020003, 0x3c010001, 0xac226d94,
+0x24020005, 0x3c010001, 0x1000003f, 0xac226f34,
+0x3c030001, 0x94636f24, 0x24027830, 0x1462000c,
+0x24030010, 0x3c020001, 0x94426f26, 0x3042fff0,
+0x14430007, 0x24020003, 0x3c010001, 0xac226d94,
+0x24020006, 0x3c010001, 0x1000002f, 0xac226f34,
+0x3c020001, 0x8c426d94, 0x3c030001, 0x94636f24,
+0x34420001, 0x3c010001, 0xac226d94, 0x24020015,
+0x1462000b, 0x0, 0x3c020001, 0x94426f26,
+0x3042fff0, 0x3843f420, 0x2c630001, 0x3842f430,
+0x2c420001, 0x621825, 0x1460001b, 0x24020003,
+0x3c030001, 0x94636f24, 0x24027810, 0x14620016,
+0x24020002, 0x3c020001, 0x94426f26, 0x3042fff0,
+0x14400011, 0x24020002, 0x1000000f, 0x24020004,
+0x3c020001, 0x8c426d94, 0x34420008, 0x3c010001,
+0xac226d94, 0x1000005e, 0x24020004, 0x3c020001,
+0x8c426d94, 0x34420004, 0x3c010001, 0x100000af,
+0xac226d94, 0x24020001, 0x3c010001, 0xac226f40,
+0x3c020001, 0x8c426d94, 0x30420002, 0x144000b2,
+0x3c09fff0, 0x24020e00, 0xaf820238, 0x8f840054,
+0x8f820054, 0x24030008, 0x3c010001, 0xac236d98,
+0x10000002, 0x248401f4, 0x8f820054, 0x821023,
+0x2c4201f5, 0x1440fffc, 0x3c0200c8, 0x344201fb,
0xaf820238, 0x8f830054, 0x8f820054, 0x10000002,
-0x2463000a, 0x8f820054, 0x621023, 0x2c42000b,
-0x1440fffc, 0x0, 0x8f820220, 0x24040001,
-0x34420002, 0xaf820220, 0x8f830200, 0x24057fff,
-0x2402fffd, 0x621824, 0xaf830200, 0xaf840204,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820224, 0x14440005, 0x34028000,
-0x42040, 0xa4102b, 0x1040fff0, 0x34028000,
-0x1082ffa0, 0x26100001, 0x2e020014, 0x1440ffcd,
-0x24020004, 0x3c010001, 0xac226e18, 0x8021,
-0x24120009, 0x3c11ffff, 0x36313f7f, 0xc0043d3,
-0x0, 0x24020001, 0x3c010001, 0xac226e34,
-0xc004498, 0x0, 0x3c020001, 0x8c426e34,
-0x1452fffb, 0x0, 0x8f820044, 0x511024,
-0x34425080, 0xaf820044, 0x8f830054, 0x8f820054,
-0x10000002, 0x2463000a, 0x8f820054, 0x621023,
-0x2c42000b, 0x1440fffc, 0x0, 0x8f820044,
-0x511024, 0x3442f080, 0xaf820044, 0x8f830054,
-0x8f820054, 0x10000002, 0x2463000a, 0x8f820054,
-0x621023, 0x2c42000b, 0x1440fffc, 0x0,
-0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
-0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
+0x246301f4, 0x8f820054, 0x621023, 0x2c4201f5,
+0x1440fffc, 0x8021, 0x24120001, 0x24110009,
+0xc004482, 0x0, 0x3c010001, 0xac326db4,
+0xc004547, 0x0, 0x3c020001, 0x8c426db4,
+0x1451fffb, 0x3c0200c8, 0x344201f6, 0xaf820238,
+0x8f830054, 0x8f820054, 0x10000002, 0x2463000a,
+0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc,
0x0, 0x8f820220, 0x24040001, 0x34420002,
0xaf820220, 0x8f830200, 0x24057fff, 0x2402fffd,
0x621824, 0xaf830200, 0xaf840204, 0x8f830054,
0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
0x621023, 0x2c420002, 0x1440fffc, 0x0,
0x8f820224, 0x14440005, 0x34028000, 0x42040,
-0xa4102b, 0x1040fff0, 0x34028000, 0x1082ff50,
-0x26100001, 0x2e020064, 0x1440ffb0, 0x0,
-0x3c020001, 0x8c426e14, 0x30420004, 0x14400007,
-0x3c09fff0, 0x8f820044, 0x3c03ffff, 0x34633f7f,
-0x431024, 0xaf820044, 0x3c09fff0, 0x3529bdc0,
-0x8f830054, 0x3c060001, 0x8cc66e14, 0x3c070001,
-0x8ce76fb8, 0x97a80018, 0x3c040001, 0x24846b70,
-0x24020001, 0x3c010001, 0xac226e1c, 0xafa80010,
-0x97a2001a, 0x3c05000d, 0x34a50100, 0x3c010001,
-0xac206e18, 0x691821, 0x3c010001, 0xac236fa8,
-0xc002b17, 0xafa20014, 0x8fbf0034, 0x8fb20030,
-0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0038,
-0x27bdffe8, 0x3c050001, 0x8ca56e18, 0x24060004,
-0x24020001, 0x14a20014, 0xafbf0010, 0x3c020002,
-0x8c42907c, 0x30428000, 0x10400005, 0x3c04000f,
-0x3c030001, 0x8c636fb8, 0x10000005, 0x34844240,
-0x3c040004, 0x3c030001, 0x8c636fb8, 0x348493e0,
-0x24020005, 0x14620016, 0x0, 0x3c04003d,
-0x10000013, 0x34840900, 0x3c020002, 0x8c429078,
-0x30428000, 0x10400005, 0x3c04001e, 0x3c030001,
-0x8c636fb8, 0x10000005, 0x34848480, 0x3c04000f,
-0x3c030001, 0x8c636fb8, 0x34844240, 0x24020005,
-0x14620003, 0x0, 0x3c04007a, 0x34841200,
-0x3c020001, 0x8c426fa8, 0x8f830054, 0x441021,
-0x431023, 0x44102b, 0x1440004b, 0x0,
-0x3c020001, 0x8c426e20, 0x14400047, 0x0,
-0x3c010001, 0x10c00025, 0xac206e30, 0x3c090001,
-0x8d296e14, 0x24070001, 0x3c044000, 0x3c080002,
-0x2508907c, 0x250afffc, 0x52842, 0x14a00002,
-0x24c6ffff, 0x24050008, 0xa91024, 0x10400010,
-0x0, 0x14a70008, 0x0, 0x8d020000,
-0x441024, 0x1040000a, 0x0, 0x3c010001,
-0x10000007, 0xac256e30, 0x8d420000, 0x441024,
-0x10400003, 0x0, 0x3c010001, 0xac276e30,
-0x3c020001, 0x8c426e30, 0x6182b, 0x2c420001,
-0x431024, 0x5440ffe5, 0x52842, 0x8f820054,
-0x3c030001, 0x8c636e30, 0x3c010001, 0xac226fa8,
-0x1060003a, 0x24020005, 0x3c030001, 0x8c636fb8,
-0x3c010001, 0xac256e18, 0x14620011, 0x24020001,
-0x3c020002, 0x8c429078, 0x3c032000, 0x431024,
-0x14400006, 0x24020001, 0x3c010001, 0xac206f98,
-0x3c010001, 0xac226e18, 0x24020001, 0x3c010001,
-0xac226ea4, 0x3c010001, 0xac226e24, 0x24020001,
-0x3c010001, 0xac226e1c, 0x3c020001, 0x8c426e30,
-0x1040001e, 0x0, 0x3c020001, 0x8c426e1c,
-0x10400008, 0x24020001, 0x3c010001, 0xac206e1c,
-0xaee204b8, 0x3c010001, 0xac206e9c, 0x3c010001,
-0xac226e54, 0x8ee304b8, 0x24020008, 0x10620005,
-0x24020001, 0xc004203, 0x0, 0x1000000b,
-0x0, 0x3c030001, 0x8c636e18, 0x10620007,
-0x2402000e, 0x3c030002, 0x8c639010, 0x10620003,
-0x0, 0xc004ecc, 0x8f840220, 0x8fbf0010,
-0x3e00008, 0x27bd0018, 0x27bdffe0, 0x3c03fdff,
-0x3c040001, 0x8c846e18, 0x3c020001, 0x8c426e40,
-0x3463ffff, 0x283a024, 0xafbf001c, 0x14820006,
-0xafb00018, 0x8ee304b8, 0x3c020001, 0x8c426e44,
-0x10620006, 0x0, 0x8ee204b8, 0x3c010001,
-0xac246e40, 0x3c010001, 0xac226e44, 0x3c030001,
-0x8c636e18, 0x24020002, 0x10620167, 0x2c620003,
-0x10400005, 0x24020001, 0x1062000a, 0x0,
-0x100001ab, 0x0, 0x24020004, 0x10620081,
-0x24020008, 0x106200d5, 0x24020001, 0x100001a4,
-0x0, 0x8ee204b8, 0x2443ffff, 0x2c620008,
-0x104001a1, 0x31080, 0x3c010001, 0x220821,
-0x8c226b88, 0x400008, 0x0, 0x3c030001,
-0x8c636fb8, 0x24020005, 0x14620010, 0x0,
-0x3c020001, 0x8c426e24, 0x10400008, 0x24020003,
-0xc0043d3, 0x0, 0x24020002, 0xaee204b8,
-0x3c010001, 0x10000002, 0xac206e24, 0xaee204b8,
-0x3c010001, 0x10000188, 0xac206db0, 0xc0043d3,
-0x0, 0x3c020001, 0x8c426e24, 0x3c010001,
-0xac206db0, 0x14400145, 0x24020002, 0x10000163,
-0x24020007, 0x24020001, 0x3c010001, 0xc00454f,
-0xac226e50, 0x3c030001, 0x8c636e50, 0x10000144,
-0x24020011, 0x3c020001, 0x8c426fb8, 0x24100005,
-0x10500007, 0x0, 0x3c050001, 0x8ca56e18,
-0x3c060002, 0x8cc6907c, 0xc005134, 0x2021,
-0x3c010001, 0xac206e24, 0x10000167, 0xaef004b8,
-0x3c040001, 0x24846b7c, 0x3c05000f, 0x34a50100,
-0x3021, 0x3821, 0xafa00010, 0xc002b17,
-0xafa00014, 0x1000015c, 0x0, 0x8f820220,
-0x3c030004, 0x431024, 0x1440013c, 0x24020007,
-0x8f830054, 0x3c020001, 0x8c426fa0, 0x2463d8f0,
-0x431023, 0x2c422710, 0x1440014f, 0x24020001,
-0x1000014b, 0x0, 0x3c050001, 0x8ca56e18,
-0xc0052c7, 0x2021, 0xc00553d, 0x2021,
-0x3c030002, 0x8c639074, 0x4610141, 0x24020001,
-0x3c020008, 0x621024, 0x10400006, 0x0,
-0x8f820214, 0x3c03ffff, 0x431024, 0x10000005,
-0x3442251f, 0x8f820214, 0x3c03ffff, 0x431024,
-0x3442241f, 0xaf820214, 0x8f820220, 0x3c030200,
-0x283a025, 0x34420002, 0xaf820220, 0x24020008,
-0xc003e45, 0xaee204b8, 0x3c010001, 0x1000012a,
-0xac206ea0, 0x8ee204b8, 0x2443ffff, 0x2c620008,
-0x10400125, 0x31080, 0x3c010001, 0x220821,
-0x8c226ba8, 0x400008, 0x0, 0xc004498,
-0x0, 0x3c030001, 0x8c636e34, 0x100000e8,
-0x24020009, 0x3c020002, 0x8c429078, 0x30424000,
-0x10400004, 0x0, 0x8f820044, 0x10000006,
-0x3442f080, 0x8f820044, 0x3c03ffff, 0x34633f7f,
-0x431024, 0x3442a080, 0xaf820044, 0x8f830054,
-0x100000ea, 0x24020004, 0x8f830054, 0x3c020001,
-0x8c426fa0, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400101, 0x24020005, 0x100000d8, 0x0,
+0xa4102b, 0x1040fff0, 0x34028000, 0x1082ffa0,
+0x26100001, 0x2e020014, 0x1440ffcd, 0x24020004,
+0x3c010001, 0xac226d98, 0x8021, 0x24120009,
+0x3c11ffff, 0x36313f7f, 0xc004482, 0x0,
+0x24020001, 0x3c010001, 0xac226db4, 0xc004547,
+0x0, 0x3c020001, 0x8c426db4, 0x1452fffb,
+0x0, 0x8f820044, 0x511024, 0x34425080,
+0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
+0x2463000a, 0x8f820054, 0x621023, 0x2c42000b,
+0x1440fffc, 0x0, 0x8f820044, 0x511024,
+0x3442f080, 0xaf820044, 0x8f830054, 0x8f820054,
+0x10000002, 0x2463000a, 0x8f820054, 0x621023,
+0x2c42000b, 0x1440fffc, 0x0, 0x8f820220,
+0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
+0x8f820054, 0x10000002, 0x24630064, 0x8f820054,
+0x621023, 0x2c420065, 0x1440fffc, 0x0,
+0x8f820220, 0x24040001, 0x34420002, 0xaf820220,
+0x8f830200, 0x24057fff, 0x2402fffd, 0x621824,
+0xaf830200, 0xaf840204, 0x8f830054, 0x8f820054,
+0x10000002, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820224,
+0x14440005, 0x34028000, 0x42040, 0xa4102b,
+0x1040fff0, 0x34028000, 0x1082ff50, 0x26100001,
+0x2e020064, 0x1440ffb0, 0x0, 0x3c020001,
+0x8c426d94, 0x30420004, 0x14400007, 0x3c09fff0,
+0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024,
+0xaf820044, 0x3c09fff0, 0x3529bdc0, 0x3c060001,
+0x8cc66d94, 0x3c040001, 0x24846ae0, 0x24020001,
+0x3c010001, 0xac226d9c, 0x8f820054, 0x3c070001,
+0x8ce76f40, 0x3c030001, 0x94636f24, 0x3c080001,
+0x95086f26, 0x3c05000d, 0x34a50100, 0x3c010001,
+0xac206d98, 0x491021, 0x3c010001, 0xac226f30,
+0xafa30010, 0xc002b3b, 0xafa80014, 0x8fbf002c,
+0x8fb20028, 0x8fb10024, 0x8fb00020, 0x3e00008,
+0x27bd0030, 0x27bdffe8, 0x3c050001, 0x8ca56d98,
+0x24060004, 0x24020001, 0x14a20014, 0xafbf0010,
+0x3c020002, 0x8c428ffc, 0x30428000, 0x10400005,
+0x3c04000f, 0x3c030001, 0x8c636f40, 0x10000005,
+0x34844240, 0x3c040004, 0x3c030001, 0x8c636f40,
+0x348493e0, 0x24020005, 0x14620016, 0x0,
+0x3c04003d, 0x10000013, 0x34840900, 0x3c020002,
+0x8c428ff8, 0x30428000, 0x10400005, 0x3c04001e,
+0x3c030001, 0x8c636f40, 0x10000005, 0x34848480,
+0x3c04000f, 0x3c030001, 0x8c636f40, 0x34844240,
+0x24020005, 0x14620003, 0x0, 0x3c04007a,
+0x34841200, 0x3c020001, 0x8c426f30, 0x8f830054,
+0x441021, 0x431023, 0x44102b, 0x1440004c,
+0x0, 0x3c020001, 0x8c426da0, 0x14400048,
+0x0, 0x3c010001, 0x10c00025, 0xac206db0,
+0x3c090001, 0x8d296d94, 0x24070001, 0x3c044000,
+0x3c080002, 0x25088ffc, 0x250afffc, 0x52842,
+0x14a00002, 0x24c6ffff, 0x24050008, 0xa91024,
+0x10400010, 0x0, 0x14a70008, 0x0,
+0x8d020000, 0x441024, 0x1040000a, 0x0,
+0x3c010001, 0x10000007, 0xac256db0, 0x8d420000,
+0x441024, 0x10400003, 0x0, 0x3c010001,
+0xac276db0, 0x3c020001, 0x8c426db0, 0x6182b,
+0x2c420001, 0x431024, 0x5440ffe5, 0x52842,
+0x8f820054, 0x3c030001, 0x8c636db0, 0x3c010001,
+0xac226f30, 0x1060003b, 0x24020005, 0x3c030001,
+0x8c636f40, 0x3c010001, 0xac256d98, 0x14620012,
+0x24020001, 0x3c020002, 0x8c428ff8, 0x3c032000,
+0x34635000, 0x431024, 0x14400006, 0x24020001,
+0x3c010001, 0xac206f1c, 0x3c010001, 0xac226d98,
+0x24020001, 0x3c010001, 0xac226e24, 0x3c010001,
+0xac226da4, 0x24020001, 0x3c010001, 0xac226d9c,
+0x3c020001, 0x8c426db0, 0x1040001e, 0x0,
+0x3c020001, 0x8c426d9c, 0x10400008, 0x24020001,
+0x3c010001, 0xac206d9c, 0xaee204b8, 0x3c010001,
+0xac206e1c, 0x3c010001, 0xac226dd4, 0x8ee304b8,
+0x24020008, 0x10620005, 0x24020001, 0xc004239,
+0x0, 0x1000000b, 0x0, 0x3c030001,
+0x8c636d98, 0x10620007, 0x2402000e, 0x3c030002,
+0x8c638f90, 0x10620003, 0x0, 0xc004e9c,
+0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018,
+0x27bdffe0, 0x3c03fdff, 0x3c040001, 0x8c846d98,
+0x3c020001, 0x8c426dc0, 0x3463ffff, 0x283a024,
+0x14820006, 0xafbf0018, 0x8ee304b8, 0x3c020001,
+0x8c426dc4, 0x10620006, 0x0, 0x8ee204b8,
+0x3c010001, 0xac246dc0, 0x3c010001, 0xac226dc4,
+0x3c030001, 0x8c636d98, 0x24020002, 0x1062019c,
+0x2c620003, 0x10400005, 0x24020001, 0x1062000a,
+0x0, 0x10000226, 0x0, 0x24020004,
+0x106200b6, 0x24020008, 0x1062010a, 0x24020001,
+0x1000021f, 0x0, 0x8ee204b8, 0x2443ffff,
+0x2c620008, 0x1040021c, 0x31080, 0x3c010001,
+0x220821, 0x8c226af8, 0x400008, 0x0,
+0x3c030001, 0x8c636f40, 0x24020005, 0x14620010,
+0x0, 0x3c020001, 0x8c426da4, 0x10400008,
+0x24020003, 0xc004482, 0x0, 0x24020002,
+0xaee204b8, 0x3c010001, 0x10000002, 0xac206da4,
+0xaee204b8, 0x3c010001, 0x10000203, 0xac206d30,
+0xc004482, 0x0, 0x3c020001, 0x8c426da4,
+0x3c010001, 0xac206d30, 0x1440017a, 0x24020002,
+0x1000019d, 0x24020007, 0x3c030001, 0x8c636f40,
+0x24020005, 0x14620003, 0x24020001, 0x3c010001,
+0xac226dd0, 0xc0045ff, 0x0, 0x3c030001,
+0x8c636dd0, 0x10000174, 0x24020011, 0x3c050001,
+0x8ca56d98, 0x3c060002, 0x8cc68ffc, 0xc005104,
+0x2021, 0x24020005, 0x3c010001, 0xac206da4,
+0x100001e1, 0xaee204b8, 0x3c040001, 0x24846aec,
+0x3c05000f, 0x34a50100, 0x3021, 0x3821,
+0xafa00010, 0xc002b3b, 0xafa00014, 0x100001d6,
+0x0, 0x8f820220, 0x3c030004, 0x431024,
+0x14400175, 0x24020007, 0x8f830054, 0x3c020001,
+0x8c426f28, 0x2463d8f0, 0x431023, 0x2c422710,
+0x14400003, 0x24020001, 0x3c010001, 0xac226d9c,
+0x3c020002, 0x8c428ffc, 0x30425000, 0x104001c2,
+0x0, 0x8f820220, 0x30428000, 0x1040017d,
+0x0, 0x10000175, 0x0, 0x3c050001,
+0x8ca56d98, 0xc00529b, 0x2021, 0xc00551b,
+0x2021, 0x3c030002, 0x8c638ff4, 0x46101b0,
+0x24020001, 0x3c020008, 0x621024, 0x10400006,
+0x0, 0x8f820214, 0x3c03ffff, 0x431024,
+0x10000005, 0x3442251f, 0x8f820214, 0x3c03ffff,
+0x431024, 0x3442241f, 0xaf820214, 0x8f820220,
+0x3c030200, 0x34420002, 0xaf820220, 0x24020008,
+0xaee204b8, 0x8f820220, 0x283a025, 0x3c030004,
+0x431024, 0x14400016, 0x0, 0x3c020002,
+0x8c428ffc, 0x30425000, 0x1040000d, 0x0,
+0x8f820220, 0x30428000, 0x10400006, 0x0,
+0x8f820220, 0x3c03ffff, 0x34637fff, 0x10000003,
+0x431024, 0x8f820220, 0x34428000, 0xaf820220,
0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
-0xaf800204, 0x3c010002, 0x100000d6, 0xac209060,
-0x8f830054, 0x3c020001, 0x8c426fa0, 0x2463fff6,
-0x431023, 0x2c42000a, 0x144000ef, 0x24020007,
-0x100000d2, 0x0, 0xc003f28, 0x0,
-0x104000e7, 0x24020001, 0x8f820214, 0x3c03ffff,
-0x3c040001, 0x8c846f98, 0x431024, 0x3442251f,
-0xaf820214, 0x24020008, 0x10800005, 0xaee204b8,
-0x3c020001, 0x8c426ec4, 0x10400064, 0x24020001,
-0x8f820220, 0x3c030008, 0x431024, 0x1040006a,
-0x3c020200, 0x10000078, 0x0, 0x8ee204b8,
-0x2443ffff, 0x2c620007, 0x104000cf, 0x31080,
-0x3c010001, 0x220821, 0x8c226bc8, 0x400008,
-0x0, 0xc003d87, 0x0, 0x3c010001,
-0xac206e1c, 0xaf800204, 0x3c010002, 0xc0043d3,
-0xac209060, 0x24020001, 0x3c010001, 0xac226e34,
-0x24020002, 0x100000bc, 0xaee204b8, 0xc004498,
-0x0, 0x3c030001, 0x8c636e34, 0x10000084,
-0x24020009, 0x3c020002, 0x8c429078, 0x30424000,
-0x10400003, 0x3c0200c8, 0x10000002, 0x344201f6,
-0x344201fe, 0xaf820238, 0x8f830054, 0x1000008b,
-0x24020004, 0x8f830054, 0x3c020001, 0x8c426fa0,
-0x2463d8f0, 0x431023, 0x2c422710, 0x144000a2,
-0x24020005, 0x10000079, 0x0, 0x8f820220,
-0x3c03f700, 0x431025, 0xaf820220, 0xaf800204,
-0x3c010002, 0x10000077, 0xac209060, 0x8f830054,
-0x3c020001, 0x8c426fa0, 0x2463fff6, 0x431023,
-0x2c42000a, 0x14400090, 0x24020007, 0x10000073,
-0x0, 0xc003f28, 0x0, 0x10400088,
-0x24020001, 0x8f820214, 0x3c03ffff, 0x3c040001,
-0x8c846f98, 0x431024, 0x3442251f, 0xaf820214,
-0x24020008, 0x1080000f, 0xaee204b8, 0x3c020001,
-0x8c426ec4, 0x1440000b, 0x0, 0x8f820220,
-0x34420002, 0xaf820220, 0x24020001, 0x3c010002,
-0xac229010, 0xc004ecc, 0x8f840220, 0x10000016,
-0x0, 0x8f820220, 0x3c030008, 0x431024,
-0x14400011, 0x3c020200, 0x282a025, 0x2402000e,
-0x3c010002, 0xac229010, 0xc00553d, 0x2021,
-0x8f820220, 0x34420002, 0xc003e45, 0xaf820220,
-0x3c050001, 0x8ca56e18, 0xc0052c7, 0x2021,
-0x1000005d, 0x0, 0x3c020001, 0x8c426ec4,
-0x10400059, 0x0, 0x3c020001, 0x8c426ec0,
-0x2442ffff, 0x3c010001, 0xac226ec0, 0x14400052,
-0x24020002, 0x3c010001, 0xac206ec4, 0x3c010001,
-0x1000004d, 0xac226ec0, 0x8ee204b8, 0x2443ffff,
-0x2c620007, 0x10400048, 0x31080, 0x3c010001,
-0x220821, 0x8c226be8, 0x400008, 0x0,
-0x3c020001, 0x8c426e24, 0x10400024, 0x24020007,
-0xc0043d3, 0x0, 0x24020002, 0xaee204b8,
-0x3c010001, 0x10000038, 0xac206e24, 0xc0048b3,
-0x0, 0x3c030001, 0x8c636e54, 0x24020006,
-0x14620031, 0x24020003, 0x1000002f, 0xaee204b8,
-0x3c050001, 0x8ca56e18, 0x3c060002, 0x8cc69078,
-0xc005134, 0x2021, 0x24020005, 0x10000026,
-0xaee204b8, 0x8f820220, 0x3c03f700, 0x431025,
-0xaf820220, 0x8f830054, 0x24020006, 0xaee204b8,
-0x3c010001, 0x1000001c, 0xac236fa0, 0x1000001a,
-0xaee204b8, 0x3c050001, 0x8ca56e18, 0xc0052c7,
-0x2021, 0xc00553d, 0x2021, 0x3c020002,
-0x8c429070, 0x441000e, 0x24020001, 0x8f820214,
+0x3c030001, 0x8c636f40, 0x24020005, 0x1462000a,
+0x0, 0x3c020001, 0x94426f26, 0x24429fbc,
+0x2c420004, 0x10400004, 0x24040018, 0x24050002,
+0xc004ddb, 0x24060020, 0xc003e6d, 0x0,
+0x3c010001, 0x10000170, 0xac206e20, 0x8ee204b8,
+0x2443ffff, 0x2c620008, 0x1040016b, 0x31080,
+0x3c010001, 0x220821, 0x8c226b18, 0x400008,
+0x0, 0xc004547, 0x0, 0x3c030001,
+0x8c636db4, 0x100000e8, 0x24020009, 0x3c020002,
+0x8c428ff8, 0x30424000, 0x10400004, 0x0,
+0x8f820044, 0x10000006, 0x3442f080, 0x8f820044,
+0x3c03ffff, 0x34633f7f, 0x431024, 0x3442a080,
+0xaf820044, 0x8f830054, 0x100000ea, 0x24020004,
+0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0,
+0x431023, 0x2c422710, 0x14400147, 0x24020005,
+0x100000d8, 0x0, 0x8f820220, 0x3c03f700,
+0x431025, 0xaf820220, 0xaf800204, 0x3c010002,
+0x100000d6, 0xac208fe0, 0x8f830054, 0x3c020001,
+0x8c426f28, 0x2463fff6, 0x431023, 0x2c42000a,
+0x14400135, 0x24020007, 0x100000d7, 0x0,
+0xc003f50, 0x0, 0x1040012d, 0x24020001,
+0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c846f1c,
+0x431024, 0x3442251f, 0xaf820214, 0x24020008,
+0x10800005, 0xaee204b8, 0x3c020001, 0x8c426e44,
+0x10400064, 0x24020001, 0x8f820220, 0x3c030008,
+0x431024, 0x1040006a, 0x3c020200, 0x10000078,
+0x0, 0x8ee204b8, 0x2443ffff, 0x2c620007,
+0x10400115, 0x31080, 0x3c010001, 0x220821,
+0x8c226b38, 0x400008, 0x0, 0xc003daf,
+0x0, 0x3c010001, 0xac206d9c, 0xaf800204,
+0x3c010002, 0xc004482, 0xac208fe0, 0x24020001,
+0x3c010001, 0xac226db4, 0x24020002, 0x10000102,
+0xaee204b8, 0xc004547, 0x0, 0x3c030001,
+0x8c636db4, 0x10000084, 0x24020009, 0x3c020002,
+0x8c428ff8, 0x30424000, 0x10400003, 0x3c0200c8,
+0x10000002, 0x344201f6, 0x344201fe, 0xaf820238,
+0x8f830054, 0x1000008b, 0x24020004, 0x8f830054,
+0x3c020001, 0x8c426f28, 0x2463d8f0, 0x431023,
+0x2c422710, 0x144000e8, 0x24020005, 0x10000079,
+0x0, 0x8f820220, 0x3c03f700, 0x431025,
+0xaf820220, 0xaf800204, 0x3c010002, 0x10000077,
+0xac208fe0, 0x8f830054, 0x3c020001, 0x8c426f28,
+0x2463fff6, 0x431023, 0x2c42000a, 0x144000d6,
+0x24020007, 0x10000078, 0x0, 0xc003f50,
+0x0, 0x104000ce, 0x24020001, 0x8f820214,
+0x3c03ffff, 0x3c040001, 0x8c846f1c, 0x431024,
+0x3442251f, 0xaf820214, 0x24020008, 0x1080000f,
+0xaee204b8, 0x3c020001, 0x8c426e44, 0x1440000b,
+0x0, 0x8f820220, 0x34420002, 0xaf820220,
+0x24020001, 0x3c010002, 0xac228f90, 0xc004e9c,
+0x8f840220, 0x10000016, 0x0, 0x8f820220,
+0x3c030008, 0x431024, 0x14400011, 0x3c020200,
+0x282a025, 0x2402000e, 0x3c010002, 0xac228f90,
+0xc00551b, 0x2021, 0x8f820220, 0x34420002,
+0xc003e6d, 0xaf820220, 0x3c050001, 0x8ca56d98,
+0xc00529b, 0x2021, 0x100000a3, 0x0,
+0x3c020001, 0x8c426e44, 0x1040009f, 0x0,
+0x3c020001, 0x8c426e40, 0x2442ffff, 0x3c010001,
+0xac226e40, 0x14400098, 0x24020002, 0x3c010001,
+0xac206e44, 0x3c010001, 0x10000093, 0xac226e40,
+0x8ee204b8, 0x2443ffff, 0x2c620007, 0x1040008e,
+0x31080, 0x3c010001, 0x220821, 0x8c226b58,
+0x400008, 0x0, 0x3c020001, 0x8c426da4,
+0x10400018, 0x24020005, 0xc004482, 0x0,
+0x24020002, 0xaee204b8, 0x3c010001, 0x1000007e,
+0xac206da4, 0xc004963, 0x0, 0x3c030001,
+0x8c636dd4, 0x24020006, 0x14620077, 0x24020003,
+0x10000075, 0xaee204b8, 0x3c050001, 0x8ca56d98,
+0x3c060002, 0x8cc68ff8, 0xc005104, 0x2021,
+0x24020005, 0x1000006c, 0xaee204b8, 0x8f820220,
+0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
+0x24020006, 0xaee204b8, 0x3c010001, 0x10000062,
+0xac236f28, 0x8f820220, 0x3c030004, 0x431024,
+0x10400003, 0x24020007, 0x1000005b, 0xaee204b8,
+0x8f830054, 0x3c020001, 0x8c426f28, 0x2463d8f0,
+0x431023, 0x2c422710, 0x14400003, 0x24020001,
+0x3c010001, 0xac226d9c, 0x3c020002, 0x8c428ff8,
+0x30425000, 0x1040004c, 0x0, 0x8f820220,
+0x30428000, 0x10400007, 0x0, 0x8f820220,
+0x3c03ffff, 0x34637fff, 0x431024, 0x10000042,
+0xaf820220, 0x8f820220, 0x34428000, 0x1000003e,
+0xaf820220, 0x3c050001, 0x8ca56d98, 0xc00529b,
+0x2021, 0xc00551b, 0x2021, 0x3c020002,
+0x8c428ff0, 0x4410032, 0x24020001, 0x8f820214,
0x3c03ffff, 0x431024, 0x3442251f, 0xaf820214,
0x24020008, 0xaee204b8, 0x8f820220, 0x34420002,
-0xc003e45, 0xaf820220, 0x10000003, 0x0,
-0x3c010001, 0xac226e1c, 0x8fbf001c, 0x8fb00018,
-0x3e00008, 0x27bd0020, 0x8f820200, 0x8f820220,
-0x8f820220, 0x34420004, 0xaf820220, 0x8f820200,
-0x3c050001, 0x8ca56e18, 0x34420004, 0xaf820200,
-0x24020002, 0x10a2004b, 0x2ca20003, 0x10400005,
-0x24020001, 0x10a2000a, 0x0, 0x100000b1,
-0x0, 0x24020004, 0x10a20072, 0x24020008,
-0x10a20085, 0x3c02f0ff, 0x100000aa, 0x0,
+0xaf820220, 0x8f820220, 0x3c030004, 0x431024,
+0x14400016, 0x0, 0x3c020002, 0x8c428ff8,
+0x30425000, 0x1040000d, 0x0, 0x8f820220,
+0x30428000, 0x10400006, 0x0, 0x8f820220,
+0x3c03ffff, 0x34637fff, 0x10000003, 0x431024,
+0x8f820220, 0x34428000, 0xaf820220, 0x8f820220,
+0x3c03f700, 0x431025, 0xaf820220, 0x3c020001,
+0x94426f26, 0x24429fbc, 0x2c420004, 0x10400004,
+0x24040018, 0x24050002, 0xc004ddb, 0x24060020,
+0xc003e6d, 0x0, 0x10000003, 0x0,
+0x3c010001, 0xac226d9c, 0x8fbf0018, 0x3e00008,
+0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220,
+0x34420004, 0xaf820220, 0x8f820200, 0x3c050001,
+0x8ca56d98, 0x34420004, 0xaf820200, 0x24020002,
+0x10a2004b, 0x2ca20003, 0x10400005, 0x24020001,
+0x10a2000a, 0x0, 0x100000b1, 0x0,
+0x24020004, 0x10a20072, 0x24020008, 0x10a20085,
+0x3c02f0ff, 0x100000aa, 0x0, 0x8f830050,
+0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c846f40,
+0x621824, 0x3c020700, 0x621825, 0x24020e00,
+0x2484fffb, 0x2c840002, 0xaf830050, 0xaf850200,
+0xaf850220, 0x14800006, 0xaf820238, 0x8f820044,
+0x3c03ffff, 0x34633f7f, 0x431024, 0xaf820044,
+0x3c030001, 0x8c636f40, 0x24020005, 0x14620004,
+0x0, 0x8f820044, 0x34425000, 0xaf820044,
+0x3c020001, 0x8c426d88, 0x3c030001, 0x8c636f40,
+0x34420022, 0x2463fffc, 0x2c630002, 0x1460000c,
+0xaf820200, 0x3c020001, 0x8c426dac, 0x3c030001,
+0x8c636d90, 0x3c040001, 0x8c846d8c, 0x34428000,
+0x621825, 0x641825, 0x1000000a, 0x34620002,
+0x3c020001, 0x8c426d90, 0x3c030001, 0x8c636dac,
+0x3c040001, 0x8c846d8c, 0x431025, 0x441025,
+0x34420002, 0xaf820220, 0x1000002f, 0x24020001,
+0x24020e01, 0xaf820238, 0x8f830050, 0x3c02f0ff,
+0x3442ffff, 0x3c040001, 0x8c846f1c, 0x621824,
+0x3c020d00, 0x621825, 0x24020001, 0xaf830050,
+0xaf820200, 0xaf820220, 0x10800005, 0x3c033f00,
+0x3c020001, 0x8c426d80, 0x10000004, 0x34630070,
+0x3c020001, 0x8c426d80, 0x34630072, 0x431025,
+0xaf820200, 0x3c030001, 0x8c636d84, 0x3c02f700,
+0x621825, 0x3c020001, 0x8c426d90, 0x3c040001,
+0x8c846dac, 0x3c050001, 0x8ca56f40, 0x431025,
+0x441025, 0xaf820220, 0x24020005, 0x14a20006,
+0x24020001, 0x8f820044, 0x2403afff, 0x431024,
+0xaf820044, 0x24020001, 0x1000003d, 0xaf820238,
0x8f830050, 0x3c02f0ff, 0x3442ffff, 0x3c040001,
-0x8c846fb8, 0x621824, 0x3c020700, 0x621825,
-0x24020e00, 0x2484fffb, 0x2c840002, 0xaf830050,
-0xaf850200, 0xaf850220, 0x14800006, 0xaf820238,
-0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024,
-0xaf820044, 0x3c030001, 0x8c636fb8, 0x24020005,
-0x14620004, 0x0, 0x8f820044, 0x34425000,
-0xaf820044, 0x3c020001, 0x8c426e08, 0x3c030001,
-0x8c636fb8, 0x34420022, 0x2463fffc, 0x2c630002,
-0x1460000c, 0xaf820200, 0x3c020001, 0x8c426e2c,
-0x3c030001, 0x8c636e10, 0x3c040001, 0x8c846e0c,
-0x34428000, 0x621825, 0x641825, 0x1000000a,
-0x34620002, 0x3c020001, 0x8c426e10, 0x3c030001,
-0x8c636e2c, 0x3c040001, 0x8c846e0c, 0x431025,
-0x441025, 0x34420002, 0xaf820220, 0x1000002f,
-0x24020001, 0x24020e01, 0xaf820238, 0x8f830050,
-0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c846f98,
-0x621824, 0x3c020d00, 0x621825, 0x24020001,
-0xaf830050, 0xaf820200, 0xaf820220, 0x10800005,
-0x3c033f00, 0x3c020001, 0x8c426e00, 0x10000004,
-0x34630070, 0x3c020001, 0x8c426e00, 0x34630072,
-0x431025, 0xaf820200, 0x3c030001, 0x8c636e04,
-0x3c02f700, 0x621825, 0x3c020001, 0x8c426e10,
-0x3c040001, 0x8c846e2c, 0x3c050001, 0x8ca56fb8,
-0x431025, 0x441025, 0xaf820220, 0x24020005,
-0x14a20006, 0x24020001, 0x8f820044, 0x2403afff,
-0x431024, 0xaf820044, 0x24020001, 0x1000003d,
-0xaf820238, 0x8f830050, 0x3c02f0ff, 0x3442ffff,
-0x3c040001, 0x8c846f98, 0x621824, 0x3c020a00,
-0x621825, 0x24020001, 0xaf830050, 0xaf820200,
-0x1080001e, 0xaf820220, 0x3c020001, 0x8c426ec4,
-0x1440001a, 0x3c033f00, 0x3c020001, 0x8c426e00,
-0x1000001a, 0x346300e0, 0x8f830050, 0x3c040001,
-0x8c846f98, 0x3442ffff, 0x621824, 0x1080000f,
-0xaf830050, 0x3c020001, 0x8c426ec4, 0x1440000b,
-0x3c043f00, 0x3c030001, 0x8c636e00, 0x348400e0,
-0x24020001, 0xaf820200, 0xaf820220, 0x641825,
-0xaf830200, 0x10000008, 0x3c05f700, 0x3c020001,
-0x8c426e00, 0x3c033f00, 0x346300e2, 0x431025,
-0xaf820200, 0x3c05f700, 0x34a58000, 0x3c030001,
-0x8c636e04, 0x3c020001, 0x8c426e10, 0x3c040001,
-0x8c846e2c, 0x651825, 0x431025, 0x441025,
-0xaf820220, 0x3e00008, 0x0, 0x3c030001,
-0x8c636e34, 0x3c020001, 0x8c426e38, 0x10620003,
-0x24020002, 0x3c010001, 0xac236e38, 0x1062001d,
-0x2c620003, 0x10400025, 0x24020001, 0x14620023,
-0x24020004, 0x3c030001, 0x8c636e18, 0x10620006,
-0x24020008, 0x1462000c, 0x3c0200c8, 0x344201fb,
-0x10000009, 0xaf820238, 0x24020e01, 0xaf820238,
-0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024,
-0x34420080, 0xaf820044, 0x8f830054, 0x24020002,
-0x3c010001, 0xac226e34, 0x3c010001, 0x1000000b,
-0xac236fa4, 0x8f830054, 0x3c020001, 0x8c426fa4,
-0x2463d8f0, 0x431023, 0x2c422710, 0x14400003,
-0x24020009, 0x3c010001, 0xac226e34, 0x3e00008,
+0x8c846f1c, 0x621824, 0x3c020a00, 0x621825,
+0x24020001, 0xaf830050, 0xaf820200, 0x1080001e,
+0xaf820220, 0x3c020001, 0x8c426e44, 0x1440001a,
+0x3c033f00, 0x3c020001, 0x8c426d80, 0x1000001a,
+0x346300e0, 0x8f830050, 0x3c040001, 0x8c846f1c,
+0x3442ffff, 0x621824, 0x1080000f, 0xaf830050,
+0x3c020001, 0x8c426e44, 0x1440000b, 0x3c043f00,
+0x3c030001, 0x8c636d80, 0x348400e0, 0x24020001,
+0xaf820200, 0xaf820220, 0x641825, 0xaf830200,
+0x10000008, 0x3c05f700, 0x3c020001, 0x8c426d80,
+0x3c033f00, 0x346300e2, 0x431025, 0xaf820200,
+0x3c05f700, 0x34a58000, 0x3c030001, 0x8c636d84,
+0x3c020001, 0x8c426d90, 0x3c040001, 0x8c846dac,
+0x651825, 0x431025, 0x441025, 0xaf820220,
+0x3e00008, 0x0, 0x3c030001, 0x8c636db4,
+0x3c020001, 0x8c426db8, 0x10620003, 0x24020002,
+0x3c010001, 0xac236db8, 0x1062001d, 0x2c620003,
+0x10400025, 0x24020001, 0x14620023, 0x24020004,
+0x3c030001, 0x8c636d98, 0x10620006, 0x24020008,
+0x1462000c, 0x3c0200c8, 0x344201fb, 0x10000009,
+0xaf820238, 0x24020e01, 0xaf820238, 0x8f820044,
+0x3c03ffff, 0x34633f7f, 0x431024, 0x34420080,
+0xaf820044, 0x8f830054, 0x24020002, 0x3c010001,
+0xac226db4, 0x3c010001, 0x1000000b, 0xac236f2c,
+0x8f830054, 0x3c020001, 0x8c426f2c, 0x2463d8f0,
+0x431023, 0x2c422710, 0x14400003, 0x24020009,
+0x3c010001, 0xac226db4, 0x3e00008, 0x0,
0x0, 0x0, 0x0, 0x27bdffd8,
0xafb20018, 0x809021, 0xafb3001c, 0xa09821,
0xafb10014, 0xc08821, 0xafb00010, 0x8021,
-0xafbf0020, 0xa6200000, 0xc004dab, 0x24040001,
+0xafbf0020, 0xa6200000, 0xc004d78, 0x24040001,
0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x24100010, 0x2501024, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
0x2501024, 0x24100010, 0x2701024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x2701024, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x2701024, 0xc004db9, 0x34108000,
+0xc004db9, 0x0, 0xc004d58, 0x0,
0x50400005, 0x108042, 0x96220000, 0x501025,
0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x0, 0x8fbf0020, 0x8fb3001c,
+0xc004db9, 0x0, 0x8fbf0020, 0x8fb3001c,
0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008,
0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821,
0xafb20018, 0xa09021, 0xafb3001c, 0xc09821,
-0xafb00010, 0x8021, 0xafbf0020, 0xc004dab,
+0xafb00010, 0x8021, 0xafbf0020, 0xc004d78,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0xc004dab,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0xc004d78,
0x24040001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
0x1600fffa, 0x2301024, 0x24100010, 0x2501024,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x2501024, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x2501024, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x34108000,
0x96620000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fff8,
-0x0, 0xc004dec, 0x0, 0x8fbf0020,
+0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
+0x0, 0xc004db9, 0x0, 0x8fbf0020,
0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
-0x3e00008, 0x27bd0028, 0x3c040001, 0x8c846e50,
-0x3c020001, 0x8c426e98, 0x27bdffd8, 0xafbf0020,
+0x3e00008, 0x27bd0028, 0x3c040001, 0x8c846dd0,
+0x3c020001, 0x8c426e18, 0x27bdffd8, 0xafbf0020,
0xafb1001c, 0x10820003, 0xafb00018, 0x3c010001,
-0xac246e98, 0x3c030001, 0x8c636fb8, 0x24020005,
-0x14620005, 0x2483ffff, 0xc0048b3, 0x0,
+0xac246e18, 0x3c030001, 0x8c636f40, 0x24020005,
+0x14620005, 0x2483ffff, 0xc004963, 0x0,
0x1000034c, 0x0, 0x2c620013, 0x10400349,
-0x31080, 0x3c010001, 0x220821, 0x8c226c10,
-0x400008, 0x0, 0xc004dec, 0x8021,
-0x34028000, 0xa7a20010, 0x27b10010, 0xc004dab,
+0x31080, 0x3c010001, 0x220821, 0x8c226b80,
+0x400008, 0x0, 0xc004db9, 0x8021,
+0x34028000, 0xa7a20010, 0x27b10010, 0xc004d78,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0xc004dab,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0xc004d78,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004dab,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0xc004d78,
0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fff8, 0x0, 0xc004dec, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
0x1000030e, 0x24020002, 0x27b10010, 0xa7a00010,
-0x8021, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x24100010,
+0x8021, 0xc004d78, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
+0x2021, 0xc004d78, 0x24040001, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x24100010,
0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004dab, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
+0x24100010, 0xc004d78, 0x2021, 0x108042,
+0x1600fffc, 0x0, 0xc004db9, 0x34108000,
+0xc004db9, 0x0, 0xc004d58, 0x0,
0x50400005, 0x108042, 0x96220000, 0x501025,
0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x0, 0x97a20010, 0x30428000,
+0xc004db9, 0x0, 0x97a20010, 0x30428000,
0x144002dc, 0x24020003, 0x100002d8, 0x0,
0x24021200, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0xc004dab, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0xc004dab, 0x24040001, 0xc004dab,
+0xc004d78, 0x2021, 0x108042, 0x1600fffc,
+0x0, 0xc004d78, 0x24040001, 0xc004d78,
0x2021, 0x34108000, 0x96220000, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fff8, 0x0, 0xc004dec,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fff8, 0x0, 0xc004db9,
0x0, 0x8f830054, 0x10000296, 0x24020004,
-0x8f830054, 0x3c020001, 0x8c426fb4, 0x2463ff9c,
+0x8f830054, 0x3c020001, 0x8c426f3c, 0x2463ff9c,
0x431023, 0x2c420064, 0x1440029e, 0x24020002,
-0x3c030001, 0x8c636fb8, 0x10620297, 0x2c620003,
+0x3c030001, 0x8c636f40, 0x10620297, 0x2c620003,
0x14400296, 0x24020011, 0x24020003, 0x10620005,
0x24020004, 0x10620291, 0x2402000f, 0x1000028f,
0x24020011, 0x1000028d, 0x24020005, 0x24020014,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004dab,
+0xa7a20010, 0x27b10010, 0x8021, 0xc004d78,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0xc004dab,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0xc004d78,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x32020012,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020012, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x32020012, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x34108000,
0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fff8,
-0x0, 0xc004dec, 0x0, 0x8f830054,
+0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
+0x0, 0xc004db9, 0x0, 0x8f830054,
0x10000248, 0x24020006, 0x8f830054, 0x3c020001,
-0x8c426fb4, 0x2463ff9c, 0x431023, 0x2c420064,
+0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064,
0x14400250, 0x24020007, 0x1000024c, 0x0,
0x24020006, 0xa7a20010, 0x27b10010, 0x8021,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020013, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020013,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020013,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fff8, 0x0, 0xc004dec, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
0x8f830054, 0x10000207, 0x24020008, 0x8f830054,
-0x3c020001, 0x8c426fb4, 0x2463ff9c, 0x431023,
+0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
0x2c420064, 0x1440020f, 0x24020009, 0x1000020b,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020018,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
+0x1600fff7, 0x0, 0xc004db9, 0x8021,
0x97a20010, 0x27b10010, 0x34420001, 0xa7a20010,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020018,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fff8, 0x0, 0xc004dec, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
0x8f830054, 0x10000193, 0x2402000a, 0x8f830054,
-0x3c020001, 0x8c426fb4, 0x2463ff9c, 0x431023,
+0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
0x2c420064, 0x1440019b, 0x2402000b, 0x10000197,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020017,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020017,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
+0x1600fff7, 0x0, 0xc004db9, 0x8021,
0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020017, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020017,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020017,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fff8, 0x0, 0xc004dec, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
0x8f830054, 0x1000011f, 0x2402000c, 0x8f830054,
-0x3c020001, 0x8c426fb4, 0x2463ff9c, 0x431023,
+0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
0x2c420064, 0x14400127, 0x24020012, 0x10000123,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020014,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020014,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
+0x1600fff7, 0x0, 0xc004db9, 0x8021,
0x97a20010, 0x27b10010, 0x34420010, 0xa7a20010,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020014, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020014,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020014,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fff8, 0x0, 0xc004dec, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
0x8f830054, 0x100000ab, 0x24020013, 0x8f830054,
-0x3c020001, 0x8c426fb4, 0x2463ff9c, 0x431023,
+0x3c020001, 0x8c426f3c, 0x2463ff9c, 0x431023,
0x2c420064, 0x144000b3, 0x2402000d, 0x100000af,
0x0, 0x27b10010, 0xa7a00010, 0x8021,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020018,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
0x96220000, 0x501025, 0xa6220000, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
+0x1600fff7, 0x0, 0xc004db9, 0x8021,
0x97a20010, 0x27b10010, 0x3042fffe, 0xa7a20010,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
0x108042, 0x1600fffa, 0x32020001, 0x24100010,
0x32020018, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020018,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x34108000, 0x96220000, 0x501024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fff8, 0x0, 0xc004dec, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
0x8f830054, 0x10000037, 0x2402000e, 0x24020840,
-0xa7a20010, 0x27b10010, 0x8021, 0xc004dab,
+0xa7a20010, 0x27b10010, 0x8021, 0xc004d78,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0xc004dab,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0xc004d78,
0x24040001, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
0x1600fffa, 0x32020001, 0x24100010, 0x32020013,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020013, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x34108000,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x32020013, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x34108000,
0x96220000, 0x501024, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fff8,
-0x0, 0xc004dec, 0x0, 0x8f830054,
-0x24020010, 0x3c010001, 0xac226e50, 0x3c010001,
-0x1000000c, 0xac236fb4, 0x8f830054, 0x3c020001,
-0x8c426fb4, 0x2463ff9c, 0x431023, 0x2c420064,
+0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
+0x0, 0xc004db9, 0x0, 0x8f830054,
+0x24020010, 0x3c010001, 0xac226dd0, 0x3c010001,
+0x1000000c, 0xac236f3c, 0x8f830054, 0x3c020001,
+0x8c426f3c, 0x2463ff9c, 0x431023, 0x2c420064,
0x14400004, 0x0, 0x24020011, 0x3c010001,
-0xac226e50, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
-0x3e00008, 0x27bd0028, 0x3c030001, 0x8c636e18,
+0xac226dd0, 0x8fbf0020, 0x8fb1001c, 0x8fb00018,
+0x3e00008, 0x27bd0028, 0x3c030001, 0x8c636d98,
0x27bdffc8, 0x24020002, 0xafbf0034, 0xafb20030,
0xafb1002c, 0x14620004, 0xafb00028, 0x3c120002,
-0x10000003, 0x8e529078, 0x3c120002, 0x8e52907c,
-0x3c030001, 0x8c636e54, 0x3c020001, 0x8c426e9c,
-0x50620004, 0x2463ffff, 0x3c010001, 0xac236e9c,
-0x2463ffff, 0x2c620006, 0x104004b9, 0x31080,
-0x3c010001, 0x220821, 0x8c226c68, 0x400008,
-0x0, 0x2021, 0x2821, 0xc004e0e,
+0x10000003, 0x8e528ff8, 0x3c120002, 0x8e528ffc,
+0x3c030001, 0x8c636dd4, 0x3c020001, 0x8c426e1c,
+0x50620004, 0x2463ffff, 0x3c010001, 0xac236e1c,
+0x2463ffff, 0x2c620006, 0x10400377, 0x31080,
+0x3c010001, 0x220821, 0x8c226bd8, 0x400008,
+0x0, 0x2021, 0x2821, 0xc004ddb,
0x34068000, 0x24040010, 0x24050002, 0x24060002,
-0x24020002, 0xc004e0e, 0xa7a20018, 0x24020002,
-0x3c010001, 0x100004a6, 0xac226e54, 0x27b10018,
-0xa7a00018, 0x8021, 0xc004dab, 0x24040001,
+0x24020002, 0xc004ddb, 0xa7a20018, 0x24020002,
+0x3c010001, 0x10000364, 0xac226dd4, 0x27b10018,
+0xa7a00018, 0x8021, 0xc004d78, 0x24040001,
0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0xc004dab, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0xc004dec,
-0x34108000, 0xc004dec, 0x0, 0xc004d8b,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
+0x32020001, 0x24100010, 0xc004d78, 0x2021,
+0x108042, 0x1600fffc, 0x0, 0xc004db9,
+0x34108000, 0xc004db9, 0x0, 0xc004d58,
0x0, 0x50400005, 0x108042, 0x96220000,
0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004dec, 0x0, 0x97a20018,
+0x0, 0xc004db9, 0x0, 0x97a20018,
0x30428000, 0x14400004, 0x24020003, 0x3c010001,
-0xac226e54, 0x24020003, 0x3c010001, 0x1000046c,
-0xac226e54, 0x24040010, 0x24050002, 0x24060002,
-0x24020002, 0xc004e0e, 0xa7a20018, 0x3c030001,
-0x8c636ea0, 0x24020001, 0x146201e2, 0x0,
-0x27b10018, 0xa7a00018, 0x8021, 0xc004dab,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x24040001, 0xc004dab,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020018,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020018, 0xc004dec,
-0x34108000, 0xc004dec, 0x0, 0xc004d8b,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004dec, 0x8021, 0x27b10018,
-0xa7a00018, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x24100010,
+0xac226dd4, 0x24020003, 0x3c010001, 0x1000032a,
+0xac226dd4, 0x24040010, 0x24050002, 0x24060002,
+0x24020002, 0xc004ddb, 0xa7a20018, 0x3c030001,
+0x8c636e20, 0x24020001, 0x146201e1, 0x8021,
+0x27b10018, 0xa7a00018, 0xc004d78, 0x24040001,
+0x26100001, 0x2e020020, 0x1440fffb, 0x0,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0x24100010, 0x32020001, 0x10400002, 0x2021,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
+0x32020001, 0x24100010, 0x32020018, 0x10400002,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020018, 0xc004db9, 0x34108000,
+0xc004db9, 0x0, 0xc004d58, 0x0,
+0x50400005, 0x108042, 0x96220000, 0x501025,
+0xa6220000, 0x108042, 0x1600fff7, 0x0,
+0xc004db9, 0x8021, 0x27b10018, 0xa7a00018,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x32020001, 0x24100010,
+0x32020018, 0x10400002, 0x2021, 0x24040001,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020018,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
+0x96220000, 0x501025, 0xa6220000, 0x108042,
+0x1600fff7, 0x0, 0xc004db9, 0x8021,
+0x24040018, 0x2821, 0xc004ddb, 0x24060404,
+0xa7a0001a, 0xc004d78, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
+0x2021, 0xc004d78, 0x24040001, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x24100010,
0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020001,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
0x24100010, 0x32020018, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020018, 0xc004dec, 0x34108000, 0xc004dec,
-0x0, 0xc004d8b, 0x0, 0x50400005,
-0x108042, 0x96220000, 0x501025, 0xa6220000,
-0x108042, 0x1600fff7, 0x0, 0xc004dec,
-0x8021, 0x24040018, 0x2821, 0xc004e0e,
-0x24060404, 0xa7a0001a, 0xc004dab, 0x24040001,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
+0x32020018, 0xc004db9, 0x34108000, 0xc004db9,
+0x0, 0xc004d58, 0x0, 0x50400005,
+0x108042, 0x97a2001a, 0x501025, 0xa7a2001a,
+0x108042, 0x1600fff7, 0x0, 0xc004db9,
+0x8021, 0xa7a0001a, 0xc004d78, 0x24040001,
0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
0x32020001, 0x24100010, 0x32020018, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020018, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020018, 0xc004db9, 0x34108000,
+0xc004db9, 0x0, 0xc004d58, 0x0,
0x50400005, 0x108042, 0x97a2001a, 0x501025,
0xa7a2001a, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x8021, 0xa7a0001a, 0xc004dab,
+0xc004db9, 0x8021, 0xa7a0001c, 0xc004d78,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x24040001, 0xc004dab,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020018,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020018, 0xc004dec,
-0x34108000, 0xc004dec, 0x0, 0xc004d8b,
-0x0, 0x50400005, 0x108042, 0x97a2001a,
-0x501025, 0xa7a2001a, 0x108042, 0x1600fff7,
-0x0, 0xc004dec, 0x8021, 0xa7a0001c,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0xc004dab,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
+0x2021, 0x24100010, 0xc004d78, 0x2021,
+0x108042, 0x1600fffc, 0x0, 0x24100010,
+0x3202001e, 0x10400002, 0x2021, 0x24040001,
+0xc004d78, 0x108042, 0x1600fffa, 0x3202001e,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
+0x97a2001c, 0x501025, 0xa7a2001c, 0x108042,
+0x1600fff7, 0x0, 0xc004db9, 0x8021,
+0xa7a0001c, 0xc004d78, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
+0x2021, 0xc004d78, 0x24040001, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x24100010,
+0xc004d78, 0x2021, 0x108042, 0x1600fffc,
+0x0, 0x24100010, 0x3202001e, 0x10400002,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x3202001e, 0xc004db9, 0x34108000,
+0xc004db9, 0x0, 0xc004d58, 0x0,
+0x50400005, 0x108042, 0x97a2001c, 0x501025,
+0xa7a2001c, 0x108042, 0x1600fff7, 0x0,
+0xc004db9, 0x8021, 0x24020002, 0xa7a2001e,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0x24100010, 0xc004d78,
0x2021, 0x108042, 0x1600fffc, 0x0,
0x24100010, 0x3202001e, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x3202001e, 0xc004dec, 0x34108000, 0xc004dec,
-0x0, 0xc004d8b, 0x0, 0x50400005,
-0x108042, 0x97a2001c, 0x501025, 0xa7a2001c,
-0x108042, 0x1600fff7, 0x0, 0xc004dec,
-0x8021, 0xa7a0001c, 0xc004dab, 0x24040001,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
+0x3202001e, 0xc004d78, 0x24040001, 0xc004d78,
+0x2021, 0x34108000, 0x97a2001e, 0x501024,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fff8, 0x0, 0xc004db9,
+0x8021, 0xa7a00020, 0xc004d78, 0x24040001,
0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0x24100010, 0xc004dab, 0x2021, 0x108042,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0x24100010, 0xc004d78, 0x2021, 0x108042,
0x1600fffc, 0x0, 0x24100010, 0x3202001e,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x3202001e, 0xc004dec,
-0x34108000, 0xc004dec, 0x0, 0xc004d8b,
-0x0, 0x50400005, 0x108042, 0x97a2001c,
-0x501025, 0xa7a2001c, 0x108042, 0x1600fff7,
-0x0, 0xc004dec, 0x8021, 0x24020002,
-0xa7a2001e, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0x24100010,
-0xc004dab, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0x24100010, 0x3202001e, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x3202001e, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x34108000, 0x97a2001e,
-0x501024, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fff8, 0x0,
-0xc004dec, 0x8021, 0xa7a00020, 0xc004dab,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x24040001, 0xc004dab,
-0x2021, 0x24100010, 0xc004dab, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0x24100010,
-0x3202001e, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x3202001e,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
-0x97a20020, 0x501025, 0xa7a20020, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
-0xa7a00020, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x24100010,
-0xc004dab, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0x24100010, 0x3202001e, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x3202001e, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
-0x50400005, 0x108042, 0x97a20020, 0x501025,
-0xa7a20020, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x8021, 0xa7a00022, 0xc004dab,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0x24100010, 0xc004dab, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0x24100010,
-0xc004dab, 0x2021, 0x108042, 0x1600fffc,
-0x0, 0xc004dab, 0x24040001, 0xc004dab,
-0x2021, 0x34108000, 0x97a20022, 0x501024,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fff8, 0x0, 0xc004dec,
-0x0, 0x24040018, 0x24050002, 0xc004e0e,
-0x24060004, 0x3c030001, 0x8c636ea4, 0x24020001,
-0x146200fc, 0x3c024000, 0x3c010001, 0xac206ea4,
-0x2421024, 0x10400276, 0x3c022000, 0x2421024,
-0x10400004, 0x0, 0x3c010001, 0x10000003,
-0xac236f98, 0x3c010001, 0xac206f98, 0x3c030001,
-0x8c636fac, 0x24020005, 0x146200ea, 0x0,
-0x3c020001, 0x8c426f98, 0x1040005f, 0x3c020004,
-0x2421024, 0x10400011, 0xa7a00018, 0x3c020008,
-0x2421024, 0x10400002, 0x24020200, 0xa7a20018,
-0x3c020010, 0x2421024, 0x10400004, 0x0,
-0x97a20018, 0x34420100, 0xa7a20018, 0x97a60018,
-0x24040009, 0x10000004, 0x2821, 0x24040009,
-0x2821, 0x3021, 0xc004e0e, 0x0,
-0x24020001, 0xa7a2001a, 0x3c020008, 0x2421024,
-0x1040000c, 0x3c020002, 0x2421024, 0x10400002,
-0x24020101, 0xa7a2001a, 0x3c020001, 0x2421024,
-0x10400005, 0x3c020010, 0x97a2001a, 0x34420040,
-0xa7a2001a, 0x3c020010, 0x2421024, 0x1040000e,
-0x3c020002, 0x2421024, 0x10400005, 0x3c020001,
-0x97a2001a, 0x34420080, 0xa7a2001a, 0x3c020001,
-0x2421024, 0x10400005, 0x3c0300a0, 0x97a2001a,
-0x34420020, 0xa7a2001a, 0x3c0300a0, 0x2431024,
-0x54430004, 0x3c020020, 0x97a2001a, 0x1000000c,
-0x34420400, 0x2421024, 0x50400004, 0x3c020080,
-0x97a2001a, 0x10000006, 0x34420800, 0x2421024,
-0x10400004, 0x0, 0x97a2001a, 0x34420c00,
-0xa7a2001a, 0x97a6001a, 0x24040004, 0xc004e0e,
-0x2821, 0x32424000, 0x10400003, 0xa7a0001c,
-0x24024000, 0xa7a2001c, 0x97a6001c, 0x2021,
-0x2821, 0x34c61200, 0xc004e0e, 0xa7a6001c,
-0x10000088, 0x0, 0x32424000, 0x10400003,
-0xa7a00018, 0x24024000, 0xa7a20018, 0x3c020010,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x3202001e, 0xc004db9,
+0x34108000, 0xc004db9, 0x0, 0xc004d58,
+0x0, 0x50400005, 0x108042, 0x97a20020,
+0x501025, 0xa7a20020, 0x108042, 0x1600fff7,
+0x0, 0xc004db9, 0x8021, 0xa7a00020,
+0xc004d78, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004d78, 0x2021,
+0xc004d78, 0x24040001, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0x24100010, 0xc004d78,
+0x2021, 0x108042, 0x1600fffc, 0x0,
+0x24100010, 0x3202001e, 0x10400002, 0x2021,
+0x24040001, 0xc004d78, 0x108042, 0x1600fffa,
+0x3202001e, 0xc004db9, 0x34108000, 0xc004db9,
+0x0, 0xc004d58, 0x0, 0x50400005,
+0x108042, 0x97a20020, 0x501025, 0xa7a20020,
+0x108042, 0x1600fff7, 0x0, 0xc004db9,
+0x8021, 0xa7a00022, 0xc004d78, 0x24040001,
+0x26100001, 0x2e020020, 0x1440fffb, 0x0,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0xc004d78, 0x2021, 0xc004d78, 0x24040001,
+0x24100010, 0xc004d78, 0x2021, 0x108042,
+0x1600fffc, 0x0, 0x24100010, 0xc004d78,
+0x2021, 0x108042, 0x1600fffc, 0x0,
+0xc004d78, 0x24040001, 0xc004d78, 0x2021,
+0x34108000, 0x97a20022, 0x501024, 0x10400002,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fff8, 0x0, 0xc004db9, 0x0,
+0x24040018, 0x24050002, 0xc004ddb, 0x24060004,
+0x3c100001, 0x8e106e24, 0x24020001, 0x1602011d,
+0x0, 0x3c020001, 0x94426f26, 0x3c010001,
+0xac206e24, 0x24429fbc, 0x2c420004, 0x1040000c,
+0x24040009, 0x24050001, 0xc004ddb, 0x24060400,
+0x24040018, 0x24050001, 0xc004ddb, 0x24060020,
+0x24040018, 0x24050001, 0xc004ddb, 0x24062000,
+0x3c024000, 0x2421024, 0x10400123, 0x3c022000,
+0x2421024, 0x10400004, 0x0, 0x3c010001,
+0x10000003, 0xac306f1c, 0x3c010001, 0xac206f1c,
+0x3c030001, 0x8c636f34, 0x24020005, 0x146200f9,
+0x0, 0x3c020001, 0x8c426f1c, 0x10400067,
+0x3c020004, 0x2421024, 0x10400011, 0xa7a00018,
+0x3c020008, 0x2421024, 0x10400002, 0x24020200,
+0xa7a20018, 0x3c020010, 0x2421024, 0x10400004,
+0x0, 0x97a20018, 0x34420100, 0xa7a20018,
+0x97a60018, 0x24040009, 0x10000004, 0x2821,
+0x24040009, 0x2821, 0x3021, 0xc004ddb,
+0x0, 0x24020001, 0xa7a2001a, 0x3c020008,
+0x2421024, 0x1040000c, 0x3c020002, 0x2421024,
+0x10400002, 0x24020101, 0xa7a2001a, 0x3c020001,
+0x2421024, 0x10400005, 0x3c020010, 0x97a2001a,
+0x34420040, 0xa7a2001a, 0x3c020010, 0x2421024,
+0x1040000e, 0x3c020002, 0x2421024, 0x10400005,
+0x3c020001, 0x97a2001a, 0x34420080, 0xa7a2001a,
+0x3c020001, 0x2421024, 0x10400005, 0x3c0300a0,
+0x97a2001a, 0x34420020, 0xa7a2001a, 0x3c0300a0,
+0x2431024, 0x54430004, 0x3c020020, 0x97a2001a,
+0x1000000c, 0x34420400, 0x2421024, 0x50400004,
+0x3c020080, 0x97a2001a, 0x10000006, 0x34420800,
+0x2421024, 0x10400004, 0x0, 0x97a2001a,
+0x34420c00, 0xa7a2001a, 0x97a6001a, 0x24040004,
+0xc004ddb, 0x2821, 0x3c020004, 0x2421024,
+0x10400004, 0xa7a0001c, 0x32425000, 0x14400004,
+0x0, 0x32424000, 0x10400005, 0x2021,
+0xc004cf9, 0x2402021, 0x10000096, 0x0,
+0x97a6001c, 0x2821, 0x34c61200, 0xc004ddb,
+0xa7a6001c, 0x1000008f, 0x0, 0x2421024,
+0x10400004, 0xa7a00018, 0x32425000, 0x14400004,
+0x0, 0x32424000, 0x10400005, 0x3c020010,
+0xc004cf9, 0x2402021, 0x10000019, 0xa7a0001a,
0x2421024, 0x10400004, 0x0, 0x97a20018,
0x10000004, 0xa7a20018, 0x97a20018, 0x34420100,
0xa7a20018, 0x3c020001, 0x2421024, 0x10400004,
0x0, 0x97a20018, 0x10000004, 0xa7a20018,
-0x97a20018, 0x34422000, 0xa7a20018, 0x2021,
-0x97a60018, 0x2821, 0xc004e0e, 0x8021,
-0xa7a0001a, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x24100010,
+0x97a20018, 0x34422000, 0xa7a20018, 0x97a60018,
+0x2021, 0xc004ddb, 0x2821, 0xa7a0001a,
+0x8021, 0xc004d78, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004d78,
+0x2021, 0xc004d78, 0x24040001, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x24100010,
0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0xc004dab, 0x2021, 0x108042,
-0x1600fffc, 0x0, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
+0xc004d78, 0x108042, 0x1600fffa, 0x32020001,
+0x24100010, 0xc004d78, 0x2021, 0x108042,
+0x1600fffc, 0x0, 0xc004db9, 0x34108000,
+0xc004db9, 0x0, 0xc004d58, 0x0,
0x50400005, 0x108042, 0x97a2001a, 0x501025,
0xa7a2001a, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x8021, 0xa7a0001a, 0xc004dab,
+0xc004db9, 0x8021, 0xa7a0001a, 0xc004d78,
0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x24040001, 0xc004dab,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0xc004dab,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0xc004d78,
0x2021, 0x108042, 0x1600fffc, 0x0,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
+0xc004db9, 0x34108000, 0xc004db9, 0x0,
+0xc004d58, 0x0, 0x50400005, 0x108042,
0x97a2001a, 0x501025, 0xa7a2001a, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x0,
-0x3c040001, 0x24846c5c, 0x97a60018, 0x97a7001a,
-0x3c020001, 0x8c426e18, 0x3c030001, 0x8c636f98,
-0x3c05000d, 0x34a50205, 0xafa20010, 0xc002b17,
+0x1600fff7, 0x0, 0xc004db9, 0x0,
+0x3c040001, 0x24846bcc, 0x97a60018, 0x97a7001a,
+0x3c020001, 0x8c426d98, 0x3c030001, 0x8c636f1c,
+0x3c05000d, 0x34a50205, 0xafa20010, 0xc002b3b,
0xafa30014, 0x8f830054, 0x24020004, 0x3c010001,
-0xac226e54, 0x3c010001, 0x10000179, 0xac236fb0,
-0x8f830054, 0x3c020001, 0x8c426fb0, 0x2463ff9c,
-0x431023, 0x2c420064, 0x14400009, 0x27b10018,
-0x8f820220, 0x24030005, 0x3c010001, 0xac236e54,
-0x3c03f700, 0x431025, 0xaf820220, 0x27b10018,
-0xa7a00018, 0x8021, 0xc004dab, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0xc004dab, 0x2021,
-0x108042, 0x1600fffc, 0x0, 0xc004dec,
-0x34108000, 0xc004dec, 0x0, 0xc004d8b,
-0x0, 0x50400005, 0x108042, 0x96220000,
-0x501025, 0xa6220000, 0x108042, 0x1600fff7,
-0x0, 0xc004dec, 0x8021, 0xa7a0001a,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020001,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
-0x97a2001a, 0x501025, 0xa7a2001a, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
-0xa7a0001a, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0xc004dec, 0x34108000, 0xc004dec,
-0x0, 0xc004d8b, 0x0, 0x50400005,
-0x108042, 0x97a2001a, 0x501025, 0xa7a2001a,
-0x108042, 0x1600fff7, 0x0, 0xc004dec,
-0x8021, 0xa7a0001c, 0xc004dab, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x32020004, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020004, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
-0x50400005, 0x108042, 0x97a2001c, 0x501025,
-0xa7a2001c, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x8021, 0xa7a0001c, 0xc004dab,
-0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
-0x0, 0xc004dab, 0x2021, 0xc004dab,
-0x24040001, 0xc004dab, 0x24040001, 0xc004dab,
-0x2021, 0x24100010, 0x32020001, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x32020001, 0x24100010, 0x32020004,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020004, 0xc004dec,
-0x34108000, 0xc004dec, 0x0, 0xc004d8b,
-0x0, 0x50400005, 0x108042, 0x97a2001c,
-0x501025, 0xa7a2001c, 0x108042, 0x1600fff7,
-0x0, 0xc004dec, 0x8021, 0xa7a00020,
-0xc004dab, 0x24040001, 0x26100001, 0x2e020020,
-0x1440fffb, 0x0, 0xc004dab, 0x2021,
-0xc004dab, 0x24040001, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x24100010, 0x32020001,
-0x10400002, 0x2021, 0x24040001, 0xc004dab,
-0x108042, 0x1600fffa, 0x32020001, 0x24100010,
-0x32020019, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020019,
-0xc004dec, 0x34108000, 0xc004dec, 0x0,
-0xc004d8b, 0x0, 0x50400005, 0x108042,
-0x97a20020, 0x501025, 0xa7a20020, 0x108042,
-0x1600fff7, 0x0, 0xc004dec, 0x8021,
-0xa7a00020, 0xc004dab, 0x24040001, 0x26100001,
-0x2e020020, 0x1440fffb, 0x0, 0xc004dab,
-0x2021, 0xc004dab, 0x24040001, 0xc004dab,
-0x24040001, 0xc004dab, 0x2021, 0x24100010,
-0x32020001, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fffa, 0x32020001,
-0x24100010, 0x32020019, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020019, 0xc004dec, 0x34108000, 0xc004dec,
-0x0, 0xc004d8b, 0x0, 0x50400005,
-0x108042, 0x97a20020, 0x501025, 0xa7a20020,
-0x108042, 0x1600fff7, 0x0, 0xc004dec,
-0x0, 0x97a60018, 0x97a7001a, 0x97a2001c,
-0x3c040001, 0x24846c5c, 0xafa20010, 0x97a20020,
-0x3c05000d, 0x34a50204, 0xc002b17, 0xafa20014,
-0x10000007, 0x0, 0x24020006, 0x3c010001,
-0xac226e54, 0x24020011, 0x3c010001, 0xac226e50,
-0x8fbf0034, 0x8fb20030, 0x8fb1002c, 0x8fb00028,
-0x3e00008, 0x27bd0038, 0x8f850044, 0x8f820044,
-0x3c030001, 0x431025, 0x3c030008, 0xaf820044,
-0x8f840054, 0x8f820054, 0xa32824, 0x10000002,
-0x24840001, 0x8f820054, 0x821023, 0x2c420002,
-0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
-0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
-0x621023, 0x2c420002, 0x1440fffc, 0x0,
-0x3e00008, 0xa01021, 0x8f830044, 0x3c02fff0,
-0x3442ffff, 0x42480, 0x621824, 0x3c020002,
-0x822025, 0x641825, 0xaf830044, 0x8f820044,
+0xac226dd4, 0x3c010001, 0x10000017, 0xac236f38,
+0x8f830054, 0x3c020001, 0x8c426f38, 0x2463ff9c,
+0x431023, 0x2c420064, 0x1440000f, 0x0,
+0x8f820220, 0x24030005, 0x3c010001, 0xac236dd4,
+0x3c03f700, 0x431025, 0x10000007, 0xaf820220,
+0x24020006, 0x3c010001, 0xac226dd4, 0x24020011,
+0x3c010001, 0xac226dd0, 0x8fbf0034, 0x8fb20030,
+0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0038,
+0x27bdffd8, 0xafb00018, 0x808021, 0xafb1001c,
+0x8821, 0x32024000, 0x10400013, 0xafbf0020,
+0x3c020010, 0x2021024, 0x2c420001, 0x21023,
+0x30434100, 0x3c020001, 0x2021024, 0x14400006,
+0x34714000, 0x3c020002, 0x2021024, 0x14400002,
+0x34716000, 0x34714040, 0x2021, 0x2821,
+0x10000036, 0x2203021, 0x32021000, 0x10400035,
+0x2021, 0x2821, 0xc004ddb, 0x24060040,
+0x24040018, 0x2821, 0xc004ddb, 0x24060c00,
+0x24040017, 0x2821, 0xc004ddb, 0x24060400,
+0x24040016, 0x2821, 0xc004ddb, 0x24060006,
+0x24040017, 0x2821, 0xc004ddb, 0x24062500,
+0x24040016, 0x2821, 0xc004ddb, 0x24060006,
+0x24040017, 0x2821, 0xc004ddb, 0x24064600,
+0x24040016, 0x2821, 0xc004ddb, 0x24060006,
+0x24040017, 0x2821, 0xc004ddb, 0x24066700,
+0x24040016, 0x2821, 0xc004ddb, 0x24060006,
+0x2404001f, 0x2821, 0xc004ddb, 0x24060010,
+0x24040009, 0x2821, 0xc004ddb, 0x24061500,
+0x24040009, 0x2821, 0x24061d00, 0xc004ddb,
+0x0, 0x3c040001, 0x24846bf0, 0x3c05000e,
+0x34a50100, 0x2003021, 0x2203821, 0xafa00010,
+0xc002b3b, 0xafa00014, 0x8fbf0020, 0x8fb1001c,
+0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044,
+0x8f820044, 0x3c030001, 0x431025, 0x3c030008,
+0xaf820044, 0x8f840054, 0x8f820054, 0xa32824,
+0x10000002, 0x24840001, 0x8f820054, 0x821023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820044,
0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820044, 0x3c030001, 0x431025,
+0x0, 0x3e00008, 0xa01021, 0x8f830044,
+0x3c02fff0, 0x3442ffff, 0x42480, 0x621824,
+0x3c020002, 0x822025, 0x641825, 0xaf830044,
+0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024,
0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
0x24630001, 0x8f820054, 0x621023, 0x2c420002,
-0x1440fffc, 0x0, 0x3e00008, 0x0,
-0x8f820044, 0x2403ff7f, 0x431024, 0xaf820044,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820044, 0x34420080, 0xaf820044,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x3e00008, 0x0, 0x8f820044,
-0x3c03fff0, 0x3463ffff, 0x431024, 0xaf820044,
-0x8f820044, 0x3c030001, 0x431025, 0xaf820044,
-0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
-0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
-0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff,
-0x431024, 0xaf820044, 0x8f830054, 0x8f820054,
+0x1440fffc, 0x0, 0x8f820044, 0x3c030001,
+0x431025, 0xaf820044, 0x8f830054, 0x8f820054,
0x10000002, 0x24630001, 0x8f820054, 0x621023,
0x2c420002, 0x1440fffc, 0x0, 0x3e00008,
-0x0, 0x27bdffc8, 0xafb30024, 0x809821,
-0xafbe002c, 0xa0f021, 0xafb20020, 0xc09021,
-0x33c2ffff, 0xafbf0030, 0xafb50028, 0xafb1001c,
-0xafb00018, 0x14400034, 0xa7b20010, 0x3271ffff,
-0x27b20010, 0x8021, 0xc004dab, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x2301024, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x34108000, 0x96420000,
-0x501024, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x12000075, 0x0,
-0x1000fff6, 0x0, 0x3275ffff, 0x27b10010,
-0xa7a00010, 0x8021, 0xc004dab, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x24040001, 0xc004dab, 0x2021,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x2b01024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x2b01024, 0xc004dec, 0x34108000,
-0xc004dec, 0x0, 0xc004d8b, 0x0,
-0x50400005, 0x108042, 0x96220000, 0x501025,
-0xa6220000, 0x108042, 0x1600fff7, 0x0,
-0xc004dec, 0x0, 0x33c5ffff, 0x24020001,
-0x54a20004, 0x24020002, 0x97a20010, 0x10000006,
-0x521025, 0x14a20006, 0x3271ffff, 0x97a20010,
-0x121827, 0x431024, 0xa7a20010, 0x3271ffff,
-0x27b20010, 0x8021, 0xc004dab, 0x24040001,
-0x26100001, 0x2e020020, 0x1440fffb, 0x0,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0xc004dab, 0x24040001,
-0x24100010, 0x32020001, 0x10400002, 0x2021,
-0x24040001, 0xc004dab, 0x108042, 0x1600fffa,
-0x32020001, 0x24100010, 0x2301024, 0x10400002,
-0x2021, 0x24040001, 0xc004dab, 0x108042,
-0x1600fffa, 0x2301024, 0xc004dab, 0x24040001,
-0xc004dab, 0x2021, 0x34108000, 0x96420000,
-0x501024, 0x10400002, 0x2021, 0x24040001,
-0xc004dab, 0x108042, 0x1600fff8, 0x0,
-0xc004dec, 0x0, 0x8fbf0030, 0x8fbe002c,
-0x8fb50028, 0x8fb30024, 0x8fb20020, 0x8fb1001c,
-0x8fb00018, 0x3e00008, 0x27bd0038, 0x27bdffe8,
+0x0, 0x8f820044, 0x2403ff7f, 0x431024,
+0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
+0x24630001, 0x8f820054, 0x621023, 0x2c420002,
+0x1440fffc, 0x0, 0x8f820044, 0x34420080,
+0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
+0x24630001, 0x8f820054, 0x621023, 0x2c420002,
+0x1440fffc, 0x0, 0x3e00008, 0x0,
+0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024,
+0xaf820044, 0x8f820044, 0x3c030001, 0x431025,
+0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
+0x24630001, 0x8f820054, 0x621023, 0x2c420002,
+0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe,
+0x3463ffff, 0x431024, 0xaf820044, 0x8f830054,
+0x8f820054, 0x10000002, 0x24630001, 0x8f820054,
+0x621023, 0x2c420002, 0x1440fffc, 0x0,
+0x3e00008, 0x0, 0x27bdffc8, 0xafb30024,
+0x809821, 0xafbe002c, 0xa0f021, 0xafb20020,
+0xc09021, 0x33c2ffff, 0xafbf0030, 0xafb50028,
+0xafb1001c, 0xafb00018, 0x14400034, 0xa7b20010,
+0x3271ffff, 0x27b20010, 0x8021, 0xc004d78,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0x24100010, 0x32020001, 0x10400002,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x2301024, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x34108000,
+0x96420000, 0x501024, 0x10400002, 0x2021,
+0x24040001, 0xc004d78, 0x108042, 0x12000075,
+0x0, 0x1000fff6, 0x0, 0x3275ffff,
+0x27b10010, 0xa7a00010, 0x8021, 0xc004d78,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x24040001, 0xc004d78,
+0x2021, 0x24100010, 0x32020001, 0x10400002,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0x2b01024,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x2b01024, 0xc004db9,
+0x34108000, 0xc004db9, 0x0, 0xc004d58,
+0x0, 0x50400005, 0x108042, 0x96220000,
+0x501025, 0xa6220000, 0x108042, 0x1600fff7,
+0x0, 0xc004db9, 0x0, 0x33c5ffff,
+0x24020001, 0x54a20004, 0x24020002, 0x97a20010,
+0x10000006, 0x521025, 0x14a20006, 0x3271ffff,
+0x97a20010, 0x121827, 0x431024, 0xa7a20010,
+0x3271ffff, 0x27b20010, 0x8021, 0xc004d78,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0xc004d78,
+0x24040001, 0x24100010, 0x32020001, 0x10400002,
+0x2021, 0x24040001, 0xc004d78, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0x2301024,
+0x10400002, 0x2021, 0x24040001, 0xc004d78,
+0x108042, 0x1600fffa, 0x2301024, 0xc004d78,
+0x24040001, 0xc004d78, 0x2021, 0x34108000,
+0x96420000, 0x501024, 0x10400002, 0x2021,
+0x24040001, 0xc004d78, 0x108042, 0x1600fff8,
+0x0, 0xc004db9, 0x0, 0x8fbf0030,
+0x8fbe002c, 0x8fb50028, 0x8fb30024, 0x8fb20020,
+0x8fb1001c, 0x8fb00018, 0x3e00008, 0x27bd0038,
+0x0, 0x0, 0x0, 0x27bdffe8,
0xafbf0010, 0x8ee304b8, 0x24020008, 0x146201e0,
-0x0, 0x3c020001, 0x8c426f98, 0x14400005,
-0x0, 0xc003d87, 0x8f840224, 0x100001d8,
+0x0, 0x3c020001, 0x8c426f1c, 0x14400005,
+0x0, 0xc003daf, 0x8f840224, 0x100001d8,
0x0, 0x8f820220, 0x3c030008, 0x431024,
0x10400026, 0x24020001, 0x8f840224, 0x8f820220,
0x3c030400, 0x431024, 0x10400006, 0x0,
-0x3c010002, 0xac209020, 0x3c010002, 0x1000000b,
-0xac209040, 0x3c030002, 0x24639020, 0x8c620000,
+0x3c010002, 0xac208fa0, 0x3c010002, 0x1000000b,
+0xac208fc0, 0x3c030002, 0x24638fa0, 0x8c620000,
0x24420001, 0xac620000, 0x2c420002, 0x14400003,
-0x24020001, 0x3c010002, 0xac229040, 0x3c020002,
-0x8c429040, 0x10400006, 0x30820040, 0x10400004,
-0x24020001, 0x3c010002, 0x10000003, 0xac229044,
-0x3c010002, 0xac209044, 0x3c010002, 0xac24901c,
-0x3c010002, 0x1000000b, 0xac209050, 0x3c010002,
-0xac229050, 0x3c010002, 0xac209040, 0x3c010002,
-0xac209020, 0x3c010002, 0xac209044, 0x3c010002,
-0xac20901c, 0x3c030002, 0x8c639010, 0x3c020002,
-0x8c429014, 0x50620004, 0x2463ffff, 0x3c010002,
-0xac239014, 0x2463ffff, 0x2c62000e, 0x10400194,
-0x31080, 0x3c010001, 0x220821, 0x8c226c80,
+0x24020001, 0x3c010002, 0xac228fc0, 0x3c020002,
+0x8c428fc0, 0x10400006, 0x30820040, 0x10400004,
+0x24020001, 0x3c010002, 0x10000003, 0xac228fc4,
+0x3c010002, 0xac208fc4, 0x3c010002, 0xac248f9c,
+0x3c010002, 0x1000000b, 0xac208fd0, 0x3c010002,
+0xac228fd0, 0x3c010002, 0xac208fc0, 0x3c010002,
+0xac208fa0, 0x3c010002, 0xac208fc4, 0x3c010002,
+0xac208f9c, 0x3c030002, 0x8c638f90, 0x3c020002,
+0x8c428f94, 0x50620004, 0x2463ffff, 0x3c010002,
+0xac238f94, 0x2463ffff, 0x2c62000e, 0x10400194,
+0x31080, 0x3c010001, 0x220821, 0x8c226c00,
0x400008, 0x0, 0x24020002, 0x3c010002,
-0xac209040, 0x3c010002, 0xac209020, 0x3c010002,
-0xac20901c, 0x3c010002, 0xac209044, 0x3c010002,
-0xac209038, 0x3c010002, 0xac209030, 0xaf800224,
-0x3c010002, 0xac229010, 0x3c020002, 0x8c429050,
-0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003d87,
+0xac208fc0, 0x3c010002, 0xac208fa0, 0x3c010002,
+0xac208f9c, 0x3c010002, 0xac208fc4, 0x3c010002,
+0xac208fb8, 0x3c010002, 0xac208fb0, 0xaf800224,
+0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fd0,
+0x1440004f, 0x3c02fdff, 0x3442ffff, 0xc003daf,
0x282a024, 0xaf800204, 0x8f820200, 0x2403fffd,
-0x431024, 0xaf820200, 0x3c010002, 0xac209060,
-0x8f830054, 0x3c020002, 0x8c429038, 0x24040001,
-0x3c010002, 0xac24904c, 0x24420001, 0x3c010002,
-0xac229038, 0x2c420004, 0x3c010002, 0xac239034,
-0x14400006, 0x24020003, 0x3c010001, 0xac246e1c,
-0x3c010002, 0x1000015e, 0xac209038, 0x3c010002,
-0x1000015b, 0xac229010, 0x8f830054, 0x3c020002,
-0x8c429034, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400003, 0x24020004, 0x3c010002, 0xac229010,
-0x3c020002, 0x8c429050, 0x14400021, 0x3c02fdff,
+0x431024, 0xaf820200, 0x3c010002, 0xac208fe0,
+0x8f830054, 0x3c020002, 0x8c428fb8, 0x24040001,
+0x3c010002, 0xac248fcc, 0x24420001, 0x3c010002,
+0xac228fb8, 0x2c420004, 0x3c010002, 0xac238fb4,
+0x14400006, 0x24020003, 0x3c010001, 0xac246d9c,
+0x3c010002, 0x1000015e, 0xac208fb8, 0x3c010002,
+0x1000015b, 0xac228f90, 0x8f830054, 0x3c020002,
+0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710,
+0x14400003, 0x24020004, 0x3c010002, 0xac228f90,
+0x3c020002, 0x8c428fd0, 0x14400021, 0x3c02fdff,
0x3442ffff, 0x1000014a, 0x282a024, 0x3c040001,
-0x8c846f9c, 0x3c010002, 0xc0050b4, 0xac209028,
-0x3c020002, 0x8c42905c, 0xaf820204, 0x3c020002,
-0x8c429050, 0x14400012, 0x3c03fdff, 0x8f820204,
+0x8c846f20, 0x3c010002, 0xc005084, 0xac208fa8,
+0x3c020002, 0x8c428fdc, 0xaf820204, 0x3c020002,
+0x8c428fd0, 0x14400012, 0x3c03fdff, 0x8f820204,
0x3463ffff, 0x30420030, 0x1440012f, 0x283a024,
-0x3c030002, 0x8c63905c, 0x24020005, 0x3c010002,
-0xac229010, 0x3c010002, 0x10000131, 0xac239060,
-0x3c020002, 0x8c429050, 0x10400010, 0x3c02fdff,
-0x3c020001, 0x8c426ebc, 0x24420001, 0x3c010001,
-0xac226ebc, 0x2c420002, 0x14400125, 0x24020001,
-0x3c010001, 0xac226ec4, 0x3c010001, 0xac206ebc,
-0x3c010001, 0x1000011e, 0xac226e1c, 0x3c030002,
-0x8c639040, 0x3442ffff, 0x10600119, 0x282a024,
-0x3c020002, 0x8c42901c, 0x10400115, 0x0,
-0x3c010002, 0xac229048, 0x24020003, 0x3c010002,
-0xac229020, 0x100000b8, 0x24020006, 0x3c010002,
-0xac209028, 0x8f820204, 0x34420040, 0xaf820204,
-0x3c020002, 0x8c429060, 0x24030007, 0x3c010002,
-0xac239010, 0x34420040, 0x3c010002, 0xac229060,
-0x3c020002, 0x8c429040, 0x10400005, 0x0,
-0x3c020002, 0x8c42901c, 0x104000f0, 0x24020002,
-0x3c050002, 0x24a59020, 0x8ca20000, 0x2c424e21,
-0x104000ea, 0x24020002, 0x3c020002, 0x8c429044,
-0x104000ef, 0x2404ffbf, 0x3c020002, 0x8c42901c,
-0x3c030002, 0x8c639048, 0x441024, 0x641824,
+0x3c030002, 0x8c638fdc, 0x24020005, 0x3c010002,
+0xac228f90, 0x3c010002, 0x10000131, 0xac238fe0,
+0x3c020002, 0x8c428fd0, 0x10400010, 0x3c02fdff,
+0x3c020001, 0x8c426e3c, 0x24420001, 0x3c010001,
+0xac226e3c, 0x2c420002, 0x14400125, 0x24020001,
+0x3c010001, 0xac226e44, 0x3c010001, 0xac206e3c,
+0x3c010001, 0x1000011e, 0xac226d9c, 0x3c030002,
+0x8c638fc0, 0x3442ffff, 0x10600119, 0x282a024,
+0x3c020002, 0x8c428f9c, 0x10400115, 0x0,
+0x3c010002, 0xac228fc8, 0x24020003, 0x3c010002,
+0xac228fa0, 0x100000b8, 0x24020006, 0x3c010002,
+0xac208fa8, 0x8f820204, 0x34420040, 0xaf820204,
+0x3c020002, 0x8c428fe0, 0x24030007, 0x3c010002,
+0xac238f90, 0x34420040, 0x3c010002, 0xac228fe0,
+0x3c020002, 0x8c428fc0, 0x10400005, 0x0,
+0x3c020002, 0x8c428f9c, 0x104000f0, 0x24020002,
+0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21,
+0x104000ea, 0x24020002, 0x3c020002, 0x8c428fc4,
+0x104000ef, 0x2404ffbf, 0x3c020002, 0x8c428f9c,
+0x3c030002, 0x8c638fc8, 0x441024, 0x641824,
0x10430004, 0x24020001, 0x3c010002, 0x100000e4,
-0xac229010, 0x24020003, 0xaca20000, 0x24020008,
-0x3c010002, 0xac229010, 0x3c020002, 0x8c42904c,
-0x1040000c, 0x24020001, 0x3c040002, 0xc0050c1,
-0x8c84901c, 0x3c020002, 0x8c429068, 0x14400005,
-0x24020001, 0x3c020002, 0x8c429064, 0x10400006,
-0x24020001, 0x3c010001, 0xac226e1c, 0x3c010002,
-0x100000cb, 0xac209038, 0x3c020002, 0x8c429030,
-0x3c030002, 0x8c63901c, 0x2c420001, 0x210c0,
-0x30630008, 0x3c010002, 0xac229030, 0x3c010002,
-0xac23902c, 0x8f830054, 0x24020009, 0x3c010002,
-0xac229010, 0x3c010002, 0x100000b9, 0xac239034,
-0x8f830054, 0x3c020002, 0x8c429034, 0x2463d8f0,
+0xac228f90, 0x24020003, 0xaca20000, 0x24020008,
+0x3c010002, 0xac228f90, 0x3c020002, 0x8c428fcc,
+0x1040000c, 0x24020001, 0x3c040002, 0xc005091,
+0x8c848f9c, 0x3c020002, 0x8c428fe8, 0x14400005,
+0x24020001, 0x3c020002, 0x8c428fe4, 0x10400006,
+0x24020001, 0x3c010001, 0xac226d9c, 0x3c010002,
+0x100000cb, 0xac208fb8, 0x3c020002, 0x8c428fb0,
+0x3c030002, 0x8c638f9c, 0x2c420001, 0x210c0,
+0x30630008, 0x3c010002, 0xac228fb0, 0x3c010002,
+0xac238fac, 0x8f830054, 0x24020009, 0x3c010002,
+0xac228f90, 0x3c010002, 0x100000b9, 0xac238fb4,
+0x8f830054, 0x3c020002, 0x8c428fb4, 0x2463d8f0,
0x431023, 0x2c422710, 0x1440009f, 0x0,
-0x3c020002, 0x8c429040, 0x10400005, 0x0,
-0x3c020002, 0x8c42901c, 0x104000a0, 0x24020002,
-0x3c030002, 0x24639020, 0x8c620000, 0x2c424e21,
-0x1040009a, 0x24020002, 0x3c020002, 0x8c42904c,
-0x1040000e, 0x0, 0x3c020002, 0x8c42901c,
-0x3c010002, 0xac20904c, 0x30420080, 0x1040002f,
+0x3c020002, 0x8c428fc0, 0x10400005, 0x0,
+0x3c020002, 0x8c428f9c, 0x104000a0, 0x24020002,
+0x3c030002, 0x24638fa0, 0x8c620000, 0x2c424e21,
+0x1040009a, 0x24020002, 0x3c020002, 0x8c428fcc,
+0x1040000e, 0x0, 0x3c020002, 0x8c428f9c,
+0x3c010002, 0xac208fcc, 0x30420080, 0x1040002f,
0x2402000c, 0x8f820204, 0x30420080, 0x1440000c,
0x24020003, 0x10000029, 0x2402000c, 0x3c020002,
-0x8c42901c, 0x30420080, 0x14400005, 0x24020003,
+0x8c428f9c, 0x30420080, 0x14400005, 0x24020003,
0x8f820204, 0x30420080, 0x1040001f, 0x24020003,
-0xac620000, 0x2402000a, 0x3c010002, 0xac229010,
-0x3c040002, 0x24849058, 0x8c820000, 0x3c030002,
-0x8c639030, 0x431025, 0xaf820204, 0x8c830000,
-0x3c040002, 0x8c849030, 0x2402000b, 0x3c010002,
-0xac229010, 0x641825, 0x3c010002, 0xac239060,
-0x3c050002, 0x24a59020, 0x8ca20000, 0x2c424e21,
-0x10400066, 0x24020002, 0x3c020002, 0x8c429050,
+0xac620000, 0x2402000a, 0x3c010002, 0xac228f90,
+0x3c040002, 0x24848fd8, 0x8c820000, 0x3c030002,
+0x8c638fb0, 0x431025, 0xaf820204, 0x8c830000,
+0x3c040002, 0x8c848fb0, 0x2402000b, 0x3c010002,
+0xac228f90, 0x641825, 0x3c010002, 0xac238fe0,
+0x3c050002, 0x24a58fa0, 0x8ca20000, 0x2c424e21,
+0x10400066, 0x24020002, 0x3c020002, 0x8c428fd0,
0x10400005, 0x0, 0x2402000c, 0x3c010002,
-0x10000067, 0xac229010, 0x3c020002, 0x8c429040,
-0x10400063, 0x0, 0x3c040002, 0x8c84901c,
-0x10800055, 0x30820008, 0x3c030002, 0x8c63902c,
-0x1062005b, 0x24020003, 0x3c010002, 0xac249048,
+0x10000067, 0xac228f90, 0x3c020002, 0x8c428fc0,
+0x10400063, 0x0, 0x3c040002, 0x8c848f9c,
+0x10800055, 0x30820008, 0x3c030002, 0x8c638fac,
+0x1062005b, 0x24020003, 0x3c010002, 0xac248fc8,
0xaca20000, 0x24020006, 0x3c010002, 0x10000054,
-0xac229010, 0x8f820200, 0x34420002, 0xaf820200,
-0x8f830054, 0x2402000d, 0x3c010002, 0xac229010,
-0x3c010002, 0xac239034, 0x8f830054, 0x3c020002,
-0x8c429034, 0x2463d8f0, 0x431023, 0x2c422710,
-0x14400031, 0x0, 0x3c020002, 0x8c429050,
-0x10400020, 0x2402000e, 0x3c030002, 0x8c639064,
-0x3c010002, 0x14600015, 0xac229010, 0xc003e45,
-0x0, 0x3c050001, 0x8ca56e18, 0xc0052c7,
-0x2021, 0x3c030001, 0x8c636e18, 0x24020004,
-0x14620005, 0x2403fffb, 0x3c020001, 0x8c426e14,
-0x10000003, 0x2403fff7, 0x3c020001, 0x8c426e14,
-0x431024, 0x3c010001, 0xac226e14, 0x8f830224,
-0x3c020200, 0x3c010002, 0xac23906c, 0x10000020,
-0x282a025, 0x3c020002, 0x8c429040, 0x10400005,
-0x0, 0x3c020002, 0x8c42901c, 0x1040000f,
-0x24020002, 0x3c020002, 0x8c429020, 0x2c424e21,
-0x1040000a, 0x24020002, 0x3c020002, 0x8c429040,
-0x1040000f, 0x0, 0x3c020002, 0x8c42901c,
+0xac228f90, 0x8f820200, 0x34420002, 0xaf820200,
+0x8f830054, 0x2402000d, 0x3c010002, 0xac228f90,
+0x3c010002, 0xac238fb4, 0x8f830054, 0x3c020002,
+0x8c428fb4, 0x2463d8f0, 0x431023, 0x2c422710,
+0x14400031, 0x0, 0x3c020002, 0x8c428fd0,
+0x10400020, 0x2402000e, 0x3c030002, 0x8c638fe4,
+0x3c010002, 0x14600015, 0xac228f90, 0xc003e6d,
+0x0, 0x3c050001, 0x8ca56d98, 0xc00529b,
+0x2021, 0x3c030001, 0x8c636d98, 0x24020004,
+0x14620005, 0x2403fffb, 0x3c020001, 0x8c426d94,
+0x10000003, 0x2403fff7, 0x3c020001, 0x8c426d94,
+0x431024, 0x3c010001, 0xac226d94, 0x8f830224,
+0x3c020200, 0x3c010002, 0xac238fec, 0x10000020,
+0x282a025, 0x3c020002, 0x8c428fc0, 0x10400005,
+0x0, 0x3c020002, 0x8c428f9c, 0x1040000f,
+0x24020002, 0x3c020002, 0x8c428fa0, 0x2c424e21,
+0x1040000a, 0x24020002, 0x3c020002, 0x8c428fc0,
+0x1040000f, 0x0, 0x3c020002, 0x8c428f9c,
0x1440000b, 0x0, 0x24020002, 0x3c010002,
-0x10000007, 0xac229010, 0x3c020002, 0x8c429040,
-0x10400003, 0x0, 0xc003d87, 0x0,
+0x10000007, 0xac228f90, 0x3c020002, 0x8c428fc0,
+0x10400003, 0x0, 0xc003daf, 0x0,
0x8f820220, 0x3c03f700, 0x431025, 0xaf820220,
0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3c030002,
-0x24639068, 0x8c620000, 0x10400005, 0x34422000,
-0x3c010002, 0xac22905c, 0x10000003, 0xac600000,
-0x3c010002, 0xac24905c, 0x3e00008, 0x0,
+0x24638fe8, 0x8c620000, 0x10400005, 0x34422000,
+0x3c010002, 0xac228fdc, 0x10000003, 0xac600000,
+0x3c010002, 0xac248fdc, 0x3e00008, 0x0,
0x27bdffe0, 0x30820030, 0xafbf0018, 0x3c010002,
-0xac229064, 0x14400067, 0x3c02ffff, 0x34421f0e,
+0xac228fe4, 0x14400067, 0x3c02ffff, 0x34421f0e,
0x821024, 0x14400061, 0x24020030, 0x30822000,
0x1040005d, 0x30838000, 0x31a02, 0x30820001,
-0x21200, 0x3c040001, 0x8c846f9c, 0x621825,
-0x331c2, 0x3c030001, 0x24636ec8, 0x30828000,
+0x21200, 0x3c040001, 0x8c846f20, 0x621825,
+0x331c2, 0x3c030001, 0x24636e48, 0x30828000,
0x21202, 0x30840001, 0x42200, 0x441025,
0x239c2, 0x61080, 0x431021, 0x471021,
0x90430000, 0x24020001, 0x10620025, 0x0,
@@ -8775,354 +8758,357 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x1062002c, 0x3c05000f, 0x10000037, 0x0,
0x8f820200, 0x2403feff, 0x431024, 0xaf820200,
0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024,
-0xaf820220, 0x3c010002, 0xac209084, 0x3c010002,
-0x10000034, 0xac20908c, 0x8f820200, 0x34420100,
+0xaf820220, 0x3c010002, 0xac209004, 0x3c010002,
+0x10000034, 0xac20900c, 0x8f820200, 0x34420100,
0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff,
0x431024, 0xaf820220, 0x24020100, 0x3c010002,
-0xac229084, 0x3c010002, 0x10000026, 0xac20908c,
+0xac229004, 0x3c010002, 0x10000026, 0xac20900c,
0x8f820200, 0x2403feff, 0x431024, 0xaf820200,
0x8f820220, 0x3c030001, 0x431025, 0xaf820220,
-0x3c010002, 0xac209084, 0x3c010002, 0x10000019,
-0xac23908c, 0x8f820200, 0x34420100, 0xaf820200,
+0x3c010002, 0xac209004, 0x3c010002, 0x10000019,
+0xac23900c, 0x8f820200, 0x34420100, 0xaf820200,
0x8f820220, 0x3c030001, 0x431025, 0xaf820220,
-0x24020100, 0x3c010002, 0xac229084, 0x3c010002,
-0x1000000c, 0xac23908c, 0x34a5ffff, 0x3c040001,
-0x24846cb8, 0xafa30010, 0xc002b17, 0xafa00014,
+0x24020100, 0x3c010002, 0xac229004, 0x3c010002,
+0x1000000c, 0xac23900c, 0x34a5ffff, 0x3c040001,
+0x24846c38, 0xafa30010, 0xc002b3b, 0xafa00014,
0x10000004, 0x0, 0x24020030, 0x3c010002,
-0xac229068, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0xac228fe8, 0x8fbf0018, 0x3e00008, 0x27bd0020,
0x0, 0x0, 0x0, 0x27bdffc8,
0xafb20028, 0x809021, 0xafb3002c, 0xa09821,
-0xafb00020, 0xc08021, 0x3c040001, 0x24846cd0,
-0x3c050009, 0x3c020001, 0x8c426e18, 0x34a59001,
+0xafb00020, 0xc08021, 0x3c040001, 0x24846c50,
+0x3c050009, 0x3c020001, 0x8c426d98, 0x34a59001,
0x2403021, 0x2603821, 0xafbf0030, 0xafb10024,
-0xa7a0001a, 0xafb00014, 0xc002b17, 0xafa20010,
-0x24020002, 0x1262007f, 0x2e620003, 0x10400005,
-0x24020001, 0x1262000a, 0x0, 0x1000016f,
-0x0, 0x24020004, 0x126200f4, 0x24020008,
-0x126200f3, 0x3c02ffec, 0x10000168, 0x0,
-0x3c020001, 0x8c426e14, 0x30420002, 0x14400004,
+0xa7a0001a, 0xafb00014, 0xc002b3b, 0xafa20010,
+0x24020002, 0x12620083, 0x2e620003, 0x10400005,
+0x24020001, 0x1262000a, 0x0, 0x10000173,
+0x0, 0x24020004, 0x126200f8, 0x24020008,
+0x126200f7, 0x3c02ffec, 0x1000016c, 0x0,
+0x3c020001, 0x8c426d94, 0x30420002, 0x14400004,
0x128940, 0x3c02fffb, 0x3442ffff, 0x2028024,
-0x3c010002, 0x310821, 0xac30907c, 0x3c024000,
-0x2021024, 0x1040004a, 0x1023c2, 0x30840030,
-0x101382, 0x3042001c, 0x3c030001, 0x24636e58,
+0x3c010002, 0x310821, 0xac308ffc, 0x3c024000,
+0x2021024, 0x1040004e, 0x1023c2, 0x30840030,
+0x101382, 0x3042001c, 0x3c030001, 0x24636dd8,
0x431021, 0x823821, 0x3c020020, 0x2021024,
0x10400006, 0x24020100, 0x3c010002, 0x310821,
-0xac229080, 0x10000005, 0x3c020080, 0x3c010002,
-0x310821, 0xac209080, 0x3c020080, 0x2021024,
+0xac229000, 0x10000005, 0x3c020080, 0x3c010002,
+0x310821, 0xac209000, 0x3c020080, 0x2021024,
0x10400006, 0x121940, 0x3c020001, 0x3c010002,
-0x230821, 0x10000005, 0xac229088, 0x121140,
-0x3c010002, 0x220821, 0xac209088, 0x94e30000,
-0x32024000, 0x10400003, 0xa7a30018, 0x34624000,
+0x230821, 0x10000005, 0xac229008, 0x121140,
+0x3c010002, 0x220821, 0xac209008, 0x94e40000,
+0x3c030001, 0x8c636f40, 0x24020005, 0x10620010,
+0xa7a40018, 0x32024000, 0x10400002, 0x34824000,
0xa7a20018, 0x24040001, 0x94e20002, 0x24050004,
-0x24e60002, 0x34420001, 0xc00450e, 0xa4e20002,
-0x24040001, 0x2821, 0xc00450e, 0x27a60018,
-0x3c020001, 0x8c426e18, 0x24110001, 0x3c010001,
-0xac316e24, 0x14530004, 0x32028000, 0xc003d87,
+0x24e60002, 0x34420001, 0xc0045be, 0xa4e20002,
+0x24040001, 0x2821, 0xc0045be, 0x27a60018,
+0x3c020001, 0x8c426d98, 0x24110001, 0x3c010001,
+0xac316da4, 0x14530004, 0x32028000, 0xc003daf,
0x0, 0x32028000, 0x1040011c, 0x0,
-0xc003d87, 0x0, 0x3c030001, 0x8c636fb8,
+0xc003daf, 0x0, 0x3c030001, 0x8c636f40,
0x24020005, 0x10620115, 0x24020002, 0x3c010001,
-0xac316e1c, 0x3c010001, 0x10000110, 0xac226e18,
-0x24040001, 0x24050004, 0x27b0001a, 0xc00450e,
-0x2003021, 0x24040001, 0x2821, 0xc00450e,
-0x2003021, 0x3c020002, 0x511021, 0x8c429074,
-0x3c040001, 0x8c846e18, 0x3c03bfff, 0x3463ffff,
-0x3c010001, 0xac336e24, 0x431024, 0x3c010002,
-0x310821, 0x109300f7, 0xac229074, 0x100000f7,
+0xac316d9c, 0x3c010001, 0x10000110, 0xac226d98,
+0x24040001, 0x24050004, 0x27b0001a, 0xc0045be,
+0x2003021, 0x24040001, 0x2821, 0xc0045be,
+0x2003021, 0x3c020002, 0x511021, 0x8c428ff4,
+0x3c040001, 0x8c846d98, 0x3c03bfff, 0x3463ffff,
+0x3c010001, 0xac336da4, 0x431024, 0x3c010002,
+0x310821, 0x109300f7, 0xac228ff4, 0x100000f7,
0x0, 0x3c022000, 0x2021024, 0x10400005,
-0x24020001, 0x3c010001, 0xac226f98, 0x10000004,
-0x128940, 0x3c010001, 0xac206f98, 0x128940,
-0x3c010002, 0x310821, 0xac309078, 0x3c024000,
+0x24020001, 0x3c010001, 0xac226f1c, 0x10000004,
+0x128940, 0x3c010001, 0xac206f1c, 0x128940,
+0x3c010002, 0x310821, 0xac308ff8, 0x3c024000,
0x2021024, 0x14400014, 0x0, 0x3c020001,
-0x8c426f98, 0x10400006, 0x24040004, 0x24050001,
-0xc004e0e, 0x24062000, 0x24020001, 0xaee204b8,
-0x3c020002, 0x511021, 0x8c429070, 0x3c03bfff,
+0x8c426f1c, 0x10400006, 0x24040004, 0x24050001,
+0xc004ddb, 0x24062000, 0x24020001, 0xaee204b8,
+0x3c020002, 0x511021, 0x8c428ff0, 0x3c03bfff,
0x3463ffff, 0x431024, 0x3c010002, 0x310821,
-0x100000d0, 0xac229070, 0x3c020001, 0x8c426f98,
+0x100000d0, 0xac228ff0, 0x3c020001, 0x8c426f1c,
0x10400028, 0x3c0300a0, 0x2031024, 0x5443000d,
-0x3c020020, 0x3c020001, 0x8c426f9c, 0x24030100,
-0x3c010002, 0x310821, 0xac239084, 0x3c030001,
-0x3c010002, 0x310821, 0xac23908c, 0x10000015,
+0x3c020020, 0x3c020001, 0x8c426f20, 0x24030100,
+0x3c010002, 0x310821, 0xac239004, 0x3c030001,
+0x3c010002, 0x310821, 0xac23900c, 0x10000015,
0x34420400, 0x2021024, 0x10400008, 0x24030100,
-0x3c020001, 0x8c426f9c, 0x3c010002, 0x310821,
-0xac239084, 0x1000000b, 0x34420800, 0x3c020080,
+0x3c020001, 0x8c426f20, 0x3c010002, 0x310821,
+0xac239004, 0x1000000b, 0x34420800, 0x3c020080,
0x2021024, 0x1040002e, 0x3c030001, 0x3c020001,
-0x8c426f9c, 0x3c010002, 0x310821, 0xac23908c,
-0x34420c00, 0x3c010001, 0xac226f9c, 0x10000025,
+0x8c426f20, 0x3c010002, 0x310821, 0xac23900c,
+0x34420c00, 0x3c010001, 0xac226f20, 0x10000025,
0x24040001, 0x3c020020, 0x2021024, 0x10400006,
-0x24020100, 0x3c010002, 0x310821, 0xac229084,
+0x24020100, 0x3c010002, 0x310821, 0xac229004,
0x10000005, 0x3c020080, 0x3c010002, 0x310821,
-0xac209084, 0x3c020080, 0x2021024, 0x10400007,
+0xac209004, 0x3c020080, 0x2021024, 0x10400007,
0x121940, 0x3c020001, 0x3c010002, 0x230821,
-0xac22908c, 0x10000006, 0x24040001, 0x121140,
-0x3c010002, 0x220821, 0xac20908c, 0x24040001,
-0x2821, 0x27b0001e, 0xc0044cc, 0x2003021,
-0x24040001, 0x2821, 0xc0044cc, 0x2003021,
-0x24040001, 0x24050001, 0x27b0001c, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050001, 0xc0044cc,
+0xac22900c, 0x10000006, 0x24040001, 0x121140,
+0x3c010002, 0x220821, 0xac20900c, 0x24040001,
+0x2821, 0x27b0001e, 0xc00457c, 0x2003021,
+0x24040001, 0x2821, 0xc00457c, 0x2003021,
+0x24040001, 0x24050001, 0x27b0001c, 0xc00457c,
+0x2003021, 0x24040001, 0x24050001, 0xc00457c,
0x2003021, 0x10000077, 0x0, 0x3c02ffec,
0x3442ffff, 0x2028024, 0x3c020008, 0x2028025,
-0x121140, 0x3c010002, 0x220821, 0xac309078,
+0x121140, 0x3c010002, 0x220821, 0xac308ff8,
0x3c022000, 0x2021024, 0x10400009, 0x0,
-0x3c020001, 0x8c426ec4, 0x14400005, 0x24020001,
-0x3c010001, 0xac226f98, 0x10000004, 0x3c024000,
-0x3c010001, 0xac206f98, 0x3c024000, 0x2021024,
-0x1440001d, 0x24020e01, 0x3c030001, 0x8c636f98,
-0xaf820238, 0x3c010001, 0xac206e30, 0x10600005,
-0x24022020, 0x3c010001, 0xac226f9c, 0x24020001,
+0x3c020001, 0x8c426e44, 0x14400005, 0x24020001,
+0x3c010001, 0xac226f1c, 0x10000004, 0x3c024000,
+0x3c010001, 0xac206f1c, 0x3c024000, 0x2021024,
+0x1440001d, 0x24020e01, 0x3c030001, 0x8c636f1c,
+0xaf820238, 0x3c010001, 0xac206db0, 0x10600005,
+0x24022020, 0x3c010001, 0xac226f20, 0x24020001,
0xaee204b8, 0x3c04bfff, 0x121940, 0x3c020002,
-0x431021, 0x8c429070, 0x3c050001, 0x8ca56e18,
+0x431021, 0x8c428ff0, 0x3c050001, 0x8ca56d98,
0x3484ffff, 0x441024, 0x3c010002, 0x230821,
-0xac229070, 0x24020001, 0x10a20044, 0x0,
-0x10000040, 0x0, 0x3c020001, 0x8c426f98,
-0x1040001c, 0x24022000, 0x3c010001, 0xac226f9c,
+0xac228ff0, 0x24020001, 0x10a20044, 0x0,
+0x10000040, 0x0, 0x3c020001, 0x8c426f1c,
+0x1040001c, 0x24022000, 0x3c010001, 0xac226f20,
0x3c0300a0, 0x2031024, 0x14430005, 0x121140,
-0x3402a000, 0x3c010001, 0x1000002d, 0xac226f9c,
-0x3c030002, 0x621821, 0x8c639078, 0x3c020020,
+0x3402a000, 0x3c010001, 0x1000002d, 0xac226f20,
+0x3c030002, 0x621821, 0x8c638ff8, 0x3c020020,
0x621024, 0x10400004, 0x24022001, 0x3c010001,
-0x10000023, 0xac226f9c, 0x3c020080, 0x621024,
+0x10000023, 0xac226f20, 0x3c020080, 0x621024,
0x1040001f, 0x3402a001, 0x3c010001, 0x1000001c,
-0xac226f9c, 0x3c020020, 0x2021024, 0x10400007,
+0xac226f20, 0x3c020020, 0x2021024, 0x10400007,
0x121940, 0x24020100, 0x3c010002, 0x230821,
-0xac229084, 0x10000006, 0x3c020080, 0x121140,
-0x3c010002, 0x220821, 0xac209084, 0x3c020080,
+0xac229004, 0x10000006, 0x3c020080, 0x121140,
+0x3c010002, 0x220821, 0xac209004, 0x3c020080,
0x2021024, 0x10400006, 0x121940, 0x3c020001,
-0x3c010002, 0x230821, 0x10000005, 0xac22908c,
-0x121140, 0x3c010002, 0x220821, 0xac20908c,
-0x3c030001, 0x8c636e18, 0x24020001, 0x10620003,
-0x0, 0xc003d87, 0x0, 0x8fbf0030,
+0x3c010002, 0x230821, 0x10000005, 0xac22900c,
+0x121140, 0x3c010002, 0x220821, 0xac20900c,
+0x3c030001, 0x8c636d98, 0x24020001, 0x10620003,
+0x0, 0xc003daf, 0x0, 0x8fbf0030,
0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
-0x3e00008, 0x27bd0038, 0x27bdffb8, 0xafbe003c,
-0x80f021, 0xafb30034, 0x9821, 0xafb20030,
-0x9021, 0xafb1002c, 0x8821, 0x24020002,
-0xafbf0040, 0xafb50038, 0xafb00028, 0xa7a00020,
-0xa7a00018, 0xa7a0001a, 0xa7a0001c, 0xa7a0001e,
-0x10a20142, 0xa7a00022, 0x2ca20003, 0x10400005,
-0x24020001, 0x10a2000a, 0x1ea940, 0x10000253,
-0x2201021, 0x24020004, 0x10a20203, 0x24020008,
-0x10a20202, 0x1e2940, 0x1000024c, 0x2201021,
-0x3c030002, 0x751821, 0x8c63907c, 0x3c024000,
-0x621024, 0x14400009, 0x24040001, 0x3c027fff,
-0x3442ffff, 0x628824, 0x3c010002, 0x350821,
-0xac319074, 0x1000023d, 0x2201021, 0x2821,
-0xc0044cc, 0x27a60018, 0x24040001, 0x2821,
-0xc0044cc, 0x27a60018, 0x24040001, 0x24050001,
-0x27b0001a, 0xc0044cc, 0x2003021, 0x24040001,
-0x24050001, 0xc0044cc, 0x2003021, 0x24040001,
-0x24050004, 0x27b0001c, 0xc0044cc, 0x2003021,
-0x24040001, 0x24050004, 0xc0044cc, 0x2003021,
-0x24040001, 0x24050005, 0x27b0001e, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050005, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050009, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050009, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050001, 0xc0044cc,
-0x27a60018, 0x24040001, 0x24050001, 0xc0044cc,
-0x27a60018, 0x97a20018, 0x30420004, 0x104000ba,
-0x3c114000, 0x3c020001, 0x8c426fb8, 0x2443ffff,
-0x2c620006, 0x104000ba, 0x31080, 0x3c010001,
-0x220821, 0x8c226ce8, 0x400008, 0x0,
-0x24040001, 0x24050011, 0x27b00020, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050011, 0xc0044cc,
-0x2003021, 0x97a30020, 0x30624000, 0x10400002,
-0x3c120010, 0x3c120008, 0x3c130001, 0x30628000,
-0x54400098, 0x3c130002, 0x10000097, 0x3c028000,
-0x24040001, 0x24050014, 0x27b00020, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050014, 0xc0044cc,
-0x2003021, 0x97a30020, 0x30621000, 0x10400002,
-0x3c120010, 0x3c120008, 0x3c130001, 0x1000ffec,
-0x30620800, 0x24040001, 0x24050019, 0x27b00022,
-0xc0044cc, 0x2003021, 0x24040001, 0x24050019,
-0xc0044cc, 0x2003021, 0x97a20022, 0x30430700,
-0x24020400, 0x10620027, 0x28620401, 0x1040000e,
-0x24020200, 0x1062001f, 0x28620201, 0x10400005,
-0x24020100, 0x5062001e, 0x3c130001, 0x1000001e,
-0x24040001, 0x24020300, 0x50620019, 0x3c130002,
-0x10000019, 0x24040001, 0x24020600, 0x1062000d,
-0x28620601, 0x10400005, 0x24020500, 0x5062000b,
-0x3c130002, 0x10000010, 0x24040001, 0x24020700,
-0x1462000d, 0x24040001, 0x3c130004, 0x1000000a,
-0x3c120008, 0x10000006, 0x3c130004, 0x10000005,
-0x3c120008, 0x3c130001, 0x10000002, 0x3c120008,
-0x3c120010, 0x24040001, 0x24050010, 0x27b0001c,
-0xc0044cc, 0x2003021, 0x24040001, 0x24050010,
-0xc0044cc, 0x2003021, 0x3c020004, 0x16620010,
-0x3c020001, 0x8f840054, 0x24030001, 0x24020002,
-0x3c010001, 0xac236e1c, 0x3c010001, 0xac226e18,
-0x3c010001, 0xac236e24, 0x3c010001, 0xac236ea4,
-0x3c010001, 0xac246fa8, 0x10000041, 0x2538825,
-0x16620035, 0x3c028000, 0x3c020001, 0x8c426ea0,
-0x1440001e, 0x24040018, 0x2021, 0x2821,
-0xc004e0e, 0x34068000, 0x8f830054, 0x8f820054,
-0x2538825, 0x10000002, 0x24630032, 0x8f820054,
-0x621023, 0x2c420033, 0x1440fffc, 0x0,
-0x8f830054, 0x24020001, 0x3c010001, 0xac226ea0,
-0x3c010001, 0xac226e1c, 0x3c010001, 0xac226e18,
-0x3c010001, 0xac226e24, 0x3c010001, 0xac226ea4,
-0x3c010001, 0x1000001e, 0xac236fa8, 0x2821,
-0xc004e0e, 0x24060404, 0x2021, 0x2405001e,
-0x27a60018, 0x24020002, 0xc00450e, 0xa7a20018,
-0x2021, 0x2821, 0x27a60018, 0xc00450e,
-0xa7a00018, 0x24040018, 0x24050002, 0xc004e0e,
-0x24060004, 0x3c028000, 0x2221025, 0x2721825,
-0x10000007, 0x438825, 0x3c110002, 0x2358821,
-0x8e31907c, 0x3c027fff, 0x3442ffff, 0x2228824,
-0x3c020001, 0x8c426e28, 0x1040001c, 0x0,
-0x3c020001, 0x8c426f98, 0x10400002, 0x3c022000,
-0x2228825, 0x1e1140, 0x3c010002, 0x220821,
-0x8c229080, 0x10400003, 0x3c020020, 0x10000004,
+0x3e00008, 0x27bd0038, 0x27bdffb0, 0xafb3003c,
+0x9821, 0xafb50040, 0xa821, 0xafb10034,
+0x8821, 0x24020002, 0xafbf0048, 0xafbe0044,
+0xafb20038, 0xafb00030, 0xafa4002c, 0xa7a0001a,
+0xa7a00018, 0xa7a00020, 0xa7a0001e, 0xa7a00022,
+0x10a20130, 0xa7a0001c, 0x2ca20003, 0x10400005,
+0x24020001, 0x10a2000a, 0x3c024000, 0x1000025d,
+0x2201021, 0x24020004, 0x10a2020a, 0x24020008,
+0x10a20208, 0x2201021, 0x10000256, 0x0,
+0x8fa8002c, 0x88140, 0x3c030002, 0x701821,
+0x8c638ffc, 0x621024, 0x14400009, 0x24040001,
+0x3c027fff, 0x3442ffff, 0x628824, 0x3c010002,
+0x300821, 0xac318ff4, 0x10000246, 0x2201021,
+0x24050001, 0xc00457c, 0x27a60018, 0x24040001,
+0x24050001, 0xc00457c, 0x27a60018, 0x97a20018,
+0x30420004, 0x104000d9, 0x3c114000, 0x3c020001,
+0x8c426f40, 0x2443ffff, 0x2c620006, 0x104000d9,
+0x31080, 0x3c010001, 0x220821, 0x8c226c68,
+0x400008, 0x0, 0x24040001, 0x24050011,
+0x27b0001a, 0xc00457c, 0x2003021, 0x24040001,
+0x24050011, 0xc00457c, 0x2003021, 0x97a3001a,
+0x30624000, 0x10400002, 0x3c150010, 0x3c150008,
+0x30628000, 0x104000aa, 0x3c130001, 0x100000a8,
+0x3c130002, 0x24040001, 0x24050014, 0x27b0001a,
+0xc00457c, 0x2003021, 0x24040001, 0x24050014,
+0xc00457c, 0x2003021, 0x97a3001a, 0x30621000,
+0x10400002, 0x3c150010, 0x3c150008, 0x30620800,
+0x10400097, 0x3c130001, 0x10000095, 0x3c130002,
+0x24040001, 0x24050019, 0x27b0001c, 0xc00457c,
+0x2003021, 0x24040001, 0x24050019, 0xc00457c,
+0x2003021, 0x97a2001c, 0x30430700, 0x24020400,
+0x10620027, 0x28620401, 0x1040000e, 0x24020200,
+0x1062001f, 0x28620201, 0x10400005, 0x24020100,
+0x5062001e, 0x3c130001, 0x1000001e, 0x24040001,
+0x24020300, 0x50620019, 0x3c130002, 0x10000019,
+0x24040001, 0x24020600, 0x1062000d, 0x28620601,
+0x10400005, 0x24020500, 0x5062000b, 0x3c130002,
+0x10000010, 0x24040001, 0x24020700, 0x1462000d,
+0x24040001, 0x3c130004, 0x1000000a, 0x3c150008,
+0x10000006, 0x3c130004, 0x10000005, 0x3c150008,
+0x3c130001, 0x10000002, 0x3c150008, 0x3c150010,
+0x24040001, 0x24050018, 0x27b0001e, 0xc00457c,
+0x2003021, 0x24040001, 0x24050018, 0xc00457c,
+0x2003021, 0x8fa8002c, 0x97a7001e, 0x81140,
+0x3c060002, 0xc23021, 0x8cc68ff4, 0x97a20022,
+0x3c100001, 0x26106c5c, 0x2002021, 0xafa20010,
+0x97a2001c, 0x3c05000c, 0x34a50303, 0xc002b3b,
+0xafa20014, 0x3c020004, 0x16620010, 0x3c020001,
+0x8f840054, 0x24030001, 0x24020002, 0x3c010001,
+0xac236d9c, 0x3c010001, 0xac226d98, 0x3c010001,
+0xac236da4, 0x3c010001, 0xac236e24, 0x3c010001,
+0xac246f30, 0x1000004f, 0x2b38825, 0x16620039,
+0x3c028000, 0x3c020001, 0x8c426e20, 0x1440001e,
+0x24040018, 0x2021, 0x2821, 0xc004ddb,
+0x34068000, 0x8f830054, 0x8f820054, 0x2b38825,
+0x10000002, 0x24630032, 0x8f820054, 0x621023,
+0x2c420033, 0x1440fffc, 0x0, 0x8f830054,
+0x24020001, 0x3c010001, 0xac226e20, 0x3c010001,
+0xac226d9c, 0x3c010001, 0xac226d98, 0x3c010001,
+0xac226da4, 0x3c010001, 0xac226e24, 0x3c010001,
+0x1000002c, 0xac236f30, 0x2821, 0xc004ddb,
+0x24060404, 0x2021, 0x2405001e, 0x27a60018,
+0x24020002, 0xc0045be, 0xa7a20018, 0x2021,
+0x2821, 0x27a60018, 0xc0045be, 0xa7a00018,
+0x24040018, 0x24050002, 0xc004ddb, 0x24060004,
+0x3c028000, 0x2221025, 0x2b31825, 0x10000015,
+0x438825, 0x2221025, 0x2751825, 0x438825,
+0x2002021, 0x97a6001c, 0x3c070001, 0x8ce76d98,
+0x3c05000c, 0x34a50326, 0xafb30010, 0xc002b3b,
+0xafb10014, 0x10000007, 0x0, 0x3c110002,
+0x2308821, 0x8e318ffc, 0x3c027fff, 0x3442ffff,
+0x2228824, 0x3c020001, 0x8c426da8, 0x1040001e,
+0x0, 0x3c020001, 0x8c426f1c, 0x10400002,
+0x3c022000, 0x2228825, 0x8fa8002c, 0x81140,
+0x3c010002, 0x220821, 0x8c229000, 0x10400003,
+0x3c020020, 0x10000005, 0x2228825, 0x3c02ffdf,
+0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140,
+0x3c010002, 0x220821, 0x8c229008, 0x10400003,
+0x3c020080, 0x10000004, 0x2228825, 0x3c02ff7f,
+0x3442ffff, 0x2228824, 0x8fa8002c, 0x81140,
+0x3c010002, 0x220821, 0xac318ff4, 0x10000135,
+0x2201021, 0x8fa8002c, 0x8f140, 0x3c030002,
+0x7e1821, 0x8c638ff8, 0x3c024000, 0x621024,
+0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff,
+0x628824, 0x3c010002, 0x3e0821, 0xac318ff0,
+0x10000124, 0x2201021, 0x2821, 0xc00457c,
+0x27a60018, 0x24040001, 0x2821, 0xc00457c,
+0x27a60018, 0x24040001, 0x24050001, 0x27b20020,
+0xc00457c, 0x2403021, 0x24040001, 0x24050001,
+0xc00457c, 0x2403021, 0x24040001, 0x24050004,
+0x27b1001e, 0xc00457c, 0x2203021, 0x24040001,
+0x24050004, 0xc00457c, 0x2203021, 0x24040001,
+0x24050005, 0x27b00022, 0xc00457c, 0x2003021,
+0x24040001, 0x24050005, 0xc00457c, 0x2003021,
+0x24040001, 0x24050010, 0xc00457c, 0x27a60018,
+0x24040001, 0x24050010, 0xc00457c, 0x27a60018,
+0x24040001, 0x2405000a, 0xc00457c, 0x2403021,
+0x24040001, 0x2405000a, 0xc00457c, 0x2403021,
+0x24040001, 0x24050018, 0xc00457c, 0x2203021,
+0x24040001, 0x24050018, 0xc00457c, 0x2203021,
+0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
+0x24040001, 0x24050001, 0xc00457c, 0x27a60018,
+0x97a20018, 0x30420004, 0x10400066, 0x3c114000,
+0x3c030001, 0x8c636f34, 0x24020005, 0x14620067,
+0x24040001, 0x24050019, 0x27b0001c, 0xc00457c,
+0x2003021, 0x24040001, 0x24050019, 0xc00457c,
+0x2003021, 0x97a2001c, 0x30430700, 0x24020400,
+0x10620027, 0x28620401, 0x1040000e, 0x24020200,
+0x1062001f, 0x28620201, 0x10400005, 0x24020100,
+0x5062001e, 0x3c130001, 0x1000001e, 0x3c020004,
+0x24020300, 0x50620019, 0x3c130002, 0x10000019,
+0x3c020004, 0x24020600, 0x1062000d, 0x28620601,
+0x10400005, 0x24020500, 0x5062000b, 0x3c130002,
+0x10000010, 0x3c020004, 0x24020700, 0x1462000d,
+0x3c020004, 0x3c130004, 0x1000000a, 0x3c150008,
+0x10000006, 0x3c130004, 0x10000005, 0x3c150008,
+0x3c130001, 0x10000002, 0x3c150008, 0x3c150010,
+0x3c020004, 0x12620017, 0x3c028000, 0x8f820054,
+0x24100001, 0x3c010001, 0xac306d9c, 0x3c010001,
+0xac306d98, 0x3c010001, 0xac306da4, 0x3c010001,
+0xac306e24, 0x3c010001, 0xac226f30, 0x3c020001,
+0x16620022, 0x2758825, 0x2021, 0x2821,
+0xc004ddb, 0x34068000, 0x3c010001, 0x1000001b,
+0xac306e20, 0x2221025, 0x2b31825, 0x438825,
+0x97a6001c, 0x3c020001, 0x8c426f1c, 0x3c070001,
+0x8ce76d98, 0x3c040001, 0x24846c5c, 0xafa20010,
+0x97a2001e, 0x3c05000c, 0x34a50323, 0x3c010001,
+0xac206e20, 0xc002b3b, 0xafa20014, 0x10000007,
+0x0, 0x3c110002, 0x23e8821, 0x8e318ff0,
+0x3c027fff, 0x3442ffff, 0x2228824, 0x3c020001,
+0x8c426da8, 0x10400069, 0x0, 0x3c020001,
+0x8c426f1c, 0x10400002, 0x3c022000, 0x2228825,
+0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
+0x8c229004, 0x10400003, 0x3c020020, 0x10000005,
0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x1e1140, 0x3c010002, 0x220821, 0x8c229088,
-0x10400003, 0x3c020080, 0x10000004, 0x2228825,
-0x3c02ff7f, 0x3442ffff, 0x2228824, 0x3c040001,
-0x24846cdc, 0x3c05000c, 0x97a60022, 0x3c070001,
-0x8ce76e18, 0x34a50326, 0x1e1140, 0x3c010002,
-0x220821, 0xac319074, 0xafb30010, 0xc002b17,
-0xafb10014, 0x10000119, 0x2201021, 0x1ea940,
-0x3c030002, 0x751821, 0x8c639078, 0x3c024000,
-0x621024, 0x14400009, 0x24040001, 0x3c027fff,
-0x3442ffff, 0x628824, 0x3c010002, 0x350821,
-0xac319070, 0x10000109, 0x2201021, 0x2821,
-0xc0044cc, 0x27a60018, 0x24040001, 0x2821,
-0xc0044cc, 0x27a60018, 0x24040001, 0x24050001,
-0x27b1001a, 0xc0044cc, 0x2203021, 0x24040001,
-0x24050001, 0xc0044cc, 0x2203021, 0x24040001,
-0x24050004, 0x27b0001c, 0xc0044cc, 0x2003021,
-0x24040001, 0x24050004, 0xc0044cc, 0x2003021,
-0x24040001, 0x24050005, 0x27b0001e, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050005, 0xc0044cc,
-0x2003021, 0x24040001, 0x24050010, 0xc0044cc,
-0x27a60018, 0x24040001, 0x24050010, 0xc0044cc,
-0x27a60018, 0x24040001, 0x2405000a, 0xc0044cc,
-0x2203021, 0x24040001, 0x2405000a, 0xc0044cc,
-0x2203021, 0x24040001, 0x24050001, 0xc0044cc,
-0x27a60018, 0x24040001, 0x24050001, 0xc0044cc,
-0x27a60018, 0x97a20018, 0x30420004, 0x10400058,
-0x3c114000, 0x3c030001, 0x8c636fac, 0x24020005,
-0x14620059, 0x24040001, 0x24050019, 0x27b00022,
-0xc0044cc, 0x2003021, 0x24040001, 0x24050019,
-0xc0044cc, 0x2003021, 0x97a20022, 0x30430700,
-0x24020400, 0x10620027, 0x28620401, 0x1040000e,
-0x24020200, 0x1062001f, 0x28620201, 0x10400005,
-0x24020100, 0x5062001e, 0x3c130001, 0x1000001e,
-0x3c020004, 0x24020300, 0x50620019, 0x3c130002,
-0x10000019, 0x3c020004, 0x24020600, 0x1062000d,
-0x28620601, 0x10400005, 0x24020500, 0x5062000b,
-0x3c130002, 0x10000010, 0x3c020004, 0x24020700,
-0x1462000d, 0x3c020004, 0x3c130004, 0x1000000a,
-0x3c120008, 0x10000006, 0x3c130004, 0x10000005,
-0x3c120008, 0x3c130001, 0x10000002, 0x3c120008,
-0x3c120010, 0x3c020004, 0x12620017, 0x3c028000,
-0x8f820054, 0x24100001, 0x3c010001, 0xac306e1c,
-0x3c010001, 0xac306e18, 0x3c010001, 0xac306e24,
-0x3c010001, 0xac306ea4, 0x3c010001, 0xac226fa8,
-0x3c020001, 0x16620014, 0x2728825, 0x2021,
-0x2821, 0xc004e0e, 0x34068000, 0x3c010001,
-0x1000000d, 0xac306ea0, 0x2221025, 0x2531825,
-0x3c010001, 0xac206ea0, 0x10000007, 0x438825,
-0x3c110002, 0x2358821, 0x8e319070, 0x3c027fff,
-0x3442ffff, 0x2228824, 0x3c020001, 0x8c426e28,
-0x10400066, 0x1e1140, 0x3c020001, 0x8c426f98,
-0x10400002, 0x3c022000, 0x2228825, 0x1e1140,
-0x3c010002, 0x220821, 0x8c229084, 0x10400003,
-0x3c020020, 0x10000004, 0x2228825, 0x3c02ffdf,
-0x3442ffff, 0x2228824, 0x1e1140, 0x3c010002,
-0x220821, 0x8c22908c, 0x10400003, 0x3c020080,
-0x1000004d, 0x2228825, 0x3c02ff7f, 0x3442ffff,
-0x10000049, 0x2228824, 0x1e2940, 0x3c030002,
-0x651821, 0x8c639078, 0x3c024000, 0x621024,
+0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
+0x8c22900c, 0x10400003, 0x3c020080, 0x1000004f,
+0x2228825, 0x3c02ff7f, 0x3442ffff, 0x1000004b,
+0x2228824, 0x8fa8002c, 0x82940, 0x3c030002,
+0x651821, 0x8c638ff8, 0x3c024000, 0x621024,
0x14400008, 0x3c027fff, 0x3442ffff, 0x628824,
-0x3c010002, 0x250821, 0xac319070, 0x1000003f,
-0x2201021, 0x3c020001, 0x8c426e28, 0x10400033,
-0x3c11c00c, 0x3c020001, 0x8c426ec4, 0x3c04c00c,
-0x34842000, 0x3c030001, 0x8c636f98, 0x2102b,
+0x3c010002, 0x250821, 0xac318ff0, 0x10000041,
+0x2201021, 0x3c020001, 0x8c426da8, 0x10400034,
+0x3c11c00c, 0x3c020001, 0x8c426e44, 0x3c04c00c,
+0x34842000, 0x3c030001, 0x8c636f1c, 0x2102b,
0x21023, 0x441024, 0x10600003, 0x518825,
0x3c022000, 0x2228825, 0x3c020002, 0x451021,
-0x8c429084, 0x10400003, 0x3c020020, 0x10000004,
+0x8c429004, 0x10400003, 0x3c020020, 0x10000004,
0x2228825, 0x3c02ffdf, 0x3442ffff, 0x2228824,
-0x1e1140, 0x3c010002, 0x220821, 0x8c22908c,
-0x10400003, 0x3c020080, 0x10000004, 0x2228825,
-0x3c02ff7f, 0x3442ffff, 0x2228824, 0x3c020001,
-0x8c426eb0, 0x10400002, 0x3c020800, 0x2228825,
-0x3c020001, 0x8c426eb4, 0x10400002, 0x3c020400,
-0x2228825, 0x3c020001, 0x8c426eb8, 0x10400006,
-0x3c020100, 0x10000004, 0x2228825, 0x3c027fff,
-0x3442ffff, 0x628824, 0x1e1140, 0x3c010002,
-0x220821, 0xac319070, 0x2201021, 0x8fbf0040,
-0x8fbe003c, 0x8fb50038, 0x8fb30034, 0x8fb20030,
-0x8fb1002c, 0x8fb00028, 0x3e00008, 0x27bd0048,
-0x27bdffd0, 0xafb20028, 0x809021, 0xafbf002c,
-0xafb10024, 0xafb00020, 0x8f840200, 0x3c100001,
-0x8e106e18, 0x8f860220, 0x24020002, 0x1202005c,
-0x2e020003, 0x10400005, 0x24020001, 0x1202000a,
-0x121940, 0x1000010c, 0x0, 0x24020004,
-0x120200bf, 0x24020008, 0x120200be, 0x128940,
-0x10000105, 0x0, 0x3c050002, 0xa32821,
-0x8ca5907c, 0x3c100002, 0x2038021, 0x8e109074,
-0x3c024000, 0xa21024, 0x10400038, 0x3c020008,
-0x2021024, 0x10400020, 0x34840002, 0x3c020002,
-0x431021, 0x8c429080, 0x10400005, 0x34840020,
-0x34840100, 0x3c020020, 0x10000006, 0x2028025,
-0x2402feff, 0x822024, 0x3c02ffdf, 0x3442ffff,
-0x2028024, 0x121140, 0x3c010002, 0x220821,
-0x8c229088, 0x10400005, 0x3c020001, 0xc23025,
-0x3c020080, 0x10000016, 0x2028025, 0x3c02fffe,
-0x3442ffff, 0xc23024, 0x3c02ff7f, 0x3442ffff,
-0x1000000f, 0x2028024, 0x2402fedf, 0x822024,
-0x3c02fffe, 0x3442ffff, 0xc23024, 0x3c02ff5f,
-0x3442ffff, 0x2028024, 0x3c010002, 0x230821,
-0xac209080, 0x3c010002, 0x230821, 0xac209088,
-0xaf840200, 0xaf860220, 0x8f820220, 0x34420002,
-0xaf820220, 0x1000000a, 0x121140, 0x3c02bfff,
-0x3442ffff, 0x8f830200, 0x2028024, 0x2402fffd,
-0x621824, 0xc003d87, 0xaf830200, 0x121140,
-0x3c010002, 0x220821, 0x100000b7, 0xac309074,
-0x3c020001, 0x8c426f98, 0x10400069, 0x24050004,
-0x24040001, 0xc0044cc, 0x27a60018, 0x24040001,
-0x24050005, 0xc0044cc, 0x27a6001a, 0x97a30018,
-0x97a2001a, 0x3c040001, 0x24846ec8, 0x30630c00,
-0x31a82, 0x30420c00, 0x21282, 0xa7a2001a,
-0x21080, 0x441021, 0x431021, 0xa7a30018,
-0x90480000, 0x24020001, 0x3103ffff, 0x10620029,
-0x28620002, 0x10400005, 0x0, 0x10600009,
-0x0, 0x1000003d, 0x0, 0x10700013,
-0x24020003, 0x1062002c, 0x0, 0x10000037,
-0x0, 0x8f820200, 0x2403feff, 0x431024,
-0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff,
-0x431024, 0xaf820220, 0x3c010002, 0xac209084,
-0x3c010002, 0x10000032, 0xac20908c, 0x8f820200,
-0x34420100, 0xaf820200, 0x8f820220, 0x3c03fffe,
-0x3463ffff, 0x431024, 0xaf820220, 0x24020100,
-0x3c010002, 0xac229084, 0x3c010002, 0x10000024,
-0xac20908c, 0x8f820200, 0x2403feff, 0x431024,
-0xaf820200, 0x8f820220, 0x3c030001, 0x431025,
-0xaf820220, 0x3c010002, 0xac209084, 0x3c010002,
-0x10000017, 0xac23908c, 0x8f820200, 0x34420100,
-0xaf820200, 0x8f820220, 0x3c030001, 0x431025,
-0xaf820220, 0x24020100, 0x3c010002, 0xac229084,
-0x3c010002, 0x1000000a, 0xac23908c, 0x3c040001,
-0x24846d00, 0x97a6001a, 0x97a70018, 0x3c050001,
-0x34a5ffff, 0xafa80010, 0xc002b17, 0xafa00014,
-0x8f820200, 0x34420002, 0x1000004b, 0xaf820200,
-0x128940, 0x3c050002, 0xb12821, 0x8ca59078,
-0x3c100002, 0x2118021, 0x8e109070, 0x3c024000,
-0xa21024, 0x14400010, 0x0, 0x3c020001,
-0x8c426f98, 0x14400005, 0x3c02bfff, 0x8f820200,
-0x34420002, 0xaf820200, 0x3c02bfff, 0x3442ffff,
-0xc003d87, 0x2028024, 0x3c010002, 0x310821,
-0x10000031, 0xac309070, 0x3c020001, 0x8c426f98,
-0x10400005, 0x3c020020, 0x3c020001, 0x8c426ec4,
-0x10400025, 0x3c020020, 0xa21024, 0x10400007,
-0x34840020, 0x24020100, 0x3c010002, 0x310821,
-0xac229084, 0x10000006, 0x34840100, 0x3c010002,
-0x310821, 0xac209084, 0x2402feff, 0x822024,
-0x3c020080, 0xa21024, 0x10400007, 0x121940,
-0x3c020001, 0x3c010002, 0x230821, 0xac22908c,
-0x10000008, 0xc23025, 0x121140, 0x3c010002,
-0x220821, 0xac20908c, 0x3c02fffe, 0x3442ffff,
-0xc23024, 0xaf840200, 0xaf860220, 0x8f820220,
-0x34420002, 0xaf820220, 0x121140, 0x3c010002,
-0x220821, 0xac309070, 0x8fbf002c, 0x8fb20028,
-0x8fb10024, 0x8fb00020, 0x3e00008, 0x27bd0030,
-0x0, 0x0, 0x0, 0x1821,
+0x8fa8002c, 0x81140, 0x3c010002, 0x220821,
+0x8c22900c, 0x10400003, 0x3c020080, 0x10000004,
+0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824,
+0x3c020001, 0x8c426e30, 0x10400002, 0x3c020800,
+0x2228825, 0x3c020001, 0x8c426e34, 0x10400002,
+0x3c020400, 0x2228825, 0x3c020001, 0x8c426e38,
+0x10400006, 0x3c020100, 0x10000004, 0x2228825,
+0x3c027fff, 0x3442ffff, 0x628824, 0x8fa8002c,
+0x81140, 0x3c010002, 0x220821, 0xac318ff0,
+0x2201021, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
+0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
+0x3e00008, 0x27bd0050, 0x27bdffd0, 0xafb20028,
+0x809021, 0xafbf002c, 0xafb10024, 0xafb00020,
+0x8f840200, 0x3c100001, 0x8e106d98, 0x8f860220,
+0x24020002, 0x1202005c, 0x2e020003, 0x10400005,
+0x24020001, 0x1202000a, 0x121940, 0x1000010c,
+0x0, 0x24020004, 0x120200bf, 0x24020008,
+0x120200be, 0x128940, 0x10000105, 0x0,
+0x3c050002, 0xa32821, 0x8ca58ffc, 0x3c100002,
+0x2038021, 0x8e108ff4, 0x3c024000, 0xa21024,
+0x10400038, 0x3c020008, 0x2021024, 0x10400020,
+0x34840002, 0x3c020002, 0x431021, 0x8c429000,
+0x10400005, 0x34840020, 0x34840100, 0x3c020020,
+0x10000006, 0x2028025, 0x2402feff, 0x822024,
+0x3c02ffdf, 0x3442ffff, 0x2028024, 0x121140,
+0x3c010002, 0x220821, 0x8c229008, 0x10400005,
+0x3c020001, 0xc23025, 0x3c020080, 0x10000016,
+0x2028025, 0x3c02fffe, 0x3442ffff, 0xc23024,
+0x3c02ff7f, 0x3442ffff, 0x1000000f, 0x2028024,
+0x2402fedf, 0x822024, 0x3c02fffe, 0x3442ffff,
+0xc23024, 0x3c02ff5f, 0x3442ffff, 0x2028024,
+0x3c010002, 0x230821, 0xac209000, 0x3c010002,
+0x230821, 0xac209008, 0xaf840200, 0xaf860220,
+0x8f820220, 0x34420002, 0xaf820220, 0x1000000a,
+0x121140, 0x3c02bfff, 0x3442ffff, 0x8f830200,
+0x2028024, 0x2402fffd, 0x621824, 0xc003daf,
+0xaf830200, 0x121140, 0x3c010002, 0x220821,
+0x100000b7, 0xac308ff4, 0x3c020001, 0x8c426f1c,
+0x10400069, 0x24050004, 0x24040001, 0xc00457c,
+0x27a60018, 0x24040001, 0x24050005, 0xc00457c,
+0x27a6001a, 0x97a30018, 0x97a2001a, 0x3c040001,
+0x24846e48, 0x30630c00, 0x31a82, 0x30420c00,
+0x21282, 0xa7a2001a, 0x21080, 0x441021,
+0x431021, 0xa7a30018, 0x90480000, 0x24020001,
+0x3103ffff, 0x10620029, 0x28620002, 0x10400005,
+0x0, 0x10600009, 0x0, 0x1000003d,
+0x0, 0x10700013, 0x24020003, 0x1062002c,
+0x0, 0x10000037, 0x0, 0x8f820200,
+0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
+0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220,
+0x3c010002, 0xac209004, 0x3c010002, 0x10000032,
+0xac20900c, 0x8f820200, 0x34420100, 0xaf820200,
+0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024,
+0xaf820220, 0x24020100, 0x3c010002, 0xac229004,
+0x3c010002, 0x10000024, 0xac20900c, 0x8f820200,
+0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
+0x3c030001, 0x431025, 0xaf820220, 0x3c010002,
+0xac209004, 0x3c010002, 0x10000017, 0xac23900c,
+0x8f820200, 0x34420100, 0xaf820200, 0x8f820220,
+0x3c030001, 0x431025, 0xaf820220, 0x24020100,
+0x3c010002, 0xac229004, 0x3c010002, 0x1000000a,
+0xac23900c, 0x3c040001, 0x24846c80, 0x97a6001a,
+0x97a70018, 0x3c050001, 0x34a5ffff, 0xafa80010,
+0xc002b3b, 0xafa00014, 0x8f820200, 0x34420002,
+0x1000004b, 0xaf820200, 0x128940, 0x3c050002,
+0xb12821, 0x8ca58ff8, 0x3c100002, 0x2118021,
+0x8e108ff0, 0x3c024000, 0xa21024, 0x14400010,
+0x0, 0x3c020001, 0x8c426f1c, 0x14400005,
+0x3c02bfff, 0x8f820200, 0x34420002, 0xaf820200,
+0x3c02bfff, 0x3442ffff, 0xc003daf, 0x2028024,
+0x3c010002, 0x310821, 0x10000031, 0xac308ff0,
+0x3c020001, 0x8c426f1c, 0x10400005, 0x3c020020,
+0x3c020001, 0x8c426e44, 0x10400025, 0x3c020020,
+0xa21024, 0x10400007, 0x34840020, 0x24020100,
+0x3c010002, 0x310821, 0xac229004, 0x10000006,
+0x34840100, 0x3c010002, 0x310821, 0xac209004,
+0x2402feff, 0x822024, 0x3c020080, 0xa21024,
+0x10400007, 0x121940, 0x3c020001, 0x3c010002,
+0x230821, 0xac22900c, 0x10000008, 0xc23025,
+0x121140, 0x3c010002, 0x220821, 0xac20900c,
+0x3c02fffe, 0x3442ffff, 0xc23024, 0xaf840200,
+0xaf860220, 0x8f820220, 0x34420002, 0xaf820220,
+0x121140, 0x3c010002, 0x220821, 0xac308ff0,
+0x8fbf002c, 0x8fb20028, 0x8fb10024, 0x8fb00020,
+0x3e00008, 0x27bd0030, 0x0, 0x1821,
0x308400ff, 0x2405ffdf, 0x2406ffbf, 0x641007,
0x30420001, 0x10400004, 0x0, 0x8f820044,
0x10000003, 0x34420040, 0x8f820044, 0x461024,
@@ -9131,7 +9117,7 @@ u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] __initdata = {
0x28620008, 0x5440ffee, 0x641007, 0x3e00008,
0x0, 0x2c820008, 0x1040001b, 0x0,
0x2405ffdf, 0x2406ffbf, 0x41880, 0x3c020001,
-0x24426ee0, 0x621821, 0x24640004, 0x90620000,
+0x24426e60, 0x621821, 0x24640004, 0x90620000,
0x10400004, 0x0, 0x8f820044, 0x10000003,
0x34420040, 0x8f820044, 0x461024, 0xaf820044,
0x8f820044, 0x34420020, 0xaf820044, 0x8f820044,
@@ -9180,7 +9166,7 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x74460000, 0x4d516576, 0x505f4600, 0x5173436f,
0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
0x51725072, 0x6f644600, 0x6261644d, 0x656d537a,
-0x0, 0x68774677, 0x56657200, 0x62616448,
+0x0, 0x68775665, 0x72000000, 0x62616448,
0x77566572, 0x0, 0x2a2a4441, 0x574e5f41,
0x0, 0x74785278, 0x4266537a, 0x0,
0x62664174, 0x6e4d726b, 0x0, 0x7265645a,
@@ -9276,12 +9262,12 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x0, 0x3f636d64, 0x48737453, 0x0,
0x3f636d64, 0x4d634d64, 0x0, 0x3f636d64,
0x50726f6d, 0x0, 0x3f636d64, 0x4c696e6b,
-0x0, 0x3f636d64, 0x45727200, 0x864c,
-0x8de0, 0x8de0, 0x8d68, 0x8b0c,
-0x8db4, 0x8de0, 0x8724, 0x8794,
-0x8924, 0x89fc, 0x89c8, 0x8de0,
-0x8804, 0x8ab8, 0x8de0, 0x8ac8,
-0x8748, 0x87b8, 0x0, 0x0,
+0x0, 0x3f636d64, 0x45727200, 0x86ac,
+0x8e5c, 0x8e5c, 0x8de4, 0x8b78,
+0x8e30, 0x8e5c, 0x8790, 0x8800,
+0x8990, 0x8a68, 0x8a34, 0x8e5c,
+0x8870, 0x8b24, 0x8e5c, 0x8b34,
+0x87b4, 0x8824, 0x0, 0x0,
0x0, 0x24486561, 0x6465723a, 0x202f7072,
0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
@@ -9332,10 +9318,10 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x2e313220, 0x31393939, 0x2f30312f, 0x32302031,
0x393a3439, 0x3a353120, 0x73687561, 0x6e672045,
0x78702024, 0x0, 0x46575f56, 0x45525349,
-0x4f4e3a20, 0x23312053, 0x61742044, 0x65632031,
-0x31203136, 0x3a30353a, 0x30332050, 0x53542031,
-0x39393900, 0x46575f43, 0x4f4d5049, 0x4c455f54,
-0x494d453a, 0x2031363a, 0x30353a30, 0x33000000,
+0x4f4e3a20, 0x23312046, 0x72692041, 0x70722037,
+0x2031373a, 0x35373a35, 0x32205044, 0x54203230,
+0x30300000, 0x46575f43, 0x4f4d5049, 0x4c455f54,
+0x494d453a, 0x2031373a, 0x35373a35, 0x32000000,
0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064,
0x65767263, 0x73000000, 0x46575f43, 0x4f4d5049,
0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465,
@@ -9343,7 +9329,7 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x4f4d4149, 0x4e3a2065, 0x6e672e61, 0x6374656f,
0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049,
0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e,
-0x20322e37, 0x2e320000, 0x0, 0x12040100,
+0x20322e37, 0x2e320000, 0x0, 0x12041100,
0x0, 0x24486561, 0x6465723a, 0x202f7072,
0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765,
0x2f2e2f6e, 0x69632f66, 0x77322f63, 0x6f6d6d6f,
@@ -9411,31 +9397,32 @@ u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] __initdata = {
0x6e495f46, 0x0, 0x5173436f, 0x6e734600,
0x51725072, 0x6f644600, 0x0, 0x0,
0x0, 0x50726f62, 0x65506879, 0x0,
-0x6c6e6b41, 0x53535254, 0x0, 0x108d0,
-0x10948, 0x10968, 0x109a4, 0x10ea8,
-0x109d0, 0x10a0c, 0x10f3c, 0x10c18,
-0x10ac0, 0x10ad8, 0x10b1c, 0x10b44,
-0x10b64, 0x10b8c, 0x10f3c, 0x10c18,
-0x10c50, 0x10c68, 0x10c98, 0x10cc0,
-0x10ce0, 0x10d08, 0x0, 0x10e34,
-0x10e60, 0x10e84, 0x10f3c, 0x10ea8,
-0x109d0, 0x10ed8, 0x0, 0x0,
-0x0, 0x115ac, 0x1167c, 0x11754,
-0x11824, 0x11880, 0x1195c, 0x11984,
-0x11a60, 0x11a88, 0x11c30, 0x11c58,
-0x11e00, 0x11ff8, 0x1228c, 0x121a0,
-0x1228c, 0x122b8, 0x11e28, 0x11fd0,
-0x7273745f, 0x676d6969, 0x0, 0x12348,
-0x12380, 0x12468, 0x13034, 0x135fc,
-0x13614, 0x13c7c, 0x13cbc, 0x13d4c,
-0x13d90, 0x13df4, 0x13e80, 0x13eb4,
-0x13f3c, 0x13fd4, 0x140a4, 0x140e4,
-0x14168, 0x1418c, 0x1429c, 0x646f4261,
+0x6c6e6b41, 0x53535254, 0x0, 0x109a4,
+0x10a1c, 0x10a50, 0x10a7c, 0x11050,
+0x10aa8, 0x10b10, 0x111fc, 0x10dc0,
+0x10c68, 0x10c80, 0x10cc4, 0x10cec,
+0x10d0c, 0x10d34, 0x111fc, 0x10dc0,
+0x10df8, 0x10e10, 0x10e40, 0x10e68,
+0x10e88, 0x10eb0, 0x0, 0x10fdc,
+0x11008, 0x1102c, 0x111fc, 0x11050,
+0x11078, 0x11108, 0x0, 0x0,
+0x0, 0x1186c, 0x1193c, 0x11a14,
+0x11ae4, 0x11b40, 0x11c1c, 0x11c44,
+0x11d20, 0x11d48, 0x11ef0, 0x11f18,
+0x120c0, 0x122b8, 0x1254c, 0x12460,
+0x1254c, 0x12578, 0x120e8, 0x12290,
+0x7273745f, 0x676d6969, 0x0, 0x12608,
+0x12640, 0x12728, 0x13374, 0x133b4,
+0x133cc, 0x7365746c, 0x6f6f7000, 0x0,
+0x0, 0x13bbc, 0x13bfc, 0x13c8c,
+0x13cd0, 0x13d34, 0x13dc0, 0x13df4,
+0x13e7c, 0x13f14, 0x13fe4, 0x14024,
+0x140a8, 0x140cc, 0x141dc, 0x646f4261,
0x73655067, 0x0, 0x0, 0x0,
0x0, 0x73746d61, 0x634c4e4b, 0x0,
-0x6765746d, 0x636c6e6b, 0x0, 0x14fb4,
-0x14fb4, 0x14ce4, 0x14d34, 0x14d78,
-0x14fb4, 0x7365746d, 0x61636163, 0x74000000,
+0x6765746d, 0x636c6e6b, 0x0, 0x14ed8,
+0x14ed8, 0x14b8c, 0x14bd8, 0x14c24,
+0x14ed8, 0x7365746d, 0x61636163, 0x74000000,
0x0, 0x0 };
u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] __initdata = {
0x1,
diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c
index 493c2f6c5..ff44715fd 100644
--- a/drivers/net/bsd_comp.c
+++ b/drivers/net/bsd_comp.c
@@ -1,3 +1,11 @@
+/*
+ * Update: The Berkeley copyright was changed, and the change
+ * is retroactive to all "true" BSD software (ie everything
+ * from UCB as opposed to other peoples code that just carried
+ * the same license). The new copyright doesn't clash with the
+ * GPL, so the module-only restriction has been removed..
+ */
+
/* Because this code is derived from the 4.3BSD compress source:
*
* Copyright (c) 1985, 1986 The Regents of the University of California.
@@ -53,10 +61,6 @@
* From: bsd_comp.c,v 1.3 1994/12/08 01:59:58 paulus Exp
*/
-#ifndef MODULE
-#error This file must be compiled as a module.
-#endif
-
#include <linux/module.h>
#include <linux/init.h>
#include <linux/malloc.h>
diff --git a/drivers/net/pcmcia/Config.in b/drivers/net/pcmcia/Config.in
index b6035305c..2052c6eaf 100644
--- a/drivers/net/pcmcia/Config.in
+++ b/drivers/net/pcmcia/Config.in
@@ -15,7 +15,7 @@ if [ "$CONFIG_NET_PCMCIA" = "y" ]; then
dep_tristate ' SMC 91Cxx PCMCIA support' CONFIG_PCMCIA_SMC91C92 $CONFIG_PCMCIA
dep_tristate ' Xircom 16-bit PCMCIA support' CONFIG_PCMCIA_XIRC2PS $CONFIG_PCMCIA
dep_tristate ' COM20020 ARCnet PCMCIA support' CONFIG_ARCNET_COM20020_CS $CONFIG_ARCNET_COM20020 $CONFIG_ARCNET $CONFIG_PCMCIA
- dep_tristate ' IBM PCMCIA tokenring adapter support' CONFIG_PCMCIA_IBMTR $CONFIG_PCMCIA_IBMTR $CONFIG_TR $CONFIG_PCMCIA
+ dep_tristate ' IBM PCMCIA tokenring adapter support' CONFIG_PCMCIA_IBMTR $CONFIG_TR $CONFIG_PCMCIA
if [ "$CONFIG_CARDBUS" = "y" ]; then
tristate ' Xircom Tulip-like CardBus support' CONFIG_PCMCIA_XIRTULIP
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 9db7132ec..9e772466c 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -39,7 +39,6 @@
#include <linux/ppp_defs.h>
#include <linux/if_ppp.h>
#include <linux/if_pppvar.h>
-#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/file.h>
#include <linux/proc_fs.h>
diff --git a/drivers/net/pppox.c b/drivers/net/pppox.c
index 6bef505b4..941bf369e 100644
--- a/drivers/net/pppox.c
+++ b/drivers/net/pppox.c
@@ -17,6 +17,7 @@
*
*/
+#include <linux/config.h>
#include <linux/string.h>
#include <linux/module.h>
diff --git a/drivers/net/skfp/fplustm.c b/drivers/net/skfp/fplustm.c
index 83a935791..f5bda2464 100644
--- a/drivers/net/skfp/fplustm.c
+++ b/drivers/net/skfp/fplustm.c
@@ -390,9 +390,9 @@ struct s_smc *smc ;
outpw(FM_A(FM_TREQ0),(unsigned)t_requ) ;
}
-void set_long(p,l)
+void set_int(p,l)
char *p;
-long l;
+int l;
{
p[0] = (char)(l >> 24) ;
p[1] = (char)(l >> 16) ;
@@ -416,12 +416,12 @@ unsigned off; /* start address within buffer memory */
int len ; /* lenght of the frame including the FC */
{
int i ;
- u_long *p ;
+ u_int *p ;
CHECK_NPP() ;
MARW(off) ; /* set memory address reg for writes */
- p = (u_long *) mac ;
+ p = (u_int *) mac ;
for (i = (len + 3)/4 ; i ; i--) {
if (i == 1) {
/* last word, set the tag bit */
@@ -460,7 +460,7 @@ int len ; /* lenght of the frame including the FC */
static void directed_beacon(smc)
struct s_smc *smc ;
{
- SK_LOC_DECL(u_long,a[2]) ;
+ SK_LOC_DECL(u_int,a[2]) ;
/*
* set UNA in frame
@@ -491,7 +491,7 @@ static void build_claim_beacon(smc,t_request)
struct s_smc *smc ;
u_long t_request;
{
- u_long td ;
+ u_int td ;
int len ;
struct fddi_mac_sf *mac ;
@@ -499,13 +499,13 @@ u_long t_request;
* build claim packet
*/
len = 17 ;
- td = TX_DESCRIPTOR | ((((u_long)len-1)&3)<<27) ;
+ td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
mac = &smc->hw.fp.mac_sfb ;
mac->mac_fc = FC_CLAIM ;
/* DA == SA in claim frame */
mac->mac_source = mac->mac_dest = MA ;
/* 2's complement */
- set_long((char *)mac->mac_info,(long)t_request) ;
+ set_int((char *)mac->mac_info,(int)t_request) ;
copy_tx_mac(smc,td,(struct fddi_mac *)mac,
smc->hw.fp.fifo.rbc_ram_start + CLAIM_FRAME_OFF,len) ;
@@ -516,11 +516,11 @@ u_long t_request;
* build beacon packet
*/
len = 17 ;
- td = TX_DESCRIPTOR | ((((u_long)len-1)&3)<<27) ;
+ td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
mac->mac_fc = FC_BEACON ;
mac->mac_source = MA ;
mac->mac_dest = null_addr ; /* DA == 0 in beacon frame */
- set_long((char *) mac->mac_info,((long)BEACON_INFO<<24L) + 0 ) ;
+ set_int((char *) mac->mac_info,((int)BEACON_INFO<<24) + 0 ) ;
copy_tx_mac(smc,td,(struct fddi_mac *)mac,
smc->hw.fp.fifo.rbc_ram_start + BEACON_FRAME_OFF,len) ;
@@ -532,13 +532,13 @@ u_long t_request;
* contains optional UNA
*/
len = 23 ;
- td = TX_DESCRIPTOR | ((((u_long)len-1)&3)<<27) ;
+ td = TX_DESCRIPTOR | ((((u_int)len-1)&3)<<27) ;
mac->mac_fc = FC_BEACON ;
mac->mac_source = MA ;
mac->mac_dest = dbeacon_multi ; /* multicast */
- set_long((char *) mac->mac_info,((long)DBEACON_INFO<<24L) + 0 ) ;
- set_long((char *) mac->mac_info+4,0L) ;
- set_long((char *) mac->mac_info+8,0L) ;
+ set_int((char *) mac->mac_info,((int)DBEACON_INFO<<24) + 0 ) ;
+ set_int((char *) mac->mac_info+4,0) ;
+ set_int((char *) mac->mac_info+8,0) ;
copy_tx_mac(smc,td,(struct fddi_mac *)mac,
smc->hw.fp.fifo.rbc_ram_start + DBEACON_FRAME_OFF,len) ;
diff --git a/drivers/net/skfp/h/fplustm.h b/drivers/net/skfp/h/fplustm.h
index 9e1ce036e..bb9f3b2ac 100644
--- a/drivers/net/skfp/h/fplustm.h
+++ b/drivers/net/skfp/h/fplustm.h
@@ -54,12 +54,12 @@ struct err_st {
* Transmit Descriptor struct
*/
struct s_smt_fp_txd {
- u_long txd_tbctrl ; /* transmit buffer control */
- u_long txd_txdscr ; /* transmit frame status word */
- u_long txd_tbadr ; /* physical tx buffer address */
- u_long txd_ntdadr ; /* physical pointer to the next TxD */
+ u_int txd_tbctrl ; /* transmit buffer control */
+ u_int txd_txdscr ; /* transmit frame status word */
+ u_int txd_tbadr ; /* physical tx buffer address */
+ u_int txd_ntdadr ; /* physical pointer to the next TxD */
#ifdef ENA_64BIT_SUP
- u_long txd_tbadr_hi ; /* physical tx buffer addr (high dword)*/
+ u_int txd_tbadr_hi ; /* physical tx buffer addr (high dword)*/
#endif
char far *txd_virt ; /* virtual pointer to the data frag */
/* virt pointer to the next TxD */
@@ -71,12 +71,12 @@ struct s_smt_fp_txd {
* Receive Descriptor struct
*/
struct s_smt_fp_rxd {
- u_long rxd_rbctrl ; /* receive buffer control */
- u_long rxd_rfsw ; /* receive frame status word */
- u_long rxd_rbadr ; /* physical rx buffer address */
- u_long rxd_nrdadr ; /* physical pointer to the next RxD */
+ u_int rxd_rbctrl ; /* receive buffer control */
+ u_int rxd_rfsw ; /* receive frame status word */
+ u_int rxd_rbadr ; /* physical rx buffer address */
+ u_int rxd_nrdadr ; /* physical pointer to the next RxD */
#ifdef ENA_64BIT_SUP
- u_long rxd_rbadr_hi ; /* physical tx buffer addr (high dword)*/
+ u_int rxd_rbadr_hi ; /* physical tx buffer addr (high dword)*/
#endif
char far *rxd_virt ; /* virtual pointer to the data frag */
/* virt pointer to the next RxD */
@@ -259,8 +259,10 @@ struct s_smt_fp {
(((x)>> 8L)&0x0000ff00L) + \
(((x)>>24L)&0x000000ffL))
#else
+#ifndef AIX_REVERSE
#define AIX_REVERSE(x) (x)
#endif
+#endif
#ifdef MDR_REV
#define MDR_REVERSE(x) ((((x)<<24L)&0xff000000L) + \
@@ -268,7 +270,9 @@ struct s_smt_fp {
(((x)>> 8L)&0x0000ff00L) + \
(((x)>>24L)&0x000000ffL))
#else
+#ifndef MDR_REVERSE
#define MDR_REVERSE(x) (x)
#endif
+#endif
#endif
diff --git a/drivers/net/skfp/h/osdef1st.h b/drivers/net/skfp/h/osdef1st.h
index 69f27707d..a6866248a 100644
--- a/drivers/net/skfp/h/osdef1st.h
+++ b/drivers/net/skfp/h/osdef1st.h
@@ -97,22 +97,27 @@
*
* Note: The size of these structures must follow this rule:
*
- * size = 8 + n * 16, n >= 0
+ * sizeof(struct) + 2*sizeof(void*) == n * 16, n >= 1
*
- * NOTE: The size of this structures may not be changed, because
- * libskfddi.a depends on it. But the dummy fields can be
- * used freely.
+ * We use the dma_addr fields under Linux to keep track of the
+ * DMA address of the packet data, for later pci_unmap_single. -DaveM
*/
struct s_txd_os { // os-specific part of transmit descriptor
struct sk_buff *skb;
- long dummy;
+ dma_addr_t dma_addr;
} ;
struct s_rxd_os { // os-specific part of receive descriptor
struct sk_buff *skb;
- long dummy;
+ dma_addr_t dma_addr;
} ;
+/*
+ * So we do not need to make too many modifications to the generic driver
+ * parts, we take advantage of the AIX byte swapping macro interface.
+ */
+#define AIX_REVERSE(x) ((u32)le32_to_cpu((u32)(x)))
+#define MDR_REVERSE(x) ((u32)le32_to_cpu((u32)(x)))
diff --git a/drivers/net/skfp/h/smt.h b/drivers/net/skfp/h/smt.h
index 08eb1ccbf..5a2606d16 100644
--- a/drivers/net/skfp/h/smt.h
+++ b/drivers/net/skfp/h/smt.h
@@ -53,7 +53,7 @@ _packed struct smt_header {
u_char smt_class ; /* NIF, SIF ... */
u_char smt_type ; /* req., response .. */
u_short smt_version ; /* version id */
- u_long smt_tid ; /* transaction ID */
+ u_int smt_tid ; /* transaction ID */
struct smt_sid smt_sid ; /* station ID */
u_short smt_pad ; /* pad with 0 */
u_short smt_len ; /* length of info field */
@@ -278,15 +278,15 @@ struct smt_p_mac_status {
struct smt_para para ; /* generic parameter header */
u_short st_mib_index ; /* MIB index */
u_short st_mac_index ; /* n+1 .. n+m */
- u_long st_t_req ; /* T_Req */
- u_long st_t_neg ; /* T_Neg */
- u_long st_t_max ; /* T_Max */
- u_long st_tvx_value ; /* TVX_Value */
- u_long st_t_min ; /* T_Min */
- u_long st_sba ; /* synchr. bandwidth alloc */
- u_long st_frame_ct ; /* frame counter */
- u_long st_error_ct ; /* error counter */
- u_long st_lost_ct ; /* lost frames counter */
+ u_int st_t_req ; /* T_Req */
+ u_int st_t_neg ; /* T_Neg */
+ u_int st_t_max ; /* T_Max */
+ u_int st_tvx_value ; /* TVX_Value */
+ u_int st_t_min ; /* T_Min */
+ u_int st_sba ; /* synchr. bandwidth alloc */
+ u_int st_frame_ct ; /* frame counter */
+ u_int st_error_ct ; /* error counter */
+ u_int st_lost_ct ; /* lost frames counter */
} ;
/*
@@ -305,8 +305,8 @@ struct smt_p_lem {
u_char lem_cutoff ; /* 0x4 .. 0xf, default 0x7 */
u_char lem_alarm ; /* 0x4 .. 0xf, default 0x8 */
u_char lem_estimate ; /* 0x0 .. 0xff */
- u_long lem_reject_ct ; /* 0x00000000 .. 0xffffffff */
- u_long lem_ct ; /* 0x00000000 .. 0xffffffff */
+ u_int lem_reject_ct ; /* 0x00000000 .. 0xffffffff */
+ u_int lem_ct ; /* 0x00000000 .. 0xffffffff */
} ;
/*
@@ -319,8 +319,8 @@ struct smt_p_mac_counter {
struct smt_para para ; /* generic parameter header */
u_short mc_mib_index ; /* MIB index */
u_short mc_index ; /* mac index */
- u_long mc_receive_ct ; /* receive counter */
- u_long mc_transmit_ct ; /* transmit counter */
+ u_int mc_receive_ct ; /* receive counter */
+ u_int mc_transmit_ct ; /* transmit counter */
} ;
/*
@@ -333,7 +333,7 @@ struct smt_p_mac_fnc {
struct smt_para para ; /* generic parameter header */
u_short nc_mib_index ; /* MIB index */
u_short nc_index ; /* mac index */
- u_long nc_counter ; /* not copied counter */
+ u_int nc_counter ; /* not copied counter */
} ;
@@ -347,7 +347,7 @@ struct smt_p_priority {
struct smt_para para ; /* generic parameter header */
u_short pr_mib_index ; /* MIB index */
u_short pr_index ; /* mac index */
- u_long pr_priority[7] ; /* priority values */
+ u_int pr_priority[7] ; /* priority values */
} ;
/*
@@ -360,7 +360,7 @@ struct smt_p_eb {
struct smt_para para ; /* generic parameter header */
u_short eb_mib_index ; /* MIB index */
u_short eb_index ; /* phy index */
- u_long eb_error_ct ; /* # of eb overflows */
+ u_int eb_error_ct ; /* # of eb overflows */
} ;
/*
@@ -406,7 +406,7 @@ struct smt_p_echo {
struct smt_p_reason {
struct smt_para para ; /* generic parameter header */
- u_long rdf_reason ; /* CLASS/VERSION */
+ u_int rdf_reason ; /* CLASS/VERSION */
} ;
#define SMT_RDF_CLASS 0x00000001 /* class not supported */
#define SMT_RDF_VERSION 0x00000002 /* version not supported */
@@ -428,7 +428,7 @@ struct smt_p_reason {
struct smt_p_refused {
struct smt_para para ; /* generic parameter header */
- u_long ref_fc ; /* 3 bytes 0 + FC */
+ u_int ref_fc ; /* 3 bytes 0 + FC */
struct smt_header ref_header ; /* refused header */
} ;
@@ -454,7 +454,7 @@ struct smt_p_version {
struct smt_p_0015 {
struct smt_para para ; /* generic parameter header */
- u_long res_type ; /* recsource type */
+ u_int res_type ; /* recsource type */
} ;
#define SYNC_BW 0x00000001L /* Synchronous Bandwidth */
@@ -466,7 +466,7 @@ struct smt_p_0015 {
struct smt_p_0016 {
struct smt_para para ; /* generic parameter header */
- u_long sba_cmd ; /* command for the SBA */
+ u_int sba_cmd ; /* command for the SBA */
} ;
#define REQUEST_ALLOCATION 0x1 /* req allocation of sync bandwidth */
@@ -482,7 +482,7 @@ struct smt_p_0016 {
struct smt_p_0017 {
struct smt_para para ; /* generic parameter header */
- long sba_pl_req ; /* total sync bandwidth measured in */
+ int sba_pl_req ; /* total sync bandwidth measured in */
} ; /* bytes per 125 us */
/*
@@ -492,7 +492,7 @@ struct smt_p_0017 {
struct smt_p_0018 {
struct smt_para para ; /* generic parameter header */
- long sba_ov_req ; /* total sync bandwidth req for overhead*/
+ int sba_ov_req ; /* total sync bandwidth req for overhead*/
} ; /* measuered in bytes per T_Neg */
/*
@@ -513,7 +513,7 @@ struct smt_p_0019 {
struct smt_p_001a {
struct smt_para para ; /* generic parameter header */
- u_long category ; /* Allocator defined classification */
+ u_int category ; /* Allocator defined classification */
} ;
/*
@@ -523,7 +523,7 @@ struct smt_p_001a {
struct smt_p_001b {
struct smt_para para ; /* generic parameter header */
- u_long max_t_neg ; /* longest T_NEG for the sync service*/
+ u_int max_t_neg ; /* longest T_NEG for the sync service*/
} ;
/*
@@ -533,7 +533,7 @@ struct smt_p_001b {
struct smt_p_001c {
struct smt_para para ; /* generic parameter header */
- u_long min_seg_siz ; /* smallest number of bytes per frame*/
+ u_int min_seg_siz ; /* smallest number of bytes per frame*/
} ;
/*
@@ -543,7 +543,7 @@ struct smt_p_001c {
struct smt_p_001d {
struct smt_para para ; /* generic parameter header */
- u_long allocatable ; /* total sync bw availabel for alloc */
+ u_int allocatable ; /* total sync bw availabel for alloc */
} ;
/*
@@ -575,8 +575,8 @@ struct smt_p_fsc {
*/
#define SWAP_SMT_P1048 "ll"
struct smt_p_1048 {
- u_long p1048_flag ;
- u_long p1048_cf_state ;
+ u_int p1048_flag ;
+ u_int p1048_cf_state ;
} ;
/*
@@ -586,7 +586,7 @@ struct smt_p_1048 {
*/
#define SWAP_SMT_P208C "4lss66"
struct smt_p_208c {
- u_long p208c_flag ;
+ u_int p208c_flag ;
u_short p208c_pad ;
u_short p208c_dupcondition ;
struct fddi_addr p208c_fddilong ;
@@ -595,26 +595,26 @@ struct smt_p_208c {
#define SWAP_SMT_P208D "4lllll"
struct smt_p_208d {
- u_long p208d_flag ;
- u_long p208d_frame_ct ;
- u_long p208d_error_ct ;
- u_long p208d_lost_ct ;
- u_long p208d_ratio ;
+ u_int p208d_flag ;
+ u_int p208d_frame_ct ;
+ u_int p208d_error_ct ;
+ u_int p208d_lost_ct ;
+ u_int p208d_ratio ;
} ;
#define SWAP_SMT_P208E "4llll"
struct smt_p_208e {
- u_long p208e_flag ;
- u_long p208e_not_copied ;
- u_long p208e_copied ;
- u_long p208e_not_copied_ratio ;
+ u_int p208e_flag ;
+ u_int p208e_not_copied ;
+ u_int p208e_copied ;
+ u_int p208e_not_copied_ratio ;
} ;
#define SWAP_SMT_P208F "4ll6666s6"
struct smt_p_208f {
- u_long p208f_multiple ;
- u_long p208f_nacondition ;
+ u_int p208f_multiple ;
+ u_int p208f_nacondition ;
struct fddi_addr p208f_old_una ;
struct fddi_addr p208f_new_una ;
struct fddi_addr p208f_old_dna ;
@@ -626,10 +626,10 @@ struct smt_p_208f {
#define SWAP_SMT_P2090 "4lssl"
struct smt_p_2090 {
- u_long p2090_multiple ;
+ u_int p2090_multiple ;
u_short p2090_availablepaths ;
u_short p2090_currentpath ;
- u_long p2090_requestedpaths ;
+ u_int p2090_requestedpaths ;
} ;
/*
@@ -649,7 +649,7 @@ struct smt_p_2090 {
struct smt_p_320b {
struct smt_para para ; /* generic parameter header */
- u_long mib_index ;
+ u_int mib_index ;
u_short path_pad ;
u_short path_index ;
} ;
@@ -658,33 +658,33 @@ struct smt_p_320b {
struct smt_p_320f {
struct smt_para para ; /* generic parameter header */
- u_long mib_index ;
- u_long mib_payload ;
+ u_int mib_index ;
+ u_int mib_payload ;
} ;
#define SWAP_SMT_P3210 "4l"
struct smt_p_3210 {
struct smt_para para ; /* generic parameter header */
- u_long mib_index ;
- u_long mib_overhead ;
+ u_int mib_index ;
+ u_int mib_overhead ;
} ;
#define SWAP_SMT_P4050 "4l1111ll"
struct smt_p_4050 {
- u_long p4050_flag ;
+ u_int p4050_flag ;
u_char p4050_pad ;
u_char p4050_cutoff ;
u_char p4050_alarm ;
u_char p4050_estimate ;
- u_long p4050_reject_ct ;
- u_long p4050_ct ;
+ u_int p4050_reject_ct ;
+ u_int p4050_ct ;
} ;
#define SWAP_SMT_P4051 "4lssss"
struct smt_p_4051 {
- u_long p4051_multiple ;
+ u_int p4051_multiple ;
u_short p4051_porttype ;
u_short p4051_connectstate ;
u_short p4051_pc_neighbor ;
@@ -693,17 +693,17 @@ struct smt_p_4051 {
#define SWAP_SMT_P4052 "4ll"
struct smt_p_4052 {
- u_long p4052_flag ;
- u_long p4052_eberrorcount ;
+ u_int p4052_flag ;
+ u_int p4052_eberrorcount ;
} ;
#define SWAP_SMT_P4053 "4lsslss"
struct smt_p_4053 {
- u_long p4053_multiple ;
+ u_int p4053_multiple ;
u_short p4053_availablepaths ;
u_short p4053_currentpath ;
- u_long p4053_requestedpaths ;
+ u_int p4053_requestedpaths ;
u_short p4053_mytype ;
u_short p4053_neighbortype ;
} ;
@@ -714,7 +714,7 @@ struct smt_p_4053 {
struct smt_p_setcount {
struct smt_para para ; /* generic parameter header */
- u_long count ;
+ u_int count ;
u_char timestamp[8] ;
} ;
diff --git a/drivers/net/skfp/h/targetos.h b/drivers/net/skfp/h/targetos.h
index dd88fb35e..7c6c1bd85 100644
--- a/drivers/net/skfp/h/targetos.h
+++ b/drivers/net/skfp/h/targetos.h
@@ -93,7 +93,7 @@
#define u8 unsigned char
#define u16 unsigned short
-#define u32 unsigned long
+#define u32 unsigned int
#define MAX_TX_QUEUE_LEN 20 // number of packets queued by driver
#define MAX_FRAME_SIZE 4550
@@ -127,11 +127,12 @@ struct s_smt_os {
u32 bus_type; /* bus type (0 == PCI, 1 == EISA) */
struct pci_dev pdev; /* PCI device structure */
- u32 base_addr;
+ unsigned long base_addr;
unsigned char factory_mac_addr[8];
ulong SharedMemSize;
ulong SharedMemHeap;
void* SharedMemAddr;
+ dma_addr_t SharedMemDMA;
ulong QueueSkb;
struct sk_buff_head SendSkbQueue;
@@ -144,8 +145,10 @@ struct s_smt_os {
// receive into this local buffer if no skb available
// data will be not valid, because multiple RxDs can
- // point here at the same time
- unsigned char LocalRxBuffer[MAX_FRAME_SIZE];
+ // point here at the same time, it must be at least
+ // MAX_FRAME_SIZE bytes in size
+ unsigned char *LocalRxBuffer;
+ dma_addr_t LocalRxBufferDMA;
// Version (required by SMT module).
u_long smc_version ;
diff --git a/drivers/net/skfp/hwmtm.c b/drivers/net/skfp/hwmtm.c
index 366b3b890..ece539646 100644
--- a/drivers/net/skfp/hwmtm.c
+++ b/drivers/net/skfp/hwmtm.c
@@ -456,7 +456,7 @@ u_char *mac_addr ; /* canonical address */
/*
* make sure that the start pointer is 16 byte aligned
*/
- i = 16 - ((int)smc->os.hwm.descr_p & 0xf) ;
+ i = 16 - ((long)smc->os.hwm.descr_p & 0xf) ;
if (i != 16) {
DB_GEN("i = %d",i,0,3) ;
smc->os.hwm.descr_p = (union s_fp_descr volatile *)
@@ -1087,9 +1087,8 @@ struct s_smc *smc ;
DB_RX("Check RxD %x for OWN and EOF",(void *)r,0,5) ;
DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORCPU) ;
rbctrl = CR_READ(r->rxd_rbctrl) ;
-#ifdef AIX
rbctrl = AIX_REVERSE(rbctrl) ;
-#endif
+
if (rbctrl & BMU_OWN) {
NDD_TRACE("RHxE",r,rfsw,rbctrl) ;
DB_RX("End of RxDs",0,0,4) ;
@@ -1425,26 +1424,19 @@ int len ;
int frame_status ;
{
struct s_smt_fp_rxd volatile *r ;
-#ifdef AIX
- u_long rbctrl ;
-#endif
+ u_int rbctrl ;
NDD_TRACE("RHfB",virt,len,frame_status) ;
DB_RX("hwm_rx_frag: len = %d, frame_status = %x\n",len,frame_status,2) ;
r = smc->hw.fp.rx_q[QUEUE_R1].rx_curr_put ;
r->rxd_virt = virt ;
r->rxd_rbadr = AIX_REVERSE(phys) ;
-#ifndef AIX
- r->rxd_rbctrl = (((u_long)frame_status & (FIRST_FRAG|LAST_FRAG))<<26) |
- (((u_long) frame_status & FIRST_FRAG) << 21) |
- BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len ;
-#else
rbctrl = AIX_REVERSE( (((u_long)frame_status &
(FIRST_FRAG|LAST_FRAG))<<26) |
(((u_long) frame_status & FIRST_FRAG) << 21) |
BMU_OWN | BMU_CHECK | BMU_EN_IRQ_EOF | len) ;
r->rxd_rbctrl = rbctrl ;
-#endif
+
DRV_BUF_FLUSH(r,DDI_DMA_SYNC_FORDEV) ;
outpd(ADDR(B0_R1_CSR),CSR_START) ;
smc->hw.fp.rx_q[QUEUE_R1].rx_free-- ;
@@ -1687,9 +1679,7 @@ int frame_status ;
{
struct s_smt_fp_txd volatile *t ;
struct s_smt_tx_queue *queue ;
-#ifdef AIX
- u_long tbctrl ;
-#endif
+ u_int tbctrl ;
queue = smc->os.hwm.tx_p ;
@@ -1708,19 +1698,15 @@ int frame_status ;
t->txd_virt = virt ;
t->txd_txdscr = AIX_REVERSE(smc->os.hwm.tx_descr) ;
t->txd_tbadr = AIX_REVERSE(phys) ;
-#ifndef AIX
- t->txd_tbctrl = (((u_long)frame_status &
- (FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) |
- BMU_OWN|BMU_CHECK |len ;
- DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
- outpd(queue->tx_bmu_ctl,CSR_START) ;
-
-#else /* ifndef AIX */
tbctrl = AIX_REVERSE((((u_long)frame_status &
(FIRST_FRAG|LAST_FRAG|EN_IRQ_EOF))<< 26) |
BMU_OWN|BMU_CHECK |len) ;
t->txd_tbctrl = tbctrl ;
+#ifndef AIX
+ DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
+ outpd(queue->tx_bmu_ctl,CSR_START) ;
+#else /* ifndef AIX */
DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
if (frame_status & QUEUE_A0) {
outpd(ADDR(B0_XA_CSR),CSR_START) ;
@@ -1888,9 +1874,7 @@ int fc;
struct s_smt_tx_queue *queue ;
struct s_smt_fp_txd volatile *t ;
u_long phys ;
-#ifdef AIX
- u_long tbctrl ;
-#endif
+ u_int tbctrl ;
NDD_TRACE("THSB",mb,fc,0) ;
DB_TX("smt_send_mbuf: mb = 0x%x, fc = 0x%x",mb,fc,4) ;
@@ -1908,7 +1892,7 @@ int fc;
frag_count = 0 ;
len = mb->sm_len ;
while (len) {
- n = SMT_PAGESIZE - ((int)data & (SMT_PAGESIZE-1)) ;
+ n = SMT_PAGESIZE - ((long)data & (SMT_PAGESIZE-1)) ;
if (n >= len) {
n = len ;
}
@@ -1964,17 +1948,14 @@ int fc;
phys = dma_master(smc, (void far *)virt[i],
frag_len[i], DMA_RD|SMT_BUF) ;
t->txd_tbadr = AIX_REVERSE(phys) ;
-#ifndef AIX
- t->txd_tbctrl = (((u_long) frame_status &
- (FIRST_FRAG|LAST_FRAG)) << 26) |
- BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i] ;
- DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
- outpd(queue->tx_bmu_ctl,CSR_START) ;
-#else
tbctrl = AIX_REVERSE((((u_long) frame_status &
(FIRST_FRAG|LAST_FRAG)) << 26) |
BMU_OWN | BMU_CHECK | BMU_SMT_TX |frag_len[i]) ;
t->txd_tbctrl = tbctrl ;
+#ifndef AIX
+ DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
+ outpd(queue->tx_bmu_ctl,CSR_START) ;
+#else
DRV_BUF_FLUSH(t,DDI_DMA_SYNC_FORDEV) ;
outpd(ADDR(B0_XA_CSR),CSR_START) ;
#endif
@@ -2039,9 +2020,8 @@ struct s_smc *smc ;
DRV_BUF_FLUSH(t1,DDI_DMA_SYNC_FORCPU) ;
DB_TX("check OWN/EOF bit of TxD 0x%x",t1,0,5) ;
tbctrl = CR_READ(t1->txd_tbctrl) ;
-#ifdef AIX
tbctrl = AIX_REVERSE(tbctrl) ;
-#endif
+
if (tbctrl & BMU_OWN || !queue->tx_used){
DB_TX("End of TxDs queue %d",i,0,4) ;
goto free_next_queue ; /* next queue */
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c
index 1bbd5f068..5b5ffc9f9 100644
--- a/drivers/net/skfp/skfddi.c
+++ b/drivers/net/skfp/skfddi.c
@@ -19,6 +19,9 @@
* Maintainers:
* CG Christoph Goos (cgoos@syskonnect.de)
*
+ * Contributors:
+ * DM David S. Miller
+ *
* Address all question to:
* linux@syskonnect.de
*
@@ -52,20 +55,20 @@
* 26-Oct-99 CG Fixed compilation error on 2.2.13
* 12-Nov-99 CG Source code release
* 22-Nov-99 CG Included in kernel source.
+ * 07-May-00 DM 64 bit fixes, new dma interface
*
* Compilation options (-Dxxx):
* DRIVERDEBUG print lots of messages to log file
* DUMPPACKETS print received/transmitted packets to logfile
*
- * Limitations:
- * I changed the driver to support memory mapped I/O, so it
- * might run on non-x86 architectures (not tested).
- * But the hardware module does not yet support 64 bit OS'es.
+ * Tested cpu architectures:
+ * - i386
+ * - sparc64
*/
/* Version information string - should be updated prior to */
/* each new release!!! */
-#define VERSION "2.05"
+#define VERSION "2.06"
static const char *boot_msg =
"SysKonnect FDDI PCI Adapter driver v" VERSION " for\n"
@@ -666,18 +669,28 @@ static int skfp_driver_init(struct net_device *dev)
spin_lock_init(&bp->DriverLock);
+ // Allocate invalid frame
+ bp->LocalRxBuffer = pci_alloc_consistent(&bp->pdev, MAX_FRAME_SIZE, &bp->LocalRxBufferDMA);
+ if (!bp->LocalRxBuffer) {
+ printk("could not allocate mem for ");
+ printk("LocalRxBuffer: %d byte\n", MAX_FRAME_SIZE);
+ goto fail;
+ }
+
// Determine the required size of the 'shared' memory area.
bp->SharedMemSize = mac_drv_check_space();
PRINTK(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
if (bp->SharedMemSize > 0) {
bp->SharedMemSize += 16; // for descriptor alignment
- bp->SharedMemAddr = kmalloc(bp->SharedMemSize, GFP_KERNEL);
+ bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev,
+ bp->SharedMemSize,
+ &bp->SharedMemDMA);
if (!bp->SharedMemSize) {
printk("could not allocate mem for ");
printk("hardware module: %ld byte\n",
bp->SharedMemSize);
- return (-1);
+ goto fail;
}
bp->SharedMemHeap = 0; // Nothing used yet.
@@ -693,7 +706,7 @@ static int skfp_driver_init(struct net_device *dev)
PRINTK(KERN_INFO "mac_drv_init()..\n");
if (mac_drv_init(smc) != 0) {
PRINTK(KERN_INFO "mac_drv_init() failed.\n");
- return (-1);
+ goto fail;
}
read_address(smc, NULL);
PRINTK(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
@@ -708,6 +721,21 @@ static int skfp_driver_init(struct net_device *dev)
smt_reset_defaults(smc, 0);
return (0);
+
+fail:
+ if (bp->SharedMemAddr) {
+ pci_free_consistent(&bp->pdev,
+ bp->SharedMemSize,
+ bp->SharedMemAddr,
+ bp->SharedMemDMA);
+ bp->SharedMemAddr = NULL;
+ }
+ if (bp->LocalRxBuffer) {
+ pci_free_consistent(&bp->pdev, MAX_FRAME_SIZE,
+ bp->LocalRxBuffer, bp->LocalRxBufferDMA);
+ bp->LocalRxBuffer = NULL;
+ }
+ return (-1);
} // skfp_driver_init
@@ -1282,7 +1310,7 @@ static int skfp_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
* is contained in a single physically contiguous buffer
* in which the virtual address of the start of packet
* (skb->data) can be converted to a physical address
- * by using virt_to_bus().
+ * by using pci_map_single().
*
* We have an internal queue for packets we can not send
* immediately. Packets in this queue can be given to the
@@ -1378,6 +1406,7 @@ static void send_queued_packets(struct s_smc *smc)
unsigned char fc;
int queue;
struct s_smt_fp_txd *txd; // Current TxD.
+ dma_addr_t dma_address;
unsigned long Flags;
int frame_status; // HWM tx frame status.
@@ -1442,13 +1471,18 @@ static void send_queued_packets(struct s_smc *smc)
txd = (struct s_smt_fp_txd *) HWM_GET_CURR_TXD(smc, queue);
+ dma_address = pci_map_single(&bp->pdev, skb->data,
+ skb->len, PCI_DMA_TODEVICE);
if (frame_status & LAN_TX) {
- txd->txd_os.skb = skb; // save skb
+ txd->txd_os.skb = skb; // save skb
+ txd->txd_os.dma_addr = dma_address; // save dma mapping
}
- hwm_tx_frag(smc, skb->data, virt_to_bus(skb->data), skb->len,
+ hwm_tx_frag(smc, skb->data, dma_address, skb->len,
frame_status | FIRST_FRAG | LAST_FRAG | EN_IRQ_EOF);
if (!(frame_status & LAN_TX)) { // local only frame
+ pci_unmap_single(&bp->pdev, dma_address,
+ skb->len, PCI_DMA_TODEVICE);
dev_kfree_skb_irq(skb);
}
spin_unlock_irqrestore(&bp->DriverLock, Flags);
@@ -1571,7 +1605,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
{
void *virt;
- PRINTK(KERN_INFO "mac_drv_get_space\n");
+ PRINTK(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap);
if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) {
@@ -1581,8 +1615,10 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
smc->os.SharedMemHeap += size; // Move heap pointer.
PRINTK(KERN_INFO "mac_drv_get_space end\n");
- PRINTK(KERN_INFO "virt addr: %08lx\n", (ulong) virt);
- PRINTK(KERN_INFO "bus addr: %08lx\n", (ulong) virt_to_bus(virt));
+ PRINTK(KERN_INFO "virt addr: %lx\n", (ulong) virt);
+ PRINTK(KERN_INFO "bus addr: %lx\n", (ulong)
+ (smc->os.SharedMemDMA +
+ ((char *) virt - (char *)smc->os.SharedMemAddr)));
return (virt);
} // mac_drv_get_space
@@ -1616,7 +1652,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
virt = mac_drv_get_space(smc, size);
- size = (u_int) ((0 - (unsigned int) virt) & 15);
+ size = (u_int) ((0 - (unsigned long) virt) & 15UL);
PRINTK("Allocate %u bytes alignment gap ", size);
PRINTK("for descriptor memory.\n");
@@ -1644,7 +1680,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
************************/
unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt)
{
- return virt_to_bus(virt);
+ return (smc->os.SharedMemDMA +
+ ((char *) virt - (char *)smc->os.SharedMemAddr));
} // mac_drv_virt2phys
@@ -1657,7 +1694,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt)
* for the DMA transfer, it should do it in this function.
*
* The hardware module calls this dma_master if it wants to send an SMT
- * frame.
+ * frame. This means that the virt address passed in here is part of
+ * the 'shared' memory area.
* Args
* smc - A pointer to the SMT context struct.
*
@@ -1677,7 +1715,8 @@ unsigned long mac_drv_virt2phys(struct s_smc *smc, void *virt)
************************/
u_long dma_master(struct s_smc * smc, void *virt, int len, int flag)
{
- return (virt_to_bus(virt));
+ return (smc->os.SharedMemDMA +
+ ((char *) virt - (char *)smc->os.SharedMemAddr));
} // dma_master
@@ -1704,7 +1743,31 @@ u_long dma_master(struct s_smc * smc, void *virt, int len, int flag)
************************/
void dma_complete(struct s_smc *smc, volatile union s_fp_descr *descr, int flag)
{
- return;
+ /* For TX buffers, there are two cases. If it is an SMT transmit
+ * buffer, there is nothing to do since we use consistent memory
+ * for the 'shared' memory area. The other case is for normal
+ * transmit packets given to us by the networking stack, and in
+ * that case we cleanup the PCI DMA mapping in mac_drv_tx_complete
+ * below.
+ *
+ * For RX buffers, we have to unmap dynamic PCI DMA mappings here
+ * because the hardware module is about to potentially look at
+ * the contents of the buffer. If we did not call the PCI DMA
+ * unmap first, the hardware module could read inconsistent data.
+ */
+ if (flag & DMA_WR) {
+ skfddi_priv *bp = (skfddi_priv *) & smc->os;
+ volatile struct s_smt_fp_rxd *r = &descr->r;
+
+ /* If SKB is NULL, we used the local buffer. */
+ if (r->rxd_os.skb && r->rxd_os.dma_addr) {
+ int MaxFrameSize = bp->MaxFrameSize;
+
+ pci_unmap_single(&bp->pdev, r->rxd_os.dma_addr,
+ MaxFrameSize, PCI_DMA_FROMDEVICE);
+ r->rxd_os.dma_addr = 0;
+ }
+ }
} // dma_complete
@@ -1735,6 +1798,11 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
}
txd->txd_os.skb = NULL;
+ // release the DMA mapping
+ pci_unmap_single(&smc->os.pdev, txd->txd_os.dma_addr,
+ skb->len, PCI_DMA_TODEVICE);
+ txd->txd_os.dma_addr = 0;
+
smc->os.MacStat.tx_packets++; // Count transmitted packets.
smc->os.MacStat.tx_bytes+=skb->len; // Count bytes
@@ -1823,6 +1891,8 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
}
virt = skb->data;
+ // The DMA mapping was released in dma_complete above.
+
dump_data(skb->data, len);
/*
@@ -1923,7 +1993,7 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
struct sk_buff *skb;
int MaxFrameSize;
unsigned char *v_addr;
- unsigned long b_addr;
+ dma_addr_t b_addr;
if (frag_count != 1) // This is not allowed to happen.
@@ -1939,25 +2009,34 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
if (skb == NULL) { // this should not happen
PRINTK("Requeue with no skb in rxd!\n");
- skb = alloc_skb(MaxFrameSize, GFP_ATOMIC);
+ skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
if (skb) {
// we got a skb
rxd->rxd_os.skb = skb;
+ skb_reserve(skb, 3);
skb_put(skb, MaxFrameSize);
v_addr = skb->data;
- b_addr = virt_to_bus(v_addr);
+ b_addr = pci_map_single(&smc->os.pdev,
+ v_addr,
+ MaxFrameSize,
+ PCI_DMA_FROMDEVICE);
+ rxd->rxd_os.dma_addr = b_addr;
} else {
// no skb available, use local buffer
PRINTK("Queueing invalid buffer!\n");
rxd->rxd_os.skb = NULL;
v_addr = smc->os.LocalRxBuffer;
- b_addr = virt_to_bus(v_addr);
+ b_addr = smc->os.LocalRxBufferDMA;
}
} else {
// we use skb from old rxd
rxd->rxd_os.skb = skb;
v_addr = skb->data;
- b_addr = virt_to_bus(v_addr);
+ b_addr = pci_map_single(&smc->os.pdev,
+ v_addr,
+ MaxFrameSize,
+ PCI_DMA_FROMDEVICE);
+ rxd->rxd_os.dma_addr = b_addr;
}
hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
FIRST_FRAG | LAST_FRAG);
@@ -2002,12 +2081,17 @@ void mac_drv_fill_rxd(struct s_smc *smc)
PRINTK(KERN_INFO ".\n");
rxd = HWM_GET_CURR_RXD(smc);
- skb = alloc_skb(MaxFrameSize, GFP_ATOMIC);
+ skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
if (skb) {
// we got a skb
+ skb_reserve(skb, 3);
skb_put(skb, MaxFrameSize);
v_addr = skb->data;
- b_addr = virt_to_bus(v_addr);
+ b_addr = pci_map_single(&smc->os.pdev,
+ v_addr,
+ MaxFrameSize,
+ PCI_DMA_FROMDEVICE);
+ rxd->rxd_os.dma_addr = b_addr;
} else {
// no skb available, use local buffer
// System has run out of buffer memory, but we want to
@@ -2016,7 +2100,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
// so data in it must be considered invalid.
PRINTK("Queueing invalid buffer!\n");
v_addr = smc->os.LocalRxBuffer;
- b_addr = virt_to_bus(v_addr);
+ b_addr = smc->os.LocalRxBufferDMA;
}
rxd->rxd_os.skb = skb;
@@ -2060,6 +2144,12 @@ void mac_drv_clear_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
for (; frag_count > 0; frag_count--) {
skb = rxd->rxd_os.skb;
if (skb != NULL) {
+ skfddi_priv *bp = (skfddi_priv *) & smc->os;
+ int MaxFrameSize = bp->MaxFrameSize;
+
+ pci_unmap_single(&bp->pdev, rxd->rxd_os.dma_addr,
+ MaxFrameSize, PCI_DMA_FROMDEVICE);
+
dev_kfree_skb(skb);
rxd->rxd_os.skb = NULL;
}
@@ -2111,11 +2201,12 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
len, la_len, (unsigned long) look_ahead);
return (0);
}
- skb = alloc_skb(len, GFP_ATOMIC);
+ skb = alloc_skb(len + 3, GFP_ATOMIC);
if (!skb) {
PRINTK("fddi: Local SMT: skb memory exhausted.\n");
return (0);
}
+ skb_reserve(skb, 3);
skb_put(skb, len);
memcpy(skb->data, look_ahead, len);
@@ -2162,7 +2253,40 @@ void smt_timer_poll(struct s_smc *smc)
************************/
void ring_status_indication(struct s_smc *smc, u_long status)
{
- PRINTK("ring_status_indication(%08lXh)\n", (unsigned long) status);
+ PRINTK("ring_status_indication( ");
+ if (status & RS_RES15)
+ PRINTK("RS_RES15 ");
+ if (status & RS_HARDERROR)
+ PRINTK("RS_HARDERROR ");
+ if (status & RS_SOFTERROR)
+ PRINTK("RS_SOFTERROR ");
+ if (status & RS_BEACON)
+ PRINTK("RS_BEACON ");
+ if (status & RS_PATHTEST)
+ PRINTK("RS_PATHTEST ");
+ if (status & RS_SELFTEST)
+ PRINTK("RS_SELFTEST ");
+ if (status & RS_RES9)
+ PRINTK("RS_RES9 ");
+ if (status & RS_DISCONNECT)
+ PRINTK("RS_DISCONNECT ");
+ if (status & RS_RES7)
+ PRINTK("RS_RES7 ");
+ if (status & RS_DUPADDR)
+ PRINTK("RS_DUPADDR ");
+ if (status & RS_NORINGOP)
+ PRINTK("RS_NORINGOP ");
+ if (status & RS_VERSION)
+ PRINTK("RS_VERSION ");
+ if (status & RS_STUCKBYPASSS)
+ PRINTK("RS_STUCKBYPASSS ");
+ if (status & RS_EVENT)
+ PRINTK("RS_EVENT ");
+ if (status & RS_RINGOPCHANGE)
+ PRINTK("RS_RINGOPCHANGE ");
+ if (status & RS_RES0)
+ PRINTK("RS_RES0 ");
+ PRINTK("]\n");
} // ring_status_indication
@@ -2261,9 +2385,18 @@ void cfm_state_change(struct s_smc *smc, int c_state)
case SC7_WRAP_S:
s = "SC7_WRAP_S";
break;
- default:
- s = "unknown";
+ case SC9_C_WRAP_A:
+ s = "SC9_C_WRAP_A";
+ break;
+ case SC10_C_WRAP_B:
+ s = "SC10_C_WRAP_B";
+ break;
+ case SC11_C_WRAP_S:
+ s = "SC11_C_WRAP_S";
break;
+ default:
+ PRINTK(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
+ return;
}
PRINTK(KERN_INFO "cfm_state_change: %s\n", s);
#endif // DRIVERDEBUG
@@ -2478,7 +2611,18 @@ static struct net_device *unlink_modules(struct net_device *p)
next = lp->os.next_module;
if (lp->os.SharedMemAddr) {
- kfree(lp->os.SharedMemAddr);
+ pci_free_consistent(&lp->os.pdev,
+ lp->os.SharedMemSize,
+ lp->os.SharedMemAddr,
+ lp->os.SharedMemDMA);
+ lp->os.SharedMemAddr = NULL;
+ }
+ if (lp->os.LocalRxBuffer) {
+ pci_free_consistent(&lp->os.pdev,
+ MAX_FRAME_SIZE,
+ lp->os.LocalRxBuffer,
+ lp->os.LocalRxBufferDMA);
+ lp->os.LocalRxBuffer = NULL;
}
release_region(p->base_addr,
(lp->os.bus_type == SK_BUS_TYPE_PCI ? FP_IO_LEN : 0));
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index f206a44f9..58f71b963 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -1750,9 +1750,9 @@ static void tr_rx(struct net_device *dev)
/* Copy the payload... */
for (;;) {
if (IPv4_p)
- chksum = csum_partial_copy(bus_to_virt(rbufdata), data,
+ chksum = csum_partial_copy_generic(bus_to_virt(rbufdata), data,
length < rbuffer_len ? length : rbuffer_len,
- chksum);
+ chksum, NULL, NULL);
else
isa_memcpy_fromio(data, rbufdata, rbuffer_len);
rbuffer = ntohs(isa_readw(rbuffer));
diff --git a/drivers/s390/Config.in b/drivers/s390/Config.in
new file mode 100644
index 000000000..257c65d9a
--- /dev/null
+++ b/drivers/s390/Config.in
@@ -0,0 +1,70 @@
+mainmenu_option next_comment
+comment 'S/390 block device drivers'
+
+tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
+if [ "$CONFIG_NET" = "y" ]; then
+ tristate 'Network block device support' CONFIG_BLK_DEV_NBD
+fi
+bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
+if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
+ tristate ' Linear (append) mode' CONFIG_MD_LINEAR
+ tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED
+ tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+ tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
+fi
+if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
+ bool ' Boot support (linear, striped)' CONFIG_MD_BOOT
+fi
+tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
+if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
+ bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+fi
+
+bool 'Support for VM minidisk (VM only)' CONFIG_MDISK
+if [ "$CONFIG_MDISK" = "y" ]; then
+ bool ' Support for synchronous read-write' CONFIG_MDISK_SYNC
+fi
+
+tristate 'Support for DASD devices' CONFIG_DASD
+if [ "$CONFIG_DASD" != "n" ]; then
+ comment 'DASD disciplines'
+ bool ' Support for ECKD Disks' CONFIG_DASD_ECKD
+# bool ' Support for CKD Disks' CONFIG_DASD_CKD
+ bool ' Support for DIAG access to CMS reserved Disks' CONFIG_DASD_MDSK
+fi
+
+#menu_option next_comment
+#endmenu
+
+if [ "$CONFIG_NET" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'S/390 Network device support'
+ bool 'Channel Device Configuration (Temporary Option)' CONFIG_CHANDEV
+ bool 'Network device support' CONFIG_NETDEVICES
+ if [ "$CONFIG_NETDEVICES" = "y" ]; then
+ menu_option next_comment
+ comment 'S390 Network devices'
+ bool 'CTC device support' CONFIG_CTC
+ bool 'IUCV device support (VM only)' CONFIG_IUCV
+ tristate 'Dummy net driver support' CONFIG_DUMMY
+ bool 'Ethernet (10 or 100Mbit)' CONFIG_NET_ETHERNET
+ bool 'Token Ring driver support' CONFIG_TR
+ bool 'FDDI driver support' CONFIG_FDDI
+ fi
+ endmenu
+fi
+
+mainmenu_option next_comment
+comment 'S/390 Terminal and Console options'
+
+bool 'Support for 3215 line mode terminal' CONFIG_3215
+if [ "$CONFIG_3215" = "y" ]; then
+ bool 'Support for console on 3215 line mode terminal' CONFIG_3215_CONSOLE
+fi
+
+bool 'Support for HWC line mode terminal' CONFIG_HWC
+if [ "$CONFIG_HWC" = "y" ]; then
+ bool 'console on HWC line mode terminal' CONFIG_HWC_CONSOLE
+fi
+endmenu
+
diff --git a/drivers/s390/Makefile b/drivers/s390/Makefile
new file mode 100644
index 000000000..009916137
--- /dev/null
+++ b/drivers/s390/Makefile
@@ -0,0 +1,40 @@
+#
+# Makefile for the linux i386-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+all: io.o
+
+CFLAGS +=
+O_TARGET := io.o
+O_OBJS :=
+M_OBJS :=
+
+SUBDIRS := $(SUBDIRS) arch/s390/drivers/block arch/s390/drivers/char \
+ arch/s390/drivers/misc arch/s390/drivers/net
+MOD_SUB_DIRS += ./net
+
+O_OBJS := block/s390-block.o \
+ char/s390-char.o \
+ misc/s390-misc.o \
+ net/s390-net.o
+
+io.o: $(O_OBJS)
+
+block/s390-block.o: dummy
+ $(MAKE) -C block
+
+char/s390-char.o: dummy
+ $(MAKE) -C char
+
+misc/s390-misc.o: dummy
+ $(MAKE) -C misc
+
+net/s390-net.o: dummy
+ $(MAKE) -C net
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile
new file mode 100644
index 000000000..16a56acb1
--- /dev/null
+++ b/drivers/s390/block/Makefile
@@ -0,0 +1,31 @@
+all: s390-block.o
+
+CFLAGS +=
+O_TARGET := s390-block.o
+O_OBJS :=
+M_OBJS :=
+
+ifeq ($(CONFIG_DASD),y)
+ O_OBJS += dasd.o dasd_ccwstuff.o dasd_erp.o
+ ifeq ($(CONFIG_PROC_FS),y)
+ O_OBJS += dasd_proc.o dasd_profile.o
+ endif
+ ifeq ($(CONFIG_DASD_ECKD),y)
+ O_OBJS += dasd_eckd.o
+ endif
+ ifeq ($(CONFIG_DASD_MDSK),y)
+ O_OBJS += dasd_mdsk.o
+ endif
+# ifeq ($(CONFIG_DASD_CKD),y)
+# O_OBJS += dasd_ckd.o
+# endif
+endif
+
+ifeq ($(CONFIG_MDISK),y)
+ O_OBJS += mdisk.o
+endif
+
+dasd_mod.o: $(D_OBJS)
+ $(LD) $(LD_RFLAG) -r -o $@ $+
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
new file mode 100644
index 000000000..79e8f27dc
--- /dev/null
+++ b/drivers/s390/block/dasd.c
@@ -0,0 +1,1560 @@
+/*
+ * File...........: linux/drivers/s390/block/dasd.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * : Utz Bacher <utz.bacher@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif /* MODULE */
+
+#include <linux/tqueue.h>
+#include <linux/timer.h>
+#include <linux/malloc.h>
+#include <linux/genhd.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/hdreg.h>
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/ebcdic.h>
+#include <asm/uaccess.h>
+
+#include <asm/irq.h>
+
+#include <linux/dasd.h>
+#include <linux/blk.h>
+
+#include "dasd_erp.h"
+#include "dasd_types.h"
+#include "dasd_ccwstuff.h"
+
+#define PRINTK_HEADER DASD_NAME":"
+
+#define CCW_READ_DEVICE_CHARACTERISTICS 0x64
+
+#define DASD_SSCH_RETRIES 2
+
+/* This macro is a little tricky, but makes the code more easy to read... */
+#define MATCH(info,ct,cm,dt,dm) ( \
+(( info -> sid_data.cu_type ct ) && ( info -> sid_data.cu_model cm )) && \
+(( info -> sid_data.dev_type dt ) && ( info -> sid_data.dev_model dm )) )
+
+/* Prototypes for the functions called from external */
+static int dasd_ioctl (struct inode *, struct file *, unsigned int, unsigned long);
+static int dasd_open (struct inode *, struct file *);
+static int dasd_release (struct inode *, struct file *);
+
+void dasd_debug (unsigned long tag);
+void dasd_profile_add (cqr_t *cqr);
+void dasd_proc_init (void);
+
+static int dasd_format( int, format_data_t * );
+
+static struct block_device_operations dasd_device_operations;
+
+spinlock_t dasd_lock; /* general purpose lock for the dasd driver */
+
+/* All asynchronous I/O should waint on this wait_queue */
+wait_queue_head_t dasd_waitq;
+
+static int dasd_autodetect = 1;
+static int dasd_devno[DASD_MAX_DEVICES] =
+{0,};
+static int dasd_count = 0;
+
+extern dasd_chanq_t *cq_head;
+
+static int
+dasd_get_hexdigit (char c)
+{
+ if ((c >= '0') && (c <= '9'))
+ return c - '0';
+ if ((c >= 'a') && (c <= 'f'))
+ return c + 10 - 'a';
+ if ((c >= 'A') && (c <= 'F'))
+ return c + 10 - 'A';
+ return -1;
+}
+
+/* sets the string pointer after the next comma */
+static void
+dasd_scan_for_next_comma (char **strptr)
+{
+ while (((**strptr) != ',') && ((**strptr)++))
+ (*strptr)++;
+
+ /* set the position AFTER the comma */
+ if (**strptr == ',')
+ (*strptr)++;
+}
+
+/*sets the string pointer after the next comma, if a parse error occured */
+static int
+dasd_get_next_int (char **strptr)
+{
+ int j, i = -1; /* for cosmetic reasons first -1, then 0 */
+ if (isxdigit (**strptr)) {
+ for (i = 0; isxdigit (**strptr);) {
+ i <<= 4;
+ j = dasd_get_hexdigit (**strptr);
+ if (j == -1) {
+ PRINT_ERR ("no integer: skipping range.\n");
+ dasd_scan_for_next_comma (strptr);
+ i = -1;
+ break;
+ }
+ i += j;
+ (*strptr)++;
+ if (i > 0xffff) {
+ PRINT_ERR (" value too big, skipping range.\n");
+ dasd_scan_for_next_comma (strptr);
+ i = -1;
+ break;
+ }
+ }
+ }
+ return i;
+}
+
+static inline int
+devindex_from_devno (int devno)
+{
+ int i;
+ for (i = 0; i < dasd_count; i++) {
+ if (dasd_devno[i] == devno)
+ return i;
+ }
+ if (dasd_autodetect) {
+ if (dasd_count < DASD_MAX_DEVICES) {
+ dasd_devno[dasd_count] = devno;
+ return dasd_count++;
+ }
+ return -EOVERFLOW;
+ }
+ return -ENODEV;
+}
+
+/* returns 1, if dasd_no is in the specified ranges, otherwise 0 */
+static inline int
+dasd_is_accessible (int devno)
+{
+ return (devindex_from_devno (devno) >= 0);
+}
+
+/* dasd_insert_range skips ranges, if the start or the end is -1 */
+static void
+dasd_insert_range (int start, int end)
+{
+ int curr;
+ FUNCTION_ENTRY ("dasd_insert_range");
+ if (dasd_count >= DASD_MAX_DEVICES) {
+ PRINT_ERR (" too many devices specified, ignoring some.\n");
+ FUNCTION_EXIT ("dasd_insert_range");
+ return;
+ }
+ if ((start == -1) || (end == -1)) {
+ PRINT_ERR
+ ("invalid format of parameter, skipping range\n");
+ FUNCTION_EXIT ("dasd_insert_range");
+ return;
+ }
+ if (end < start) {
+ PRINT_ERR (" ignoring range from %x to %x - start value " \
+ "must be less than end value.\n", start, end);
+ FUNCTION_EXIT ("dasd_insert_range");
+ return;
+ }
+/* concurrent execution would be critical, but will not occur here */
+ for (curr = start; curr <= end; curr++) {
+ if (dasd_is_accessible (curr)) {
+ PRINT_WARN (" %x is already in list as device %d\n",
+ curr, devindex_from_devno (curr));
+ }
+ dasd_devno[dasd_count] = curr;
+ dasd_count++;
+ if (dasd_count >= DASD_MAX_DEVICES) {
+ PRINT_ERR (" too many devices specified, ignoring some.\n");
+ break;
+ }
+ }
+ PRINT_INFO (" added dasd range from %x to %x.\n",
+ start, dasd_devno[dasd_count - 1]);
+
+ FUNCTION_EXIT ("dasd_insert_range");
+}
+
+static int __init
+dasd_setup (char *str)
+{
+ int devno, devno2;
+
+ FUNCTION_ENTRY ("dasd_setup");
+ dasd_autodetect = 0;
+ while (*str && *str != 1) {
+ if (!isxdigit (*str)) {
+ str++; /* to avoid looping on two commas */
+ PRINT_ERR (" kernel parameter in invalid format.\n");
+ continue;
+ }
+ devno = dasd_get_next_int (&str);
+
+ /* range was skipped? -> scan for comma has been done */
+ if (devno == -1)
+ continue;
+
+ if (*str == ',') {
+ str++;
+ dasd_insert_range (devno, devno);
+ continue;
+ }
+ if (*str == '-') {
+ str++;
+ devno2 = dasd_get_next_int (&str);
+ if (devno2 == -1) {
+ PRINT_ERR (" invalid character in " \
+ "kernel parameters.");
+ } else {
+ dasd_insert_range (devno, devno2);
+ }
+ dasd_scan_for_next_comma (&str);
+ continue;
+ }
+ if (*str == 0) {
+ dasd_insert_range (devno, devno);
+ break;
+ }
+ PRINT_ERR (" unexpected character in kernel parameter, " \
+ "skipping range.\n");
+ }
+ FUNCTION_EXIT ("dasd_setup");
+ return 1;
+}
+
+__setup("dasd=", dasd_setup);
+
+dasd_information_t *dasd_info[DASD_MAX_DEVICES] = {NULL,};
+static struct hd_struct dd_hdstruct[DASD_MAX_DEVICES << PARTN_BITS];
+static int dasd_blks[256] = {0,};
+static int dasd_secsize[256] = {0,};
+static int dasd_blksize[256] = {0,};
+static int dasd_maxsecs[256] = {0,};
+
+struct gendisk dd_gendisk =
+{
+ MAJOR_NR, /* Major number */
+ "dasd", /* Major name */
+ PARTN_BITS, /* Bits to shift to get real from partn */
+ 1 << PARTN_BITS, /* Number of partitions per real */
+ dd_hdstruct, /* hd struct */
+ dasd_blks, /* sizes in blocks */
+ DASD_MAX_DEVICES, /* number */
+ NULL, /* internal */
+ NULL /* next */
+
+};
+
+static atomic_t bh_scheduled = ATOMIC_INIT (0);
+
+static inline void
+schedule_bh (void (*func) (void))
+{
+ static struct tq_struct dasd_tq =
+ {0,};
+ /* Protect against rescheduling, when already running */
+ if (atomic_compare_and_swap (0, 1, &bh_scheduled))
+ return;
+ dasd_tq.routine = (void *) (void *) func;
+ queue_task (&dasd_tq, &tq_immediate);
+ mark_bh (IMMEDIATE_BH);
+ return;
+}
+
+void
+sleep_done (struct semaphore *sem)
+{
+ if (sem != NULL) {
+ up (sem);
+ }
+}
+
+void
+sleep (int timeout)
+{
+ struct semaphore sem;
+ struct timer_list timer;
+
+ init_MUTEX_LOCKED (&sem);
+ init_timer (&timer);
+ timer.data = (unsigned long) &sem;
+ timer.expires = jiffies + timeout;
+ timer.function = (void (*)(unsigned long)) sleep_done;
+ printk (KERN_DEBUG PRINTK_HEADER
+ "Sleeping for timer tics %d\n", timeout);
+ add_timer (&timer);
+ down (&sem);
+ del_timer (&timer);
+}
+
+#ifdef CONFIG_DASD_ECKD
+extern dasd_operations_t dasd_eckd_operations;
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+extern dasd_operations_t dasd_mdsk_operations;
+#endif /* CONFIG_DASD_MDSK */
+
+dasd_operations_t *dasd_disciplines[] =
+{
+#ifdef CONFIG_DASD_ECKD
+ &dasd_eckd_operations,
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+ &dasd_mdsk_operations,
+#endif /* CONFIG_DASD_MDSK */
+#ifdef CONFIG_DASD_CKD
+ &dasd_ckd_operations,
+#endif /* CONFIG_DASD_CKD */
+ NULL
+};
+
+char *dasd_name[] =
+{
+#ifdef CONFIG_DASD_ECKD
+ "ECKD",
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+ "MDSK",
+#endif /* CONFIG_DASD_MDSK */
+#ifdef CONFIG_DASD_CKD
+ "CKD",
+#endif /* CONFIG_DASD_CKD */
+ "END"
+};
+
+
+static inline int
+do_dasd_ioctl (struct inode *inp, unsigned int no, unsigned long data)
+{
+ int rc;
+ int di;
+ dasd_information_t *dev;
+
+ di = DEVICE_NR (inp->i_rdev);
+ if (!dasd_info[di]) {
+ PRINT_WARN ("No device registered as %d\n", inp->i_rdev);
+ return -EINVAL;
+ }
+ if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) {
+ PRINT_DEBUG ("empty data ptr");
+ return -EINVAL;
+ }
+ dev = dasd_info[di];
+ if (!dev) {
+ PRINT_WARN ("No device registered as %d\n", inp->i_rdev);
+ return -EINVAL;
+ }
+ PRINT_INFO ("ioctl 0x%08x %s'0x%x'%d(%d) on dev %d/%d (%d) with data %8lx\n", no,
+ _IOC_DIR (no) == _IOC_NONE ? "0" :
+ _IOC_DIR (no) == _IOC_READ ? "r" :
+ _IOC_DIR (no) == _IOC_WRITE ? "w" :
+ _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
+ _IOC_TYPE (no), _IOC_NR (no), _IOC_SIZE (no),
+ MAJOR (inp->i_rdev), MINOR (inp->i_rdev), di, data);
+
+ switch (no) {
+ case BLKGETSIZE:{ /* Return device size */
+ unsigned long blocks;
+ if (inp->i_rdev & 0x01) {
+ blocks = (dev->sizes.blocks - 3) <<
+ dev->sizes.s2b_shift;
+ } else {
+ blocks = dev->sizes.kbytes << dev->sizes.s2b_shift;
+ }
+ rc = copy_to_user ((long *) data, &blocks, sizeof (long));
+ break;
+ }
+ case BLKFLSBUF:{
+ rc = fsync_dev (inp->i_rdev);
+ break;
+ }
+ case BLKRAGET:{
+ rc = copy_to_user ((long *) data,
+ read_ahead + MAJOR_NR, sizeof (long));
+ break;
+ }
+ case BLKRASET:{
+ rc = copy_from_user (read_ahead + MAJOR_NR,
+ (long *) data, sizeof (long));
+ break;
+ }
+ case BLKRRPART:{
+ INTERNAL_CHECK ("BLKRPART not implemented%s", "");
+ rc = -EINVAL;
+ break;
+ }
+ case HDIO_GETGEO:{
+ INTERNAL_CHECK ("HDIO_GETGEO not implemented%s", "");
+ rc = -EINVAL;
+ break;
+ }
+
+ case BIODASDRSID:{
+ rc = copy_to_user ((void *) data,
+ &(dev->info.sid_data),
+ sizeof (senseid_t));
+ break;
+ }
+ case BIODASDRWTB:{
+ int offset = 0;
+ int xlt;
+ rc = copy_from_user (&xlt, (void *) data,
+ sizeof (int));
+ PRINT_INFO("Xlating %d to",xlt);
+ if (rc)
+ break;
+ if (MINOR (inp->i_rdev) & 1)
+ offset = 3;
+ xlt += offset;
+ printk(" %d \n",xlt);
+ rc = copy_to_user ((void *) data, &xlt,
+ sizeof (int));
+ break;
+ }
+ case BIODASDFORMAT:{
+ /* fdata == NULL is a valid arg to dasd_format ! */
+ format_data_t *fdata = NULL;
+ if (data) {
+ fdata = kmalloc (sizeof (format_data_t),
+ GFP_ATOMIC);
+ if (!fdata) {
+ rc = -ENOMEM;
+ break;
+ }
+ rc = copy_from_user (fdata, (void *) data,
+ sizeof (format_data_t));
+ if (rc)
+ break;
+ }
+ rc = dasd_format (inp->i_rdev, fdata);
+ if (fdata) {
+ kfree (fdata);
+ }
+ break;
+ }
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+static void
+dasd_end_request (struct request *req, int uptodate)
+{
+ struct buffer_head *bh;
+ FUNCTION_ENTRY ("dasd_end_request");
+#if DASD_PARANOIA > 2
+ if (!req) {
+ INTERNAL_CHECK ("end_request called with zero arg%s\n", "");
+ }
+#endif /* DASD_PARANOIA */
+ while ((bh = req->bh) != NULL) {
+ req->bh = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ bh->b_end_io (bh, uptodate);
+ }
+ if (!end_that_request_first (req, uptodate, DEVICE_NAME)) {
+#ifndef DEVICE_NO_RANDOM
+ add_blkdev_randomness (MAJOR (req->rq_dev));
+#endif
+ DEVICE_OFF (req->rq_dev);
+ end_that_request_last (req);
+ }
+ FUNCTION_EXIT ("dasd_end_request");
+ return;
+}
+
+void
+dasd_wakeup (void)
+{
+ wake_up (&dasd_waitq);
+}
+
+int
+dasd_unregister_dasd (int irq, dasd_type_t dt, dev_info_t * info)
+{
+ int rc = 0;
+ FUNCTION_ENTRY ("dasd_unregister_dasd");
+ INTERNAL_CHECK ("dasd_unregister_dasd not implemented%s\n", "");
+ FUNCTION_EXIT ("dasd_unregister_dasd");
+ return rc;
+}
+
+/* Below you find the functions already cleaned up */
+static dasd_type_t
+check_type (dev_info_t * info)
+{
+ dasd_type_t type = dasd_none;
+
+ FUNCTION_ENTRY ("check_type");
+#ifdef CONFIG_DASD_ECKD
+ if (MATCH (info, == 0x3990, ||1, == 0x3390, ||1) ||
+ MATCH (info, == 0x9343, ||1, == 0x9345, ||1) ||
+ MATCH (info, == 0x3990, ||1, == 0x3380, ||1)) {
+ type = dasd_eckd;
+ } else
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+ if ( MACHINE_IS_VM ) {
+ type = dasd_mdsk;
+ } else
+#endif /* CONFIG_DASD_MDSK */
+ {
+ type = dasd_none;
+ }
+
+ FUNCTION_EXIT ("check_type");
+ return type;
+}
+
+static int
+dasd_read_characteristics (dasd_information_t * info)
+{
+ int rc;
+ int ct = 0;
+ dev_info_t *di;
+ dasd_type_t dt;
+
+ FUNCTION_ENTRY ("read_characteristics");
+ if (info == NULL) {
+ return -ENODEV;
+ }
+ di = &(info->info);
+ if (di == NULL) {
+ return -ENODEV;
+ }
+ dt = check_type (di);
+ /* Some cross-checks, if the cu supports RDC */
+ if (MATCH (di, == 0x2835, ||1, ||1, ||1) ||
+ MATCH (di, == 0x3830, ||1, ||1, ||1) ||
+ MATCH (di, == 0x3830, ||1, ||1, ||1) ||
+ MATCH (di, == 0x3990, <=0x03, == 0x3380, <=0x0d)) {
+ PRINT_WARN ("Device %d (%x/%x at %x/%x) supports no RDC\n",
+ info->info.irq,
+ di->sid_data.dev_type,
+ di->sid_data.dev_model,
+ di->sid_data.cu_type,
+ di->sid_data.cu_model);
+ return -EINVAL;
+ }
+ switch (dt) {
+#ifdef CONFIG_DASD_ECKD
+ case dasd_eckd:
+ ct = 64;
+ rc = read_dev_chars (info->info.irq,
+ (void *) &(info->rdc_data), ct);
+ break;
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+ case dasd_mdsk:
+ ct = 0;
+ break;
+#endif /* CONFIG_DASD_MDSK */
+ default:
+ INTERNAL_ERROR ("don't know dasd type %d\n", dt);
+ }
+ if (rc) {
+ PRINT_WARN ("RDC resulted in rc=%d\n", rc);
+ }
+ FUNCTION_EXIT ("read_characteristics");
+ return rc;
+}
+
+/* How many sectors must be in a request to dequeue it ? */
+#define QUEUE_BLOCKS 25
+#define QUEUE_SECTORS (QUEUE_BLOCKS << dasd_info[di]->sizes.s2b_shift)
+
+/* How often to retry an I/O before raising an error */
+#define DASD_MAX_RETRIES 5
+
+
+static inline
+ cqr_t *
+dasd_cqr_from_req (struct request *req)
+{
+ cqr_t *cqr = NULL;
+ int di;
+ dasd_information_t *info;
+
+ if (!req) {
+ PRINT_ERR ("No request passed!");
+ return NULL;
+ }
+ di = DEVICE_NR (req->rq_dev);
+ info = dasd_info[di];
+ if (!info)
+ return NULL;
+ /* if applicable relocate block */
+ if (MINOR (req->rq_dev) & ((1 << PARTN_BITS) - 1) ) {
+ req->sector +=
+ dd_gendisk.part[MINOR(req->rq_dev)].start_sect;
+ }
+ /* Now check for consistency */
+ if (!req->nr_sectors) {
+ PRINT_WARN ("req: %p dev: %08x sector: %ld nr_sectors: %ld bh: %p\n",
+ req, req->rq_dev, req->sector, req->nr_sectors, req->bh);
+ return NULL;
+ }
+ if (((req->sector + req->nr_sectors) >> 1) > info->sizes.kbytes) {
+ printk (KERN_ERR PRINTK_HEADER
+ "Requesting I/O past end of device %d\n",
+ di);
+ return NULL;
+ }
+ cqr = dasd_disciplines[info->type]->get_req_ccw (di, req);
+ if (!cqr) {
+ PRINT_WARN ("empty CQR generated\n");
+ } else {
+ cqr->req = req;
+ cqr->int4cqr = cqr;
+ cqr->devindex = di;
+#ifdef DASD_PROFILE
+ asm volatile ("STCK %0":"=m" (cqr->buildclk));
+#endif /* DASD_PROFILE */
+ if (atomic_compare_and_swap (CQR_STATUS_EMPTY,
+ CQR_STATUS_FILLED,
+ &cqr->status)) {
+ PRINT_WARN ("cqr from req stat changed %d\n",
+ atomic_read (&cqr->status));
+ }
+ }
+ return cqr;
+}
+
+int
+dasd_start_IO (cqr_t * cqr)
+{
+ int rc = 0;
+ int retries = DASD_SSCH_RETRIES;
+ int di, irq;
+
+ dasd_debug ((unsigned long) cqr); /* cqr */
+
+ if (!cqr) {
+ PRINT_WARN ("(start_IO) no cqr passed\n");
+ return -EINVAL;
+ }
+ if (cqr->magic != DASD_MAGIC) {
+ PRINT_WARN ("(start_IO) magic number mismatch\n");
+ return -EINVAL;
+ }
+ if (atomic_compare_and_swap (CQR_STATUS_QUEUED,
+ CQR_STATUS_IN_IO,
+ &cqr->status)) {
+ PRINT_WARN ("start_IO: status changed %d\n",
+ atomic_read (&cqr->status));
+ atomic_set (&cqr->status, CQR_STATUS_ERROR);
+ return -EINVAL;
+ }
+ di = cqr->devindex;
+ irq = dasd_info[di]->info.irq;
+ do {
+ asm volatile ("STCK %0":"=m" (cqr->startclk));
+ rc = do_IO (irq, cqr->cpaddr, (long) cqr, 0x00, cqr->options);
+ switch (rc) {
+ case 0:
+ if (!(cqr->options & DOIO_WAIT_FOR_INTERRUPT))
+ atomic_set_mask (DASD_CHANQ_BUSY,
+ &dasd_info[di]->queue.flags);
+ break;
+ case -ENODEV:
+ PRINT_WARN ("cqr %p: 0x%04x error, %d retries left\n",
+ cqr, dasd_info[di]->info.devno, retries);
+ break;
+ case -EIO:
+ PRINT_WARN ("cqr %p: 0x%04x I/O, %d retries left\n",
+ cqr, dasd_info[di]->info.devno, retries);
+ break;
+ case -EBUSY: /* set up timer, try later */
+
+ PRINT_WARN ("cqr %p: 0x%04x busy, %d retries left\n",
+ cqr, dasd_info[di]->info.devno, retries);
+ break;
+ default:
+
+ PRINT_WARN ("cqr %p: 0x%04x %d, %d retries left\n",
+ cqr, rc, dasd_info[di]->info.devno,
+ retries);
+ break;
+ }
+ } while (rc && --retries);
+ if (rc) {
+ if (atomic_compare_and_swap (CQR_STATUS_IN_IO,
+ CQR_STATUS_ERROR,
+ &cqr->status)) {
+ PRINT_WARN ("start_IO:(done) status changed %d\n",
+ atomic_read (&cqr->status));
+ atomic_set (&cqr->status, CQR_STATUS_ERROR);
+ }
+ }
+ return rc;
+}
+
+static inline
+void
+dasd_end_cqr (cqr_t * cqr, int uptodate)
+{
+ struct request *req = cqr->req;
+ asm volatile ("STCK %0":"=m" (cqr->endclk));
+#ifdef DASD_PROFILE
+ dasd_profile_add (cqr);
+#endif /* DASD_PROFILE */
+ dasd_chanq_deq (&dasd_info[cqr->devindex]->queue, cqr);
+ if (req) {
+ dasd_end_request (req, uptodate);
+ }
+}
+
+void
+dasd_dump_sense (devstat_t * stat)
+{
+ int sl, sct;
+ if ( ! stat->flag | DEVSTAT_FLAG_SENSE_AVAIL) {
+ PRINT_INFO("I/O status w/o sense data");
+ } else {
+ printk (KERN_INFO PRINTK_HEADER
+ "-------------------I/O result:-----------\n");
+ for (sl = 0; sl < 4; sl++) {
+ printk (KERN_INFO PRINTK_HEADER "Sense:");
+ for (sct = 0; sct < 8; sct++) {
+ printk (" %2d:0x%02X", 8 * sl + sct,
+ stat->ii.sense.data[8 * sl + sct]);
+ }
+ printk ("\n");
+ }
+ }
+}
+
+static int
+register_dasd_last (int di)
+{
+ int rc = 0;
+ int minor;
+ struct buffer_head *bh;
+ rc = dasd_disciplines[dasd_info[di]->type]->fill_sizes_last (di);
+ switch (rc) {
+ case -EMEDIUMTYPE:
+ dasd_info[di]->flags |= DASD_INFO_FLAGS_NOT_FORMATTED;
+ break;
+ }
+ PRINT_INFO ("%ld kB <- 'soft'-block: %d, hardsect %d Bytes\n",
+ dasd_info[di]->sizes.kbytes,
+ dasd_info[di]->sizes.bp_block,
+ dasd_info[di]->sizes.bp_sector);
+ switch (dasd_info[di]->type) {
+#ifdef CONFIG_DASD_ECKD
+ case dasd_eckd:
+ dasd_info[di]->sizes.label_block = 2;
+ break;
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+ case dasd_mdsk:
+ dasd_info[di]->sizes.label_block = -1;
+ break;
+#endif /* CONFIG_DASD_ECKD */
+
+ default:
+ INTERNAL_CHECK ("Unknown dasd type %d\n", dasd_info[di]->type);
+ }
+ minor = di << PARTN_BITS;
+ dasd_blks[minor] = dasd_info[di]->sizes.kbytes;
+ dasd_secsize[minor] = dasd_info[di]->sizes.bp_sector;
+ dasd_blksize[minor] = dasd_info[di]->sizes.bp_block;
+ dasd_maxsecs[minor] = 252<<dasd_info[di]->sizes.s2b_shift;
+ dasd_secsize[minor+1] = dasd_info[di]->sizes.bp_sector;
+ dasd_blksize[minor+1] = dasd_info[di]->sizes.bp_block;
+ dasd_maxsecs[minor+1] = 252<<dasd_info[di]->sizes.s2b_shift;
+
+ {
+#define DASD_NAME_PREFIX "dasd_"
+ char * name = (char *) kmalloc ( 1+strlen (DASD_NAME_PREFIX) +
+ 2 /* 0x */ + 4 /* devno */,
+ GFP_KERNEL);
+ sprintf ( name , DASD_NAME_PREFIX "%04x%c",
+ dasd_info[di]->info.devno,'\0' );
+ dasd_info[di] -> devfs_entry =
+ devfs_register ( NULL /* dir */,
+ name, strlen(name),
+ 0 /* flags */,
+ DASD_MAJOR, minor,
+ 0755 /* mode */,
+ 0 /* uid */ , 0 /* gid */,
+ &dasd_device_operations,
+ (void *)dasd_info[di]);
+ }
+ /* end of that stuff */
+ return rc;
+}
+
+void
+dasd_partn_detect ( int di )
+{
+ int minor = di << PARTN_BITS;
+ LOOP_CONTROL ("Setting partitions of DASD %d\n", di);
+ register_disk (&dd_gendisk,
+ MKDEV(DASD_MAJOR,minor),
+ 1 << PARTN_BITS,
+ &dasd_device_operations,
+ dasd_info[di]->sizes.kbytes << 1);
+}
+
+void
+dasd_do_chanq (void)
+{
+ dasd_chanq_t *qp = NULL;
+ cqr_t *cqr;
+ long flags;
+ int irq;
+ int tasks;
+ atomic_set (&bh_scheduled, 0);
+ dasd_debug (0xc4c40000); /* DD */
+ while ((tasks = atomic_read(&chanq_tasks)) != 0) {
+/* initialization and wraparound */
+ if (qp == NULL) {
+ dasd_debug (0xc4c46df0); /* DD_0 */
+ qp = cq_head;
+ if (!qp) {
+ dasd_debug (0xc4c46ff1); /* DD?1 */
+ dasd_debug (tasks);
+ PRINT_ERR("Mismatch of NULL queue pointer and "
+ "still %d chanq_tasks to do!!\n"
+ "Please send output of /proc/dasd/debug "
+ "to Linux390@de.ibm.com\n", tasks);
+ atomic_set(&chanq_tasks,0);
+ break;
+ }
+ }
+/* Get first request */
+ dasd_debug ((unsigned long) qp);
+ cqr = (cqr_t *) (qp->head);
+/* empty queue -> dequeue and proceed */
+ if (!cqr) {
+ dasd_chanq_t *nqp = qp->next_q;
+ cql_deq (qp);
+ qp = nqp;
+ continue;
+ }
+/* process all requests on that queue */
+ do {
+ cqr_t *next;
+ dasd_debug ((unsigned long) cqr); /* cqr */
+ if (cqr->magic != DASD_MAGIC) {
+ dasd_debug (0xc4c46ff2); /* DD?2 */
+ panic ( PRINTK_HEADER "do_cq:"
+ "magic mismatch %p -> %x\n",
+ cqr, cqr -> magic);
+ break;
+ }
+ irq = dasd_info[cqr->devindex]->info.irq;
+ s390irq_spin_lock_irqsave (irq, flags);
+ switch (atomic_read (&cqr->status)) {
+ case CQR_STATUS_IN_IO:
+ dasd_debug (0xc4c4c9d6); /* DDIO */
+ cqr = NULL;
+ break;
+ case CQR_STATUS_QUEUED:
+ dasd_debug (0xc4c4e2e3); /* DDST */
+ if (dasd_start_IO (cqr) == 0) {
+ atomic_dec (&chanq_tasks);
+ cqr = NULL;
+ }
+ break;
+ case CQR_STATUS_ERROR:
+ dasd_debug (0xc4c4c5d9); /* DDER */
+ dasd_dump_sense (cqr->dstat);
+ if ( ++ cqr->retries < 2 ) {
+ atomic_set (&cqr->status,
+ CQR_STATUS_QUEUED);
+ dasd_debug (0xc4c4e2e3); /* DDST */
+ if (dasd_start_IO (cqr) == 0) {
+ atomic_dec ( &qp ->
+ dirty_requests);
+ atomic_dec (&chanq_tasks);
+ cqr = NULL;
+ }
+ } else {
+ atomic_set (&cqr->status,
+ CQR_STATUS_FAILED);
+ }
+ break;
+ case CQR_STATUS_DONE:
+ next = cqr->next;
+ dasd_debug (0xc4c49692); /* DDok */
+ dasd_end_cqr (cqr, 1);
+ atomic_dec (&chanq_tasks);
+ cqr = next;
+ break;
+ case CQR_STATUS_FAILED:
+ next = cqr->next;
+ dasd_debug (0xc4c47a7a); /* DD:: */
+ if ( ! ( dasd_info[cqr->devindex]-> flags &
+ DASD_INFO_FLAGS_INITIALIZED ) ) {
+ dasd_info[cqr->devindex]-> flags |=
+ DASD_INFO_FLAGS_INITIALIZED |
+ DASD_INFO_FLAGS_NOT_FORMATTED;
+ }
+ dasd_end_cqr (cqr, 0);
+ atomic_dec ( &qp -> dirty_requests );
+ atomic_dec (&chanq_tasks);
+ cqr = next;
+ break;
+ default:
+ PRINT_WARN ("unknown cqrstatus\n");
+ cqr = NULL;
+ }
+ s390irq_spin_unlock_irqrestore (irq, flags);
+ } while (cqr);
+ qp = qp->next_q;
+ }
+ spin_lock (&io_request_lock);
+ do_dasd_request (&blk_dev[DASD_MAJOR].request_queue);
+ spin_unlock (&io_request_lock);
+ dasd_debug (0xc4c46d6d); /* DD__ */
+}
+
+/*
+ The request_fn is called from ll_rw_blk for any new request.
+ We use it to feed the chanqs.
+ This implementation assumes we are serialized by the io_request_lock.
+ */
+
+#define QUEUE_THRESHOLD 5
+
+void
+do_dasd_request (request_queue_t *queue)
+{
+ struct request *req;
+ cqr_t *cqr;
+ dasd_chanq_t *q;
+ long flags;
+ int di, irq, go;
+ int broken, busy;
+
+ dasd_debug (0xc4d90000); /* DR */
+ dasd_debug ((unsigned long) __builtin_return_address(0));
+ go = 1;
+ while (go && !list_empty(&queue->queue_head)) {
+ req = blkdev_entry_next_request(&queue->queue_head);
+ req = blkdev_entry_next_request(&queue->queue_head);
+ di = DEVICE_NR (req->rq_dev);
+ dasd_debug ((unsigned long) req); /* req */
+ dasd_debug (0xc4d90000 + /* DR## */
+ ((((di/16)<9?(di/16)+0xf0:(di/16)+0xc1))<<8) +
+ (((di%16)<9?(di%16)+0xf0:(di%16)+0xc1)));
+ irq = dasd_info[di]->info.irq;
+ s390irq_spin_lock_irqsave (irq, flags);
+ q = &dasd_info[di]->queue;
+ busy = atomic_read(&q->flags) & DASD_CHANQ_BUSY;
+ broken = atomic_read(&q->flags)&DASD_REQUEST_Q_BROKEN;
+ if ( ! busy ||
+ ( ! broken &&
+ (req->nr_sectors >= QUEUE_SECTORS))) {
+ blkdev_dequeue_request(req);
+ /*
+ printk ( KERN_INFO "0x%04x %c %d %d\n",
+ req->rq_dev,req->cmd ?'w':'r',
+ req->sector,req->nr_sectors);
+ */
+ cqr = dasd_cqr_from_req (req);
+ if (!cqr) {
+ dasd_debug (0xc4d96ff1); /* DR?1 */
+ dasd_end_request (req, 0);
+ goto cont;
+ }
+ dasd_debug ((unsigned long) cqr); /* cqr */
+ dasd_chanq_enq (q, cqr);
+ if (!(atomic_read (&q->flags) &
+ DASD_CHANQ_ACTIVE)) {
+ cql_enq_head (q);
+ }
+ if ( ! busy ) {
+ atomic_clear_mask (DASD_REQUEST_Q_BROKEN,
+ &q->flags );
+ if (atomic_read( &q->dirty_requests) == 0 ) {
+ if ( dasd_start_IO (cqr) == 0 ) {
+ } else {
+ atomic_inc (&chanq_tasks);
+ schedule_bh (dasd_do_chanq);
+ }
+ }
+ }
+ } else {
+ dasd_debug (0xc4d9c2d9); /* DRBR */
+ atomic_set_mask (DASD_REQUEST_Q_BROKEN, &q->flags );
+ go = 0;
+ }
+ cont:
+ s390irq_spin_unlock_irqrestore (irq, flags);
+ }
+ dasd_debug (0xc4d96d6d); /* DR__ */
+}
+
+void
+dasd_handler (int irq, void *ds, struct pt_regs *regs)
+{
+ devstat_t *stat = (devstat_t *) ds;
+ int ip;
+ cqr_t *cqr;
+ int done_fast_io = 0;
+
+ dasd_debug (0xc4c80000); /* DH */
+ if (!stat)
+ PRINT_ERR ("handler called without devstat");
+ ip = stat->intparm;
+ dasd_debug (ip); /* intparm */
+ switch (ip) { /* filter special intparms... */
+ case 0x00000000: /* no intparm: unsolicited interrupt */
+ dasd_debug (0xc4c8a489); /* DHui */
+ PRINT_INFO ("Unsolicited interrupt on device %04X\n",
+ stat->devno);
+ dasd_dump_sense (stat);
+ return;
+ default:
+ if (ip & 0x80000001) {
+ dasd_debug (0xc4c8a489); /* DHui */
+ PRINT_INFO ("Spurious interrupt %08x on device %04X\n",
+ ip, stat->devno);
+ return;
+ }
+ cqr = (cqr_t *) ip;
+ if (cqr->magic != DASD_MAGIC) {
+ dasd_debug (0xc4c86ff1); /* DH?1 */
+ PRINT_ERR ("handler:magic mismatch on %p %08x\n",
+ cqr, cqr->magic);
+ return;
+ }
+ asm volatile ("STCK %0":"=m" (cqr->stopclk));
+ if ( ( stat->cstat == 0x00 &&
+ stat->dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END) ) ||
+ dasd_erp_examine ( cqr ) == dasd_era_none ) {
+ dasd_debug (0xc4c89692); /* DHok */
+ if (atomic_compare_and_swap (CQR_STATUS_IN_IO,
+ CQR_STATUS_DONE,
+ &cqr->status)) {
+ PRINT_WARN ("handler: cqrstat changed%d\n",
+ atomic_read (&cqr->status));
+ atomic_set(&cqr->status, CQR_STATUS_DONE);
+ }
+ if ( ! ( dasd_info[cqr->devindex]-> flags &
+ DASD_INFO_FLAGS_INITIALIZED ) ) {
+ int rc = register_dasd_last ( cqr->devindex );
+ dasd_info[cqr->devindex]-> flags |=
+ DASD_INFO_FLAGS_INITIALIZED;
+ if ( rc ) {
+ dasd_info[cqr->devindex]->flags &=
+ ~DASD_INFO_FLAGS_NOT_FORMATTED;
+ } else {
+ dasd_info[cqr->devindex]->flags |=
+ DASD_INFO_FLAGS_NOT_FORMATTED;
+ }
+ }
+ if (cqr->next) {
+ dasd_debug (0xc4c8e2e3); /* DHST */
+ if (dasd_start_IO (cqr->next) == 0) {
+ done_fast_io = 1;
+ } else {
+ atomic_inc (&chanq_tasks);
+ }
+ }
+ break;
+ }
+ /* only visited in case of error ! */
+ dasd_debug (0xc4c8c5d9); /* DHER */
+ if (!cqr->dstat)
+ cqr->dstat = kmalloc (sizeof (devstat_t),
+ GFP_ATOMIC);
+ if (cqr->dstat) {
+ memcpy (cqr->dstat, stat, sizeof (devstat_t));
+ } else {
+ PRINT_ERR ("no memory for dstat\n");
+ }
+ /* errorprocessing */
+ atomic_set (&cqr->status, CQR_STATUS_ERROR);
+ atomic_inc (&dasd_info[cqr->devindex]->queue.dirty_requests);
+ }
+ if (done_fast_io == 0)
+ atomic_clear_mask (DASD_CHANQ_BUSY,
+ &dasd_info[cqr->devindex]->queue.flags);
+
+ if (cqr->flags & DASD_DO_IO_SLEEP) {
+ dasd_debug (0xc4c8a6a4); /* DHwu */
+ dasd_wakeup ();
+ } else if (! (cqr->options & DOIO_WAIT_FOR_INTERRUPT) ){
+ dasd_debug (0xc4c8a293); /* DHsl */
+ atomic_inc (&chanq_tasks);
+ schedule_bh (dasd_do_chanq);
+ } else {
+ dasd_debug (0x64686f6f); /* DH_g */
+ dasd_debug (cqr->flags); /* DH_g */
+ }
+ dasd_debug (0xc4c86d6d); /* DHwu */
+}
+
+static int
+dasd_format (int dev, format_data_t * fdata)
+{
+ int rc;
+ int devindex = DEVICE_NR (dev);
+ dasd_chanq_t *q;
+ cqr_t *cqr;
+ int irq;
+ long flags;
+ PRINT_INFO ("Format called with devno %x\n", dev);
+ if (MINOR (dev) & (0xff >> (8 - PARTN_BITS))) {
+ PRINT_WARN ("Can't format partition! minor %x %x\n",
+ MINOR (dev), 0xff >> (8 - PARTN_BITS));
+ return -EINVAL;
+ }
+ down (&dasd_info[devindex]->sem);
+ if (dasd_info[devindex]->open_count == 1) {
+ rc = dasd_disciplines[dasd_info[devindex]->type]->
+ dasd_format (devindex, fdata);
+ if (rc) {
+ PRINT_WARN ("Formatting failed rc=%d\n", rc);
+ }
+ } else {
+ PRINT_WARN ("device is open! %d\n", dasd_info[devindex]->open_count);
+ rc = -EINVAL;
+ }
+ if (!rc) {
+#if DASD_PARANOIA > 1
+ if (!dasd_disciplines[dasd_info[devindex]->type]->fill_sizes_first) {
+ INTERNAL_CHECK ("No fill_sizes for dt=%d\n", dasd_info[devindex]->type);
+ } else
+#endif /* DASD_PARANOIA */
+ {
+ dasd_info[devindex]->flags &= ~DASD_INFO_FLAGS_INITIALIZED;
+ irq = dasd_info[devindex]->info.irq;
+ PRINT_INFO ("Trying to access DASD %x, irq %x, index %d\n",
+ get_devno_by_irq(irq), irq, devindex);
+ s390irq_spin_lock_irqsave (irq, flags);
+ q = &dasd_info[devindex]->queue;
+ cqr = dasd_disciplines[dasd_info[devindex]->type]->
+ fill_sizes_first (devindex);
+ dasd_chanq_enq (q, cqr);
+ schedule_bh(dasd_do_chanq);
+ s390irq_spin_unlock_irqrestore (irq, flags);
+ }
+ }
+ up (&dasd_info[devindex]->sem);
+ return rc;
+}
+
+
+static int
+register_dasd (int irq, dasd_type_t dt, dev_info_t * info)
+{
+ int rc = 0;
+ int di;
+ unsigned long flags;
+ dasd_chanq_t *q;
+ cqr_t * cqr;
+ static spinlock_t register_lock = SPIN_LOCK_UNLOCKED;
+ spin_lock (&register_lock);
+ FUNCTION_ENTRY ("register_dasd");
+ di = devindex_from_devno (info->devno);
+ if (di < 0) {
+ INTERNAL_CHECK ("Can't get index for devno %d\n", info->devno);
+ return -ENODEV;
+ }
+ if (dasd_info[di]) { /* devindex is not free */
+ INTERNAL_CHECK ("reusing allocated deviceindex %d\n", di);
+ return -ENODEV;
+ }
+ dasd_info[di] = (dasd_information_t *)
+ kmalloc (sizeof (dasd_information_t), GFP_ATOMIC);
+ if (dasd_info[di] == NULL) {
+ PRINT_WARN ("No memory for dasd_info_t on irq %d\n", irq);
+ return -ENOMEM;
+ }
+ memset (dasd_info[di], 0, sizeof (dasd_information_t));
+ memcpy (&(dasd_info[di]->info), info, sizeof (dev_info_t));
+ spin_lock_init (&dasd_info[di]->queue.f_lock);
+ spin_lock_init (&dasd_info[di]->queue.q_lock);
+ dasd_info[di]->type = dt;
+ dasd_info[di]->irq = irq;
+ init_MUTEX (&dasd_info[di]->sem);
+ rc = dasd_read_characteristics (dasd_info[di]);
+ if (rc) {
+ PRINT_WARN ("RDC returned error %d\n", rc);
+ rc = -ENODEV;
+ goto unalloc;
+ }
+#if DASD_PARANOIA > 1
+ if (dasd_disciplines[dt]->ck_characteristics)
+#endif /* DASD_PARANOIA */
+ rc = dasd_disciplines[dt]->
+ ck_characteristics (dasd_info[di]->rdc_data);
+
+ if (rc) {
+ INTERNAL_CHECK ("Discipline returned non-zero when"
+ "checking device characteristics%s\n", "");
+ rc = -ENODEV;
+ goto unalloc;
+ }
+ rc = request_irq (irq, dasd_handler, 0, "dasd",
+ &(dasd_info[di]->dev_status));
+ if (rc) {
+#if DASD_PARANOIA > 0
+ printk (KERN_WARNING PRINTK_HEADER
+ "Cannot register irq %d, rc=%d\n",
+ irq, rc);
+#endif /* DASD_PARANOIA */
+ rc = -ENODEV;
+ goto unalloc;
+ }
+#if DASD_PARANOIA > 1
+ if (!dasd_disciplines[dt]->fill_sizes_first) {
+ INTERNAL_CHECK ("No fill_sizes for dt=%d\n", dt);
+ goto unregister;
+ }
+#endif /* DASD_PARANOIA */
+ irq = dasd_info[di]->info.irq;
+ PRINT_INFO ("Trying to access DASD %x, irq %x, index %d\n",
+ get_devno_by_irq(irq), irq, di);
+ s390irq_spin_lock_irqsave (irq, flags);
+ q = &dasd_info[di]->queue;
+ cqr = dasd_disciplines[dt]->fill_sizes_first (di);
+ dasd_chanq_enq (q, cqr);
+ cql_enq_head(q);
+ if (dasd_start_IO(cqr) != 0) {
+ atomic_inc(&chanq_tasks);
+ }
+ s390irq_spin_unlock_irqrestore (irq, flags);
+
+ goto exit;
+
+ unregister:
+ free_irq (irq, &(dasd_info[di]->dev_status));
+ unalloc:
+ kfree (dasd_info[di]);
+ exit:
+ spin_unlock (&register_lock);
+ FUNCTION_EXIT ("register_dasd");
+ return rc;
+}
+
+static int
+probe_for_dasd (int irq)
+{
+ int rc;
+ dev_info_t info;
+ dasd_type_t dt;
+
+ FUNCTION_ENTRY ("probe_for_dasd");
+
+ rc = get_dev_info_by_irq (irq, &info);
+ if (rc == -ENODEV) { /* end of device list */
+ return rc;
+ }
+#if DASD_PARANOIA > 2
+ if (rc) {
+ INTERNAL_CHECK ("unknown rc %d of get_dev_info", rc);
+ return rc;
+ }
+#endif /* DASD_PARANOIA */
+ if ((info.status & DEVSTAT_NOT_OPER)) {
+ return -ENODEV;
+ }
+ dt = check_type (&info);
+ switch (dt) {
+#ifdef CONFIG_DASD_ECKD
+ case dasd_eckd:
+#endif /* CONFIG_DASD_ECKD */
+ FUNCTION_CONTROL ("Probing devno %d...\n", info.devno);
+ if (!dasd_is_accessible (info.devno)) {
+ FUNCTION_CONTROL ("out of range...skip%s\n", "");
+ return -ENODEV;
+ }
+ if (dasd_disciplines[dt]->ck_devinfo) {
+ rc = dasd_disciplines[dt]->ck_devinfo (&info);
+ }
+#if DASD_PARANOIA > 1
+ else {
+ INTERNAL_ERROR ("no ck_devinfo function%s\n", "");
+ return -ENODEV;
+ }
+#endif /* DASD_PARANOIA */
+ if (rc == -ENODEV) {
+ return rc;
+ }
+#if DASD_PARANOIA > 2
+ if (rc) {
+ INTERNAL_CHECK ("unknown error rc=%d\n", rc);
+ return -ENODEV;
+ }
+#endif /* DASD_PARANOIA */
+ rc = register_dasd (irq, dt, &info);
+ if (rc) {
+ PRINT_INFO ("devno %x not enabled as minor %d due to errors\n",
+ info.devno,
+ devindex_from_devno (info.devno) <<
+ PARTN_BITS);
+ } else {
+ PRINT_INFO ("devno %x added as minor %d (%s)\n",
+ info.devno,
+ devindex_from_devno (info.devno) << PARTN_BITS,
+ dasd_name[dt]);
+ }
+ case dasd_none:
+ break;
+ default:
+ PRINT_DEBUG ("unknown device type\n");
+ break;
+ }
+ FUNCTION_EXIT ("probe_for_dasd");
+ return rc;
+}
+
+static int
+register_major (int major)
+{
+ request_queue_t *q;
+ int rc = 0;
+
+ FUNCTION_ENTRY ("register_major");
+ rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);
+#if DASD_PARANOIA > 1
+ if (rc) {
+ PRINT_WARN ("registering major -> rc=%d aborting... \n", rc);
+ return rc;
+ }
+#endif /* DASD_PARANOIA */
+ q = BLK_DEFAULT_QUEUE(major);
+ blk_init_queue(q, do_dasd_request);
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
+ FUNCTION_CONTROL ("successfully registered major: %d\n", major);
+ FUNCTION_EXIT ("register_major");
+ return rc;
+}
+
+/*
+ Below you find functions which are called from outside. Some of them may be
+ static, because they are called by their function pointers only. Thus static
+ modifier is to make sure, that they are only called via the kernel's methods
+ */
+
+static int
+dasd_ioctl (struct inode *inp, struct file *filp,
+ unsigned int no, unsigned long data)
+{
+ int rc = 0;
+ FUNCTION_ENTRY ("dasd_ioctl");
+ if ((!inp) || !(inp->i_rdev)) {
+ return -EINVAL;
+ }
+ rc = do_dasd_ioctl (inp, no, data);
+ FUNCTION_EXIT ("dasd_ioctl");
+ return rc;
+}
+
+static int
+dasd_open (struct inode *inp, struct file *filp)
+{
+ int rc = 0;
+ dasd_information_t *dev;
+ FUNCTION_ENTRY ("dasd_open");
+ if ((!inp) || !(inp->i_rdev)) {
+ return -EINVAL;
+ }
+ dev = dasd_info[DEVICE_NR (inp->i_rdev)];
+ if (!dev) {
+ PRINT_DEBUG ("No device registered as %d (%d)\n",
+ inp->i_rdev, DEVICE_NR (inp->i_rdev));
+ return -EINVAL;
+ }
+ down (&dev->sem);
+ up (&dev->sem);
+#ifdef MODULE
+ MOD_INC_USE_COUNT;
+#endif /* MODULE */
+#if DASD_PARANOIA > 2
+ if (dev->open_count < 0) {
+ INTERNAL_ERROR ("open count cannot be less than 0: %d",
+ dev->open_count);
+ return -EINVAL;
+ }
+#endif /* DASD_PARANOIA */
+ dev->open_count++;
+ FUNCTION_EXIT ("dasd_open");
+ return rc;
+}
+
+static int
+dasd_release (struct inode *inp, struct file *filp)
+{
+ int rc = 0;
+ dasd_information_t *dev;
+ FUNCTION_ENTRY ("dasd_release");
+ if ((!inp) || !(inp->i_rdev)) {
+ return -EINVAL;
+ }
+ dev = dasd_info[DEVICE_NR (inp->i_rdev)];
+ if (!dev) {
+ PRINT_WARN ("No device registered as %d\n", inp->i_rdev);
+ return -EINVAL;
+ }
+#ifdef MODULE
+ MOD_DEC_USE_COUNT;
+#endif /* MODULE */
+#if DASD_PARANOIA > 2
+ if (!dev->open_count) {
+ PRINT_WARN ("device %d has not been opened before:\n",
+ inp->i_rdev);
+ }
+#endif /* DASD_PARANOIA */
+ dev->open_count--;
+#if DASD_PARANOIA > 2
+ if (dev->open_count < 0) {
+ INTERNAL_ERROR ("open count cannot be less than 0: %d",
+ dev->open_count);
+ return -EINVAL;
+ }
+#endif /* DASD_PARANOIA */
+ FUNCTION_EXIT ("dasd_release");
+ return rc;
+}
+
+static struct
+block_device_operations dasd_device_operations =
+{
+ ioctl: dasd_ioctl,
+ open: dasd_open,
+ release: dasd_release,
+};
+
+int
+dasd_init (void)
+{
+ int rc = 0;
+ int i;
+
+ FUNCTION_ENTRY ("dasd_init");
+ PRINT_INFO ("initializing...\n");
+ atomic_set (&chanq_tasks, 0);
+ atomic_set (&bh_scheduled, 0);
+ spin_lock_init (&dasd_lock);
+ init_waitqueue_head(&dasd_waitq);
+ /* First register to the major number */
+ rc = register_major (MAJOR_NR);
+#if DASD_PARANOIA > 1
+ if (rc) {
+ PRINT_WARN ("registering major_nr returned rc=%d\n", rc);
+ return rc;
+ }
+#endif /* DASD_PARANOIA */
+ read_ahead[MAJOR_NR] = 8;
+ blk_size[MAJOR_NR] = dasd_blks;
+ hardsect_size[MAJOR_NR] = dasd_secsize;
+ blksize_size[MAJOR_NR] = dasd_blksize;
+ max_sectors[MAJOR_NR] = dasd_maxsecs;
+#ifdef CONFIG_PROC_FS
+ dasd_proc_init ();
+#endif /* CONFIG_PROC_FS */
+ /* Now scan the device list for DASDs */
+ FUNCTION_CONTROL ("entering detection loop%s\n", "");
+ for (i = 0; i < NR_IRQS; i++) {
+ int irc; /* Internal return code */
+ LOOP_CONTROL ("Probing irq %d...\n", i);
+ irc = probe_for_dasd (i);
+ switch (irc) {
+ case 0:
+ LOOP_CONTROL ("Added DASD%s\n", "");
+ break;
+ case -ENODEV:
+ LOOP_CONTROL ("No DASD%s\n", "");
+ break;
+ case -EMEDIUMTYPE:
+ PRINT_WARN ("DASD not formatted%s\n", "");
+ break;
+ default:
+ INTERNAL_CHECK ("probe_for_dasd: unknown rc=%d", irc);
+ break;
+ }
+ }
+ FUNCTION_CONTROL ("detection loop completed %s partn check...\n", "");
+/* Finally do the genhd stuff */
+ dd_gendisk.next = gendisk_head;
+ gendisk_head = &dd_gendisk;
+ for ( i = 0; i < DASD_MAX_DEVICES; i ++ )
+ if ( dasd_info[i] )
+ dasd_partn_detect ( i );
+
+ FUNCTION_EXIT ("dasd_init");
+ return rc;
+}
+
+#ifdef MODULE
+int
+init_module (void)
+{
+ int rc = 0;
+
+ FUNCTION_ENTRY ("init_module");
+ PRINT_INFO ("trying to load module\n");
+ rc = dasd_init ();
+ if (rc == 0) {
+ PRINT_INFO ("module loaded successfully\n");
+ } else {
+ PRINT_WARN ("warning: Module load returned rc=%d\n", rc);
+ }
+ FUNCTION_EXIT ("init_module");
+ return rc;
+}
+
+void
+cleanup_module (void)
+{
+ int rc = 0;
+
+ FUNCTION_ENTRY ("cleanup_module");
+ PRINT_INFO ("trying to unload module \n");
+
+ /* FIXME: replace by proper unload functionality */
+ INTERNAL_ERROR ("Modules not yet implemented %s", "");
+
+ if (rc == 0) {
+ PRINT_INFO ("module unloaded successfully\n");
+ } else {
+ PRINT_WARN ("module unloaded with errors\n");
+ }
+ FUNCTION_EXIT ("cleanup_module");
+}
+#endif /* MODULE */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff --git a/drivers/s390/block/dasd_ccwstuff.c b/drivers/s390/block/dasd_ccwstuff.c
new file mode 100644
index 000000000..4f666da28
--- /dev/null
+++ b/drivers/s390/block/dasd_ccwstuff.c
@@ -0,0 +1,419 @@
+/*
+ * File...........: linux/drivers/s390/block/dasd_ccwstuff.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/dasd.h>
+#include <asm/atomic.h>
+
+#include "dasd_types.h"
+
+#define PRINTK_HEADER "dasd_ccw:"
+#define MAX_CP_POWER 9 /* Maximum allowed index */
+#define CP_PER_PAGE_POWER 9 /* Maximum index, fitting on page */
+
+#define get_free_pages __get_free_pages
+
+/* Stuff for the handling task_list */
+dasd_chanq_t *cq_head = NULL; /* head of task_list */
+atomic_t chanq_tasks;
+
+/* Array of freelists for the channel programs' -space */
+static ccw1_t *ccwarea[CP_PER_PAGE_POWER + 1] =
+{NULL,};
+
+/* array of pages retrieved for internal use */
+#define MAX_DASD_PAGES 64
+static int dasd_page_count = 0;
+static long dasd_page[MAX_DASD_PAGES];
+
+static spinlock_t ccw_lock=SPIN_LOCK_UNLOCKED; /* spinlock for ccwareas */
+static spinlock_t cq_lock=SPIN_LOCK_UNLOCKED; /* spinlock for cq_head */
+
+void
+ccwarea_enq (int index, ccw1_t * area)
+{
+ FUNCTION_ENTRY ("ccwarea_enq");
+#if DASD_PARANOIA > 2
+ if (!area) {
+ INTERNAL_CHECK ("zero area %s\n", "");
+ }
+ if (index > CP_PER_PAGE_POWER) {
+ INTERNAL_CHECK ("index too large %d\n", index);
+ }
+#endif
+ *(ccw1_t **) area = ccwarea[index];
+ ccwarea[index] = area;
+ FUNCTION_EXIT ("ccwarea_enq");
+ return;
+}
+
+ccw1_t *
+ccwarea_deq (int index)
+{
+ ccw1_t *cp;
+ FUNCTION_ENTRY ("ccwarea_deq");
+#if DASD_PARANOIA > 2
+ if (index > CP_PER_PAGE_POWER) {
+ INTERNAL_CHECK ("index too large %d\n", index);
+ }
+#endif
+ cp = ccwarea[index];
+ ccwarea[index] = *(ccw1_t **) ccwarea[index];
+#if DASD_PARANOIA > 2
+ if (!cp) {
+ INTERNAL_CHECK ("returning NULL %s\n", "");
+ }
+#endif
+ FUNCTION_EXIT ("ccwarea_deq");
+ return cp;
+}
+
+ccw1_t *
+request_cpa (int index)
+{
+ ccw1_t *freeblk;
+ FUNCTION_ENTRY ("request_cpa");
+ if (index > MAX_CP_POWER) {
+ INTERNAL_ERROR ("index too large %d\n", index);
+ freeblk = NULL;
+ goto exit;
+ }
+ if (index > CP_PER_PAGE_POWER) {
+ int pc = 1 << (index - CP_PER_PAGE_POWER);
+ do {
+ freeblk = (ccw1_t *) get_free_pages (GFP_ATOMIC, index - CP_PER_PAGE_POWER);
+ if (dasd_page_count + pc >= MAX_DASD_PAGES) {
+ PRINT_WARN ("Requesting too many pages...");
+ } else {
+ int i;
+ for (i = 0; i < pc; i++)
+ dasd_page[dasd_page_count++] =
+ (long) freeblk + i * PAGE_SIZE;
+ }
+ FUNCTION_CONTROL ("requesting index %d", index);
+ if ( ! freeblk ) {
+ panic ("No memory received\n");
+ }
+ } while (!freeblk);
+ memset(freeblk,0,PAGE_SIZE<<(index-CP_PER_PAGE_POWER));
+ goto exit;
+ }
+ while (ccwarea[index] == NULL) {
+ ccw1_t *blk;
+ if (index == CP_PER_PAGE_POWER) {
+ do {
+ blk = (ccw1_t *) get_free_page (GFP_ATOMIC);
+ if (dasd_page_count + 1 >= MAX_DASD_PAGES) {
+ PRINT_WARN ("Requesting too many pages...");
+ } else {
+ dasd_page[dasd_page_count++] =
+ (long) blk;
+ }
+ if (blk == NULL) {
+ PRINT_WARN ("Can't allocate page!\n");
+ }
+ } while ( ! blk );
+ memset(blk,0,PAGE_SIZE);
+ ccwarea_enq (CP_PER_PAGE_POWER, blk);
+ continue;
+ }
+ blk = request_cpa (index + 1);
+#if DASD_PARANOIA > 1
+ if (!blk) {
+ PRINT_WARN ("retrieved NULL");
+ }
+#endif /* DASD_PARANOIA */
+ ccwarea_enq (index, blk);
+ ccwarea_enq (index, blk + (1 << index));
+ }
+#if DASD_PARANOIA > 2
+ if (!ccwarea[index]) {
+ INTERNAL_ERROR ("ccwarea is NULL\n%s", "");
+ }
+#endif /* DASD_PARANOIA */
+
+ freeblk = ccwarea_deq (index);
+#if DASD_PARANOIA > 1
+ if (!freeblk) {
+ INTERNAL_ERROR ("freeblk is NULL\n%s", "");
+ }
+#endif /* DASD_PARANOIA */
+ exit:
+ FUNCTION_EXIT ("request_cpa");
+ return freeblk;
+}
+
+ccw1_t *
+request_cp (int size)
+{
+ ccw1_t *freeblk;
+ int index;
+ int blksize;
+ /* Determine the index of ccwarea to look at */
+ for (index = 0, blksize = 1;
+ size > blksize;
+ index++, blksize = blksize << 1) {
+ }
+ if (index > MAX_CP_POWER) {
+ INTERNAL_ERROR ("index too large %d\n", index);
+ }
+ spin_lock (&ccw_lock);
+ freeblk = request_cpa (index);
+ spin_unlock (&ccw_lock);
+ if (freeblk == NULL) {
+ printk (KERN_WARNING PRINTK_HEADER
+ "No way to deliver free ccw space\n");
+ }
+ return freeblk;
+}
+
+void
+release_cp (int size, ccw1_t * area)
+{
+ int index;
+ int blksize;
+ /* Determine the index of ccwarea to look at */
+ for (index = 0, blksize = 1;
+ size > blksize;
+ index++, blksize = blksize << 1) {
+ }
+ if (index > MAX_CP_POWER) {
+ INTERNAL_ERROR ("index too large %d\n", index);
+ } else if (index > CP_PER_PAGE_POWER) {
+ free_pages ((unsigned long) area,
+ index - CP_PER_PAGE_POWER);
+ INTERNAL_CHECK ("large index used: %d\n", index);
+ } else {
+ spin_lock (&ccw_lock);
+ ccwarea_enq (index, area);
+ spin_unlock (&ccw_lock);
+ }
+ return;
+}
+
+/* ---------------------------------------------------------- */
+
+static cqr_t *cqrp = NULL;
+static spinlock_t cqr_lock=SPIN_LOCK_UNLOCKED;
+
+void
+cqf_enq (cqr_t * cqf)
+{
+ *(cqr_t **) cqf = cqrp;
+ cqrp = cqf;
+}
+
+cqr_t *
+cqf_deq (void)
+{
+ cqr_t *cqr = cqrp;
+ cqrp = *(cqr_t **) cqrp;
+ return cqr;
+}
+
+cqr_t *
+request_cq (void)
+{
+ cqr_t *cqr = NULL;
+ int i;
+ cqr_t *area;
+
+ spin_lock (&cqr_lock);
+ while (cqrp == NULL) {
+ do {
+ area = (cqr_t *) get_free_page (GFP_ATOMIC);
+ if (area == NULL) {
+ printk (KERN_WARNING PRINTK_HEADER
+ "No memory for chanq area\n");
+ }
+ } while ( ! area );
+ memset(area,0,PAGE_SIZE);
+ if (dasd_page_count + 1 >= MAX_DASD_PAGES) {
+ PRINT_WARN ("Requesting too many pages...");
+ } else {
+ dasd_page[dasd_page_count++] =
+ (long) area;
+ }
+ for (i = 0; i < 4096 / sizeof (cqr_t); i++) {
+ cqf_enq (area + i);
+ }
+ }
+ cqr = cqf_deq ();
+ spin_unlock (&cqr_lock);
+ return cqr;
+}
+
+void
+release_cq (cqr_t * cqr)
+{
+ spin_lock (&cqr_lock);
+ cqf_enq (cqr);
+ spin_unlock (&cqr_lock);
+ return;
+}
+
+/* ----------------------------------------------------------- */
+cqr_t *
+request_cqr (int cpsize, int datasize)
+{
+ cqr_t *cqr = NULL;
+ cqr = request_cq ();
+ if (cqr == NULL) {
+ printk (KERN_WARNING PRINTK_HEADER __FILE__
+ "No memory for chanq request\n");
+ goto exit;
+ }
+ memset (cqr, 0, sizeof (cqr_t));
+ cqr -> magic = DASD_MAGIC;
+ if (cpsize) {
+ cqr->cpaddr = request_cp (cpsize);
+ if (cqr->cpaddr == NULL) {
+ printk (KERN_WARNING PRINTK_HEADER __FILE__
+ "No memory for channel program\n");
+ goto nocp;
+ }
+ cqr->cplength = cpsize;
+ }
+ if (datasize) {
+ do {
+ cqr->data = (char *) kmalloc (datasize, GFP_ATOMIC);
+ if (cqr->data == NULL) {
+ printk (KERN_WARNING PRINTK_HEADER __FILE__
+ "No memory for cqr data area\n");
+ }
+ } while (!cqr->data);
+ memset (cqr->data,0,datasize);
+ }
+ goto exit;
+ nocp:
+ release_cq (cqr);
+ cqr = NULL;
+ exit:
+ return cqr;
+}
+
+int
+release_cqr (cqr_t * cqr)
+{
+ int rc = 0;
+ if (cqr == NULL) {
+ rc = -ENOENT;
+ return rc;
+ }
+ if (cqr->data) {
+ kfree (cqr->data);
+ }
+ if (cqr->dstat) {
+ kfree (cqr->dstat);
+ }
+ if (cqr->cpaddr) {
+ release_cp (cqr->cplength, cqr->cpaddr);
+ }
+ cqr -> magic = dasd_MAGIC;
+ release_cq (cqr);
+ return rc;
+}
+
+/* -------------------------------------------------------------- */
+void
+dasd_chanq_enq (dasd_chanq_t * q, cqr_t * cqr)
+{
+ if (q->head != NULL) {
+ q->tail->next = cqr;
+ } else
+ q->head = cqr;
+ cqr->next = NULL;
+ q->tail = cqr;
+ q->queued_requests ++;
+ if (atomic_compare_and_swap(CQR_STATUS_FILLED,
+ CQR_STATUS_QUEUED,
+ &cqr->status)) {
+ PRINT_WARN ("q_cqr: %p status changed %d\n",
+ cqr,atomic_read(&cqr->status));
+ atomic_set(&cqr->status,CQR_STATUS_QUEUED);
+ }
+}
+
+int
+dasd_chanq_deq (dasd_chanq_t * q, cqr_t * cqr)
+{
+ cqr_t *prev;
+
+ if (cqr == NULL)
+ return -ENOENT;
+ if (cqr == (cqr_t *) q->head) {
+ q->head = cqr->next;
+ if (q->head == NULL)
+ q->tail = NULL;
+ } else {
+ prev = (cqr_t *) q->head;
+ while (prev && prev->next != cqr)
+ prev = prev->next;
+ if (prev == NULL)
+ return -ENOENT;
+ prev->next = cqr->next;
+ if (prev->next == NULL)
+ q->tail = prev;
+ }
+ cqr->next = NULL;
+ q->queued_requests --;
+ return release_cqr(cqr);
+}
+
+/* -------------------------------------------------------------------------- */
+void
+cql_enq_head (dasd_chanq_t * q)
+{
+ if (q == NULL) {
+ INTERNAL_ERROR ("NULL queue passed%s\n", "");
+ return;
+ }
+ if (atomic_read(&q->flags) & DASD_CHANQ_ACTIVE) {
+ PRINT_WARN("Queue already active");
+ return;
+ }
+ spin_lock(&cq_lock);
+ atomic_set_mask(DASD_CHANQ_ACTIVE,&q->flags);
+ q->next_q = cq_head;
+ cq_head = q;
+ spin_unlock(&cq_lock);
+}
+
+void
+cql_deq (dasd_chanq_t * q)
+{
+ dasd_chanq_t *c;
+
+ if (cq_head == NULL) {
+ INTERNAL_ERROR ("Channel queue is empty%s\n", "");
+ return;
+ }
+ if (q == NULL) {
+ INTERNAL_ERROR ("NULL queue passed%s\n", "");
+ return;
+ }
+ spin_lock(&cq_lock);
+ if (! (atomic_read(&q->flags) & DASD_CHANQ_ACTIVE)) {
+ PRINT_WARN("Queue not active\n");
+ }
+ else if (cq_head == q) {
+ cq_head = q->next_q;
+ } else {
+ c = cq_head;
+ while (c->next_q && c->next_q != q)
+ c = c->next_q;
+ if (c->next_q != q)
+ INTERNAL_ERROR ("Entry not in queue%s\n", "");
+ else
+ c->next_q = q->next_q;
+ }
+ q->next_q = NULL;
+ atomic_clear_mask(DASD_CHANQ_ACTIVE,&q->flags);
+ spin_unlock(&cq_lock);
+}
diff --git a/drivers/s390/block/dasd_ccwstuff.h b/drivers/s390/block/dasd_ccwstuff.h
new file mode 100644
index 000000000..611777e17
--- /dev/null
+++ b/drivers/s390/block/dasd_ccwstuff.h
@@ -0,0 +1,9 @@
+extern atomic_t chanq_tasks;
+extern dasd_chanq_t *cq_head;
+
+cqr_t *request_cqr (int, int);
+int release_cqr (cqr_t *);
+int dasd_chanq_enq (dasd_chanq_t *, cqr_t *);
+int dasd_chanq_deq (dasd_chanq_t *, cqr_t *);
+void cql_enq_head (dasd_chanq_t * q);
+void cql_deq (dasd_chanq_t * q);
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
new file mode 100644
index 000000000..30e41f815
--- /dev/null
+++ b/drivers/s390/block/dasd_eckd.c
@@ -0,0 +1,973 @@
+/*
+ * File...........: linux/drivers/s390/block/dasd_eckd.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+
+#ifdef MODULE
+#include <linux/module.h>
+#endif /* MODULE */
+
+#include <linux/malloc.h>
+#include <linux/dasd.h>
+#include <asm/io.h>
+
+#include <asm/irq.h>
+
+#include "dasd_types.h"
+#include "dasd_ccwstuff.h"
+
+
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
+#endif /* PRINTK_HEADER */
+#define PRINTK_HEADER "dasd(eckd):"
+
+#define ECKD_C0(i) (i->home_bytes)
+#define ECKD_F(i) (i -> formula)
+#define ECKD_F1(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f1):(i->factors.f_0x02.f1))
+#define ECKD_F2(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f2):(i->factors.f_0x02.f2))
+#define ECKD_F3(i) (ECKD_F(i)==0x01?(i->factors.f_0x01.f3):(i->factors.f_0x02.f3))
+#define ECKD_F4(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f4):0)
+#define ECKD_F5(i) (ECKD_F(i)==0x02?(i->factors.f_0x02.f5):0)
+#define ECKD_F6(i) (i -> factor6)
+#define ECKD_F7(i) (i -> factor7)
+#define ECKD_F8(i) (i -> factor8)
+
+#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
+
+#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
+#define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
+
+#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
+#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
+
+#define DASD_ECKD_CCW_READ_COUNT 0x12
+#define DASD_ECKD_CCW_READ 0x06
+#define DASD_ECKD_CCW_READ_MT 0x86
+#define DASD_ECKD_CCW_WRITE 0x05
+#define DASD_ECKD_CCW_WRITE_MT 0x85
+#define DASD_ECKD_CCW_READ_CKD 0x1e
+#define DASD_ECKD_CCW_READ_CKD_MT 0x9e
+#define DASD_ECKD_CCW_WRITE_CKD 0x1d
+#define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
+
+typedef
+struct {
+ __u16 cyl;
+ __u16 head;
+} __attribute__ ((packed))
+
+ch_t;
+
+typedef
+struct {
+ __u16 cyl;
+ __u16 head;
+ __u32 sector;
+} __attribute__ ((packed))
+
+chs_t;
+
+typedef
+struct {
+ __u16 cyl;
+ __u16 head;
+ __u8 record;
+} __attribute__ ((packed))
+
+chr_t;
+
+typedef
+struct {
+ __u16 cyl;
+ __u16 head;
+ __u32 sector;
+} geom_t;
+
+typedef struct {
+ struct {
+ struct {
+ unsigned char identifier:2;
+ unsigned char token_id:1;
+ unsigned char sno_valid:1;
+ unsigned char subst_sno:1;
+ unsigned char recNED:1;
+ unsigned char emuNED:1;
+ unsigned char reserved:1;
+ } __attribute__ ((packed)) flags;
+ __u8 descriptor;
+ __u8 dev_class;
+ __u8 reserved;
+ unsigned char dev_type[6];
+ unsigned char dev_model[3];
+ unsigned char HDA_manufacturer[3];
+ unsigned char HDA_location[2];
+ unsigned char HDA_seqno[12];
+ __u16 ID;
+ } __attribute__ ((packed)) ned1;
+ struct {
+ struct {
+ unsigned char identifier:2;
+ unsigned char token_id:1;
+ unsigned char sno_valid:1;
+ unsigned char subst_sno:1;
+ unsigned char recNED:1;
+ unsigned char emuNED:1;
+ unsigned char reserved:1;
+ } __attribute__ ((packed)) flags;
+ __u8 descriptor;
+ __u8 reserved[2];
+ unsigned char dev_type[6];
+ unsigned char dev_model[3];
+ unsigned char DASD_manufacturer[3];
+ unsigned char DASD_location[2];
+ unsigned char DASD_seqno[12];
+ __u16 ID;
+ } __attribute__ ((packed)) ned2;
+ struct {
+ struct {
+ unsigned char identifier:2;
+ unsigned char token_id:1;
+ unsigned char sno_valid:1;
+ unsigned char subst_sno:1;
+ unsigned char recNED:1;
+ unsigned char emuNED:1;
+ unsigned char reserved:1;
+ } __attribute__ ((packed)) flags;
+ __u8 descriptor;
+ __u8 reserved[2];
+ unsigned char cont_type[6];
+ unsigned char cont_model[3];
+ unsigned char cont_manufacturer[3];
+ unsigned char cont_location[2];
+ unsigned char cont_seqno[12];
+ __u16 ID;
+ } __attribute__ ((packed)) ned3;
+ struct {
+ struct {
+ unsigned char identifier:2;
+ unsigned char token_id:1;
+ unsigned char sno_valid:1;
+ unsigned char subst_sno:1;
+ unsigned char recNED:1;
+ unsigned char emuNED:1;
+ unsigned char reserved:1;
+ } __attribute__ ((packed)) flags;
+ __u8 descriptor;
+ __u8 reserved[2];
+ unsigned char cont_type[6];
+ unsigned char empty[3];
+ unsigned char cont_manufacturer[3];
+ unsigned char cont_location[2];
+ unsigned char cont_seqno[12];
+ __u16 ID;
+ } __attribute__ ((packed)) ned4;
+ unsigned char ned5[32];
+ unsigned char ned6[32];
+ unsigned char ned7[32];
+ struct {
+ struct {
+ unsigned char identifier:2;
+ unsigned char reserved:6;
+ } __attribute__ ((packed)) flags;
+ __u8 selector;
+ __u16 interfaceID;
+ __u32 reserved;
+ __u16 subsystemID;
+ struct {
+ unsigned char sp0:1;
+ unsigned char sp1:1;
+ unsigned char reserved:5;
+ unsigned char scluster:1;
+ } __attribute__ ((packed)) spathID;
+ __u8 unit_address;
+ __u8 dev_ID;
+ __u8 dev_address;
+ __u8 adapterID;
+ __u16 link_address;
+ struct {
+ unsigned char parallel:1;
+ unsigned char escon:1;
+ unsigned char reserved:1;
+ unsigned char ficon:1;
+ unsigned char reserved2:4;
+ } __attribute__ ((packed)) protocol_type;
+ struct {
+ unsigned char PID_in_236:1;
+ unsigned char reserved:7;
+ } __attribute__ ((packed)) format_flags;
+ __u8 log_dev_address;
+ unsigned char reserved2[12];
+ } __attribute__ ((packed)) neq;
+
+} __attribute__ ((packed))
+
+eckd_confdata_t;
+
+typedef
+struct {
+ struct {
+ unsigned char perm:2; /* Permissions on this extent */
+ unsigned char reserved:1;
+ unsigned char seek:2; /* Seek control */
+ unsigned char auth:2; /* Access authorization */
+ unsigned char pci:1; /* PCI Fetch mode */
+ } __attribute__ ((packed)) mask;
+ struct {
+ unsigned char mode:2; /* Architecture mode */
+ unsigned char ckd:1; /* CKD Conversion */
+ unsigned char operation:3; /* Operation mode */
+ unsigned char cfw:1; /* Cache fast write */
+ unsigned char dfw:1; /* DASD fast write */
+ } __attribute__ ((packed)) attributes;
+ __u16 short blk_size; /* Blocksize */
+ __u16 fast_write_id;
+ __u8 unused;
+ __u8 reserved;
+ ch_t beg_ext;
+ ch_t end_ext;
+} __attribute__ ((packed, aligned (32)))
+
+DE_eckd_data_t;
+
+typedef
+struct {
+ struct {
+ unsigned char orientation:2;
+ unsigned char operation:6;
+ } __attribute__ ((packed)) operation;
+ struct {
+ unsigned char last_bytes_used:1;
+ unsigned char reserved:6;
+ unsigned char read_count_suffix:1;
+ } __attribute__ ((packed)) auxiliary;
+ __u8 unused;
+ __u8 count;
+ ch_t seek_addr;
+ chr_t search_arg;
+ __u8 sector;
+ __u16 length;
+} __attribute__ ((packed, aligned (32)))
+
+LO_eckd_data_t;
+
+/* Stuff for handling home addresses */
+typedef struct {
+ __u8 skip_control[14];
+ __u16 cell_number;
+ __u8 physical_addr[3];
+ __u8 flag;
+ ch_t track_addr;
+ __u8 reserved;
+ __u8 key_length;
+ __u8 reserved2[2];
+} __attribute__ ((packed, aligned (32)))
+
+eckd_home_t;
+
+
+static unsigned int
+round_up_multiple (unsigned int no, unsigned int mult)
+{
+ int rem = no % mult;
+ return (rem ? no - rem + mult : no);
+/* return (no % mult ? no - (no % mult) + mult : no); */
+}
+
+static unsigned int
+ceil_quot (unsigned int d1, unsigned int d2)
+{
+ return (d1 + (d2 - 1)) / d2;
+}
+
+static int
+bytes_per_record (dasd_eckd_characteristics_t * rdc,
+ int kl, /* key length */
+ int dl /* data length */ )
+{
+ int bpr = 0;
+ switch (rdc->formula) {
+ case 0x01:{
+ unsigned int fl1, fl2;
+ fl1 = round_up_multiple (ECKD_F2 (rdc) + dl,
+ ECKD_F1 (rdc));
+ fl2 = round_up_multiple (kl ? ECKD_F2 (rdc) + kl : 0,
+ ECKD_F1 (rdc));
+ bpr = fl1 + fl2;
+ break;
+ }
+ case 0x02:{
+ unsigned int fl1, fl2, int1, int2;
+ int1 = ceil_quot (dl + ECKD_F6 (rdc),
+ ECKD_F5 (rdc) << 1);
+ int2 = ceil_quot (kl + ECKD_F6 (rdc),
+ ECKD_F5 (rdc) << 1);
+ fl1 = round_up_multiple (ECKD_F1 (rdc) *
+ ECKD_F2 (rdc) +
+ (dl + ECKD_F6 (rdc) +
+ ECKD_F4 (rdc) * int1),
+ ECKD_F1 (rdc));
+ fl2 = round_up_multiple (ECKD_F1 (rdc) *
+ ECKD_F3 (rdc) +
+ (kl + ECKD_F6 (rdc) +
+ ECKD_F4 (rdc) * int2),
+ ECKD_F1 (rdc));
+ bpr = fl1 + fl2;
+ break;
+ }
+ default:
+ INTERNAL_ERROR ("unknown formula%d\n", rdc->formula);
+ }
+ return bpr;
+}
+
+static inline unsigned int
+bytes_per_track (dasd_eckd_characteristics_t * rdc)
+{
+ return *(unsigned int *) (rdc->byte_per_track) >> 8;
+}
+
+static unsigned int
+recs_per_track (dasd_eckd_characteristics_t * rdc,
+ unsigned int kl, unsigned int dl)
+{
+ int rpt = 0;
+ int dn;
+ switch ( rdc -> dev_type ) {
+ case 0x3380:
+ if (kl)
+ return 1499 / (15 +
+ 7 + ceil_quot (kl + 12, 32) +
+ ceil_quot (dl + 12, 32));
+ else
+ return 1499 / (15 + ceil_quot (dl + 12, 32));
+ case 0x3390:
+ dn = ceil_quot (dl + 6, 232) + 1;
+ if (kl) {
+ int kn = ceil_quot (kl + 6, 232) + 1;
+ return 1729 / (10 +
+ 9 + ceil_quot (kl + 6 * kn, 34) +
+ 9 + ceil_quot (dl + 6 * dn, 34));
+ } else
+ return 1729 / (10 +
+ 9 + ceil_quot (dl + 6 * dn, 34));
+ case 0x9345:
+ dn = ceil_quot (dl + 6, 232) + 1;
+ if (kl) {
+ int kn = ceil_quot (kl + 6, 232) + 1;
+ return 1420 / (18 +
+ 7 + ceil_quot (kl + 6 * kn, 34) +
+ ceil_quot (dl + 6 * dn, 34));
+ } else
+ return 1420 / (18 +
+ 7 + ceil_quot (dl + 6 * dn, 34));
+ }
+ return rpt;
+}
+
+static
+void
+define_extent (ccw1_t * de_ccw,
+ DE_eckd_data_t * data,
+ int trk,
+ int totrk,
+ int cmd,
+ dasd_information_t * info)
+{
+ ch_t geo, beg, end;
+
+ geo.cyl = info->rdc_data->eckd.no_cyl;
+ geo.head = info->rdc_data->eckd.trk_per_cyl;
+ beg.cyl = trk / geo.head;
+ beg.head = trk % geo.head;
+ end.cyl = totrk / geo.head;
+ end.head = totrk % geo.head;
+
+ memset (de_ccw, 0, sizeof (ccw1_t));
+ de_ccw->cmd_code = CCW_DEFINE_EXTENT;
+ de_ccw->count = 16;
+ de_ccw->cda = (void *) virt_to_phys (data);
+
+ memset (data, 0, sizeof (DE_eckd_data_t));
+ switch (cmd) {
+ case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+ case DASD_ECKD_CCW_READ_RECORD_ZERO:
+ case DASD_ECKD_CCW_READ:
+ case DASD_ECKD_CCW_READ_MT:
+ case DASD_ECKD_CCW_READ_CKD: /* Fallthrough */
+ case DASD_ECKD_CCW_READ_CKD_MT:
+ case DASD_ECKD_CCW_READ_COUNT:
+ data->mask.perm = 0x1;
+ data->attributes.operation = 0x3; /* enable seq. caching */
+ break;
+ case DASD_ECKD_CCW_WRITE:
+ case DASD_ECKD_CCW_WRITE_MT:
+ data->attributes.operation = 0x3; /* enable seq. caching */
+ break;
+ case DASD_ECKD_CCW_WRITE_CKD:
+ case DASD_ECKD_CCW_WRITE_CKD_MT:
+ data->attributes.operation = 0x1; /* format through cache */
+ break;
+ case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+ case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+ data->mask.perm = 0x3;
+ data->mask.auth = 0x1;
+ data->attributes.operation = 0x1; /* format through cache */
+ break;
+ default:
+ INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd);
+ break;
+ }
+ data->attributes.mode = 0x3;
+ data->beg_ext.cyl = beg.cyl;
+ data->beg_ext.head = beg.head;
+ data->end_ext.cyl = end.cyl;
+ data->end_ext.head = end.head;
+}
+
+static inline void
+locate_record (ccw1_t * lo_ccw,
+ LO_eckd_data_t * data,
+ int trk,
+ int rec_on_trk,
+ int no_rec,
+ int cmd,
+ dasd_information_t * info)
+{
+ ch_t geo =
+ {info->rdc_data->eckd.no_cyl,
+ info->rdc_data->eckd.trk_per_cyl};
+ ch_t seek =
+ {trk / (geo.head), trk % (geo.head)};
+ int reclen = info->sizes.bp_block;
+ memset (lo_ccw, 0, sizeof (ccw1_t));
+ lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
+ lo_ccw->count = 16;
+ lo_ccw->cda = (void *) virt_to_phys (data);
+
+ memset (data, 0, sizeof (LO_eckd_data_t));
+ switch (cmd) {
+ case DASD_ECKD_CCW_WRITE_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_READ_HOME_ADDRESS:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_WRITE_RECORD_ZERO:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x03;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_READ_RECORD_ZERO:
+ data->operation.orientation = 0x3;
+ data->operation.operation = 0x16;
+ data->count++;
+ break;
+ case DASD_ECKD_CCW_WRITE:
+ case DASD_ECKD_CCW_WRITE_MT:
+ data->auxiliary.last_bytes_used = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x01;
+ break;
+ case DASD_ECKD_CCW_WRITE_CKD:
+ case DASD_ECKD_CCW_WRITE_CKD_MT:
+ data->auxiliary.last_bytes_used = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x03;
+ break;
+ case DASD_ECKD_CCW_READ:
+ case DASD_ECKD_CCW_READ_MT:
+ data->auxiliary.last_bytes_used = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x06;
+ break;
+ case DASD_ECKD_CCW_READ_CKD:
+ case DASD_ECKD_CCW_READ_CKD_MT:
+ data->auxiliary.last_bytes_used = 0x1;
+ data->length = reclen;
+ data->operation.operation = 0x16;
+ break;
+ case DASD_ECKD_CCW_READ_COUNT:
+ data->operation.operation = 0x06;
+ break;
+ default:
+ INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd);
+ }
+ memcpy (&(data->seek_addr), &seek, sizeof (ch_t));
+ memcpy (&(data->search_arg), &seek, sizeof (ch_t));
+ data->search_arg.record = rec_on_trk;
+ data->count += no_rec;
+}
+
+void
+dasd_eckd_print_error (devstat_t * stat)
+{
+ int sct, sl;
+ char *sense = stat->ii.sense.data;
+ PRINT_WARN ("IRQ on devno %x: with intparm:%x DS:0x%02x CS:0x%02x\n",
+ stat->devno, stat->intparm, stat->dstat, stat->cstat);
+ PRINT_WARN ("Failing CCW: %p\n", (ccw1_t *) stat->cpa);
+ for (sl = 0; sl < 4; sl++) {
+ PRINT_DEBUG ("Sense:");
+ for (sct = 0; sct < 8; sct++) {
+ printk (" %2d:0x%02x",
+ 8 * sl + sct, sense[8 * sl + sct]);
+ }
+ printk ("\n");
+ }
+ if (sense[27] & 0x80) { /* 32 Byte Sense Data */
+ PRINT_INFO ("Sense Data is 32 Byte information\n");
+ PRINT_INFO ("Format: %x Exception class %x\n",
+ sense[6] & 0x0f, sense[22] >> 4);
+ } else { /* 24 Byte Sense Data */
+ PRINT_INFO ("Sense Data is 24 Byte information\n");
+ PRINT_INFO ("FMT: %x MSG %x, %s MSGb to SYSOP\n",
+ sense[7] >> 4, sense[7] & 0x0f,
+ sense[1] & 0x10 ? "" : "no");
+ }
+}
+
+int
+dasd_eckd_format_track (int di, int trk, int bs)
+{
+ int rc = 0;
+ int i;
+ int flags = 0x00; /* FORMAT_R0 = 0x01, FORMAT_HA = 0x03 */
+ dasd_information_t * info=dasd_info[di];
+ cqr_t *fcp;
+ DE_eckd_data_t *DE_data;
+ LO_eckd_data_t *LO_data;
+ eckd_count_t *ct_data;
+ eckd_count_t *r0_data;
+ ccw1_t *last_ccw;
+ int retries = 5;
+
+ int rpt = recs_per_track (&(info->rdc_data->eckd), 0, bs);
+ int cyl = trk / info->rdc_data->eckd.trk_per_cyl;
+ int head = trk % info->rdc_data->eckd.trk_per_cyl;
+
+ fcp = request_cqr (2 + 1 + rpt,
+ sizeof (DE_eckd_data_t) +
+ sizeof (LO_eckd_data_t) +
+ (rpt + 1) * sizeof (eckd_count_t));
+ fcp -> devindex=di;
+ DE_data = (DE_eckd_data_t *) fcp->data;
+ LO_data = (LO_eckd_data_t *) (((long) DE_data) +
+ sizeof (DE_eckd_data_t));
+ r0_data = (eckd_count_t *) (((long) LO_data) +
+ sizeof (LO_eckd_data_t));
+ ct_data = (eckd_count_t *) (((long) r0_data) +
+ sizeof (eckd_count_t));
+ last_ccw = fcp->cpaddr;
+ switch (flags) {
+ case 0x03:
+ define_extent (last_ccw, DE_data, trk, trk,
+ DASD_ECKD_CCW_WRITE_HOME_ADDRESS, info);
+ last_ccw->flags = CCW_FLAG_CC;
+ last_ccw++;
+ locate_record (last_ccw, LO_data, trk, 0, rpt,
+ DASD_ECKD_CCW_WRITE_HOME_ADDRESS, info);
+ last_ccw->flags = CCW_FLAG_CC;
+ last_ccw++;
+ break;
+ case 0x01:
+ define_extent (last_ccw, DE_data, trk, trk,
+ DASD_ECKD_CCW_WRITE_RECORD_ZERO, info);
+ last_ccw->flags = CCW_FLAG_CC;
+ last_ccw++;
+ locate_record (last_ccw, LO_data, trk, 0, rpt,
+ DASD_ECKD_CCW_WRITE_RECORD_ZERO, info);
+ last_ccw->flags = CCW_FLAG_CC;
+ last_ccw++;
+ break;
+ case 0x00:
+ define_extent (last_ccw, DE_data, trk, trk,
+ DASD_ECKD_CCW_WRITE_CKD, info);
+ last_ccw->flags = CCW_FLAG_CC;
+ last_ccw++;
+ locate_record (last_ccw, LO_data, trk, 0, rpt,
+ DASD_ECKD_CCW_WRITE_CKD, info);
+ LO_data->length = bs;
+ last_ccw->flags = CCW_FLAG_CC;
+ last_ccw++;
+ break;
+ default:
+ PRINT_WARN ("Unknown format flags...%d\n", flags);
+ return -EINVAL;
+ }
+ if (flags & 0x02) {
+ PRINT_WARN ("Unsupported format flag...%d\n", flags);
+ return -EINVAL;
+ }
+ if (flags & 0x01) { /* write record zero */
+ memset (r0_data, 0, sizeof (eckd_count_t));
+ r0_data->cyl = cyl;
+ r0_data->head = head;
+ r0_data->record = 0;
+ r0_data->kl = 0;
+ r0_data->dl = 8;
+ last_ccw->cmd_code = 0x03;
+ last_ccw->count = 8;
+ last_ccw->flags = CCW_FLAG_CC | CCW_FLAG_SLI;
+ last_ccw->cda = (void *) virt_to_phys (r0_data);
+ last_ccw++;
+ }
+ /* write remaining records */
+ for (i = 0; i < rpt; i++, last_ccw++) {
+ memset (ct_data + i, 0, sizeof (eckd_count_t));
+ (ct_data + i)->cyl = cyl;
+ (ct_data + i)->head = head;
+ (ct_data + i)->record = i + 1;
+ (ct_data + i)->kl = 0;
+ (ct_data + i)->dl = bs;
+ last_ccw->cmd_code = DASD_ECKD_CCW_WRITE_CKD;
+ last_ccw->flags = CCW_FLAG_CC | CCW_FLAG_SLI;
+ last_ccw->count = 8;
+ last_ccw->cda = (void *)
+ virt_to_phys (ct_data + i);
+ }
+ (last_ccw - 1)->flags &= ~(CCW_FLAG_CC | CCW_FLAG_DC);
+ fcp -> devindex = di;
+ fcp -> flags = DASD_DO_IO_SLEEP;
+ do {
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+ int irq;
+ int cs;
+
+ irq = dasd_info[fcp->devindex]->info.irq;
+ s390irq_spin_lock_irqsave (irq, flags);
+ atomic_set(&fcp->status,CQR_STATUS_QUEUED);
+ rc = dasd_start_IO ( fcp );
+ add_wait_queue (&dasd_waitq, &wait);
+ do {
+ current->state = TASK_UNINTERRUPTIBLE;
+ s390irq_spin_unlock_irqrestore (irq, flags);
+ schedule ();
+ s390irq_spin_lock_irqsave (irq, flags);
+ } while (((cs = atomic_read (&fcp->status)) !=
+ CQR_STATUS_DONE) &&
+ (cs != CQR_STATUS_ERROR));
+ remove_wait_queue (&dasd_waitq, &wait);
+ s390irq_spin_unlock_irqrestore (irq, flags);
+
+ retries --;
+ } while ( (rc || (atomic_read(&fcp->status) != CQR_STATUS_DONE)) &&
+ retries);
+ if ((rc || (atomic_read(&fcp->status) != CQR_STATUS_DONE)))
+ rc = -EIO;
+ release_cqr (fcp);
+ return rc;
+}
+
+int
+dasd_eckd_ck_devinfo (dev_info_t * info)
+{
+ return 0;
+}
+
+cqr_t *
+dasd_eckd_build_req (int devindex,
+ struct request * req)
+{
+ cqr_t *rw_cp = NULL;
+ ccw1_t *ccw;
+
+ DE_eckd_data_t *DE_data;
+ LO_eckd_data_t *LO_data;
+ struct buffer_head *bh;
+ int rw_cmd;
+ dasd_information_t *info = dasd_info[devindex];
+ int blk_per_trk = recs_per_track (&(info->rdc_data->eckd),
+ 0, info->sizes.bp_block);
+ int byt_per_blk = info->sizes.bp_block;
+ int noblk = req-> nr_sectors >> info->sizes.s2b_shift;
+ int btrk = (req->sector >> info->sizes.s2b_shift) / blk_per_trk;
+ int etrk = ((req->sector + req->nr_sectors - 1) >>
+ info->sizes.s2b_shift) / blk_per_trk;
+
+ if ( ! noblk ) {
+ PRINT_ERR("No blocks to write...returning\n");
+ return NULL;
+ }
+
+ if (req->cmd == READ) {
+ rw_cmd = DASD_ECKD_CCW_READ_MT;
+ } else
+#if DASD_PARANOIA > 2
+ if (req->cmd == WRITE)
+#endif /* DASD_PARANOIA */
+ {
+ rw_cmd = DASD_ECKD_CCW_WRITE_MT;
+ }
+#if DASD_PARANOIA > 2
+ else {
+ PRINT_ERR ("Unknown command %d\n", req->cmd);
+ return NULL;
+ }
+#endif /* DASD_PARANOIA */
+ /* Build the request */
+ rw_cp = request_cqr (2 + noblk,
+ sizeof (DE_eckd_data_t) +
+ sizeof (LO_eckd_data_t));
+ if ( ! rw_cp ) {
+ return NULL;
+ }
+ DE_data = rw_cp->data;
+ LO_data = rw_cp->data + sizeof (DE_eckd_data_t);
+ ccw = rw_cp->cpaddr;
+
+ define_extent (ccw, DE_data, btrk, etrk, rw_cmd, info);
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ locate_record (ccw, LO_data, btrk,
+ (req->sector >> info->sizes.s2b_shift) %
+ blk_per_trk + 1,
+ req->nr_sectors >> info->sizes.s2b_shift,
+ rw_cmd, info);
+ ccw->flags = CCW_FLAG_CC;
+ for (bh = req->bh; bh; bh = bh->b_reqnext) {
+ long size;
+ for (size = 0; size < bh->b_size; size += byt_per_blk) {
+ ccw++;
+ ccw->flags = CCW_FLAG_CC;
+ ccw->cmd_code = rw_cmd;
+ ccw->count = byt_per_blk;
+ ccw->cda = (void *) virt_to_phys (bh->b_data + size);
+ }
+ }
+ ccw->flags &= ~(CCW_FLAG_DC | CCW_FLAG_CC);
+ return rw_cp;
+}
+
+cqr_t *
+dasd_eckd_rw_label (int devindex, int rw, char *buffer)
+{
+ int cmd_code = 0x03;
+ dasd_information_t *info = dasd_info[devindex];
+ cqr_t *cqr;
+ ccw1_t *ccw;
+
+ switch (rw) {
+ case READ:
+ cmd_code = DASD_ECKD_CCW_READ;
+ break;
+ case WRITE:
+ cmd_code = DASD_ECKD_CCW_WRITE;
+ break;
+#if DASD_PARANOIA > 2
+ default:
+ INTERNAL_ERROR ("unknown cmd %d", rw);
+ return NULL;
+#endif /* DASD_PARANOIA */
+ }
+ cqr = request_cqr (3, sizeof (DE_eckd_data_t) +
+ sizeof (LO_eckd_data_t));
+ ccw = cqr->cpaddr;
+ define_extent (ccw, cqr->data, 0, 0, cmd_code, info);
+ ccw->flags |= CCW_FLAG_CC;
+ ccw++;
+ locate_record (ccw, cqr->data + 1, 0, 2, 1, cmd_code, info);
+ ccw->flags |= CCW_FLAG_CC;
+ ccw++;
+ ccw->cmd_code = cmd_code;
+ ccw->flags |= CCW_FLAG_SLI;
+ ccw->count = sizeof (dasd_volume_label_t);
+ ccw->cda = (void *) virt_to_phys ((void *) buffer);
+ return cqr;
+
+}
+
+void
+dasd_eckd_print_char (dasd_characteristics_t * i)
+{
+ dasd_eckd_characteristics_t * c =
+ (dasd_eckd_characteristics_t *)i;
+ PRINT_INFO ("%x/%x (%x/%x) Cyl: %d Head: %d Sec: %d \n",
+ c->dev_type, c->dev_model,
+ c->cu_type, c->cu_model.model,
+ c->no_cyl, c->trk_per_cyl,
+ c->sec_per_trk);
+ PRINT_INFO ("Estimate: %d Byte/trk %d byte/kByte %d kByte/trk \n",
+ bytes_per_track (c),
+ bytes_per_record (c, 0, 1024),
+ recs_per_track (c, 0, 1024));
+};
+
+int
+dasd_eckd_ck_char (dasd_characteristics_t * i)
+{
+ int rc = 0;
+ dasd_eckd_print_char (i);
+ return rc;
+}
+
+int
+dasd_eckd_format (int devindex, format_data_t * fdata)
+{
+ int rc = 0;
+ int i;
+ dasd_information_t *info = dasd_info[devindex];
+ format_data_t fd;
+
+ if (!fdata) {
+ fd.start_unit = 0;
+ fd.stop_unit = info->rdc_data->eckd.no_cyl *
+ info->rdc_data->eckd.trk_per_cyl - 1;
+ fd.blksize = 4096;
+ } else {
+ memcpy (&fd, fdata, sizeof (format_data_t));
+ if ( fd.stop_unit == -1 ) {
+ fd.stop_unit = info->rdc_data->eckd.no_cyl *
+ info->rdc_data->eckd.trk_per_cyl - 1;
+ }
+ if ( fd.blksize == 0 ) {
+ fd.blksize = 4096;
+ }
+ }
+ PRINT_INFO("Formatting device %d from %d to %d with bs %d\n",
+ devindex,fd.start_unit,fd.stop_unit,fd.blksize);
+ if ( fd.start_unit > fd.stop_unit ) {
+ PRINT_WARN ("start unit .gt. stop unit\n");
+ return -EINVAL;
+ }
+ if ( (fd.start_unit > info->rdc_data->eckd.no_cyl *
+ info->rdc_data->eckd.trk_per_cyl - 1) ) {
+ PRINT_WARN ("start unit beyond end of disk\n");
+ return -EINVAL;
+ }
+ if ( (fd.stop_unit > info->rdc_data->eckd.no_cyl *
+ info->rdc_data->eckd.trk_per_cyl - 1) ) {
+ PRINT_WARN ("stop unit beyond end of disk\n");
+ return -EINVAL;
+ }
+ switch (fd.blksize) {
+ case 512:
+ case 1024:
+ case 2048:
+ case 4096:
+ break;
+ default:
+ PRINT_WARN ("invalid blocksize\n");
+ return -EINVAL;
+ }
+ for (i = fd.start_unit; i <= fd.stop_unit; i++) {
+ /* print 20 messages per disk at all */
+ if ( ! ( i % (info->rdc_data->eckd.trk_per_cyl *
+ (info->rdc_data->eckd.no_cyl / 20 ) ))) {
+ PRINT_INFO ("Format %d Cylinder: %d\n",devindex,
+ i/info->rdc_data->eckd.trk_per_cyl);
+ }
+ rc = dasd_eckd_format_track (devindex, i, fd.blksize);
+ if (rc) {
+ PRINT_WARN ("Formatting of Track %d failed...exiting\n", i);
+ break;
+ }
+ }
+ PRINT_INFO("Formated device %d from %d to %d with bs %d\n",
+ devindex,fd.start_unit,fd.stop_unit,fd.blksize);
+ return rc;
+}
+
+cqr_t *
+dasd_eckd_fill_sizes_first (int di)
+{
+ cqr_t *rw_cp = NULL;
+ ccw1_t *ccw;
+ DE_eckd_data_t *DE_data;
+ LO_eckd_data_t *LO_data;
+ dasd_information_t *info = dasd_info[di];
+ eckd_count_t *count_data= &(info->private.eckd.count_data);
+ rw_cp = request_cqr (3,
+ sizeof (DE_eckd_data_t) +
+ sizeof (LO_eckd_data_t));
+ DE_data = rw_cp->data;
+ LO_data = rw_cp->data + sizeof (DE_eckd_data_t);
+ ccw = rw_cp->cpaddr;
+ define_extent (ccw, DE_data, 0, 0, DASD_ECKD_CCW_READ_COUNT, info);
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ locate_record (ccw, LO_data, 0, 1, 1, DASD_ECKD_CCW_READ_COUNT, info);
+ ccw->flags = CCW_FLAG_CC;
+ ccw++;
+ ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
+ ccw->count = 8;
+ ccw->cda = (void *) __pa (count_data);
+ rw_cp->devindex = di;
+ atomic_set(&rw_cp->status,CQR_STATUS_FILLED);
+ return rw_cp;
+}
+
+int dasd_eckd_fill_sizes_last (int devindex)
+{
+ int sb;
+ dasd_information_t *in = dasd_info[devindex];
+ int bs = in->private.eckd.count_data.dl;
+ if (bs <= 0) {
+ PRINT_INFO("Cannot figure out blocksize. did you format the disk?\n");
+ memset (&(in -> sizes), 0, sizeof(dasd_sizes_t ));
+ return -EMEDIUMTYPE;
+ } else {
+ in->sizes.bp_block = bs;
+ }
+ in->sizes.bp_sector = in->sizes.bp_block;
+
+ in->sizes.b2k_shift = 0; /* bits to shift a block to get 1k */
+ for (sb = 1024; sb < bs; sb = sb << 1)
+ in->sizes.b2k_shift++;
+
+ in->sizes.s2b_shift = 0; /* bits to shift 512 to get a block */
+ for (sb = 512; sb < bs; sb = sb << 1)
+ in->sizes.s2b_shift++;
+
+ in->sizes.blocks = in->rdc_data->eckd.no_cyl *
+ in->rdc_data->eckd.trk_per_cyl *
+ recs_per_track (&(in->rdc_data->eckd), 0, bs);
+ in->sizes.kbytes = in->sizes.blocks << in->sizes.b2k_shift;
+
+ PRINT_INFO ("Verified: %d B/trk %d B/Blk(%d B) %d Blks/trk %d kB/trk \n",
+ bytes_per_track (&(in->rdc_data->eckd)),
+ bytes_per_record (&(in->rdc_data->eckd), 0, in->sizes.bp_block),
+ in->sizes.bp_block,
+ recs_per_track (&(in->rdc_data->eckd), 0, in->sizes.bp_block),
+ (recs_per_track (&(in->rdc_data->eckd), 0, in->sizes.bp_block) <<
+ in->sizes.b2k_shift ));
+ return 0;
+}
+
+dasd_operations_t dasd_eckd_operations =
+{
+ ck_devinfo: dasd_eckd_ck_devinfo,
+ get_req_ccw: dasd_eckd_build_req,
+ rw_label: dasd_eckd_rw_label,
+ ck_characteristics: dasd_eckd_ck_char,
+ fill_sizes_first: dasd_eckd_fill_sizes_first,
+ fill_sizes_last: dasd_eckd_fill_sizes_last,
+ dasd_format: dasd_eckd_format,
+};
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff --git a/drivers/s390/block/dasd_erp.c b/drivers/s390/block/dasd_erp.c
new file mode 100644
index 000000000..9028b797f
--- /dev/null
+++ b/drivers/s390/block/dasd_erp.c
@@ -0,0 +1,21 @@
+/*
+ * File...........: linux/drivers/s390/block/dasd_erp.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ */
+
+#include <asm/irq.h>
+#include <linux/dasd.h>
+#include "dasd_erp.h"
+#include "dasd_types.h"
+
+dasd_era_t
+dasd_erp_examine ( cqr_t * cqr)
+{
+ devstat_t *stat = cqr->dstat ;
+ if ( stat->cstat == 0x00 &&
+ stat->dstat == (DEV_STAT_CHN_END|DEV_STAT_DEV_END ) )
+ return dasd_era_none;
+ return dasd_era_fatal;
+}
diff --git a/drivers/s390/block/dasd_erp.h b/drivers/s390/block/dasd_erp.h
new file mode 100644
index 000000000..ab92bd122
--- /dev/null
+++ b/drivers/s390/block/dasd_erp.h
@@ -0,0 +1,15 @@
+/*
+ * File...........: linux/drivers/s390/block/dasd_erp.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ */
+
+#include "dasd_types.h"
+
+typedef enum {
+ dasd_era_fatal = -1,
+ dasd_era_none = 0
+} dasd_era_t;
+
+dasd_era_t dasd_erp_examine ( cqr_t * );
diff --git a/drivers/s390/block/dasd_mdsk.c b/drivers/s390/block/dasd_mdsk.c
new file mode 100644
index 000000000..63de4a6b4
--- /dev/null
+++ b/drivers/s390/block/dasd_mdsk.c
@@ -0,0 +1,14 @@
+#include <linux/dasd.h>
+#include "dasd_types.h"
+#include "dasd_erp.h"
+
+dasd_operations_t dasd_mdsk_operations =
+{
+ NULL,
+ /* dasd_mdsk_ck_devinfo,
+ dasd_mdsk_build_req,
+ dasd_mdsk_rw_label,
+ dasd_mdsk_ck_char,
+ dasd_mdsk_fill_sizes,
+ dasd_mdsk_format, */
+};
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
new file mode 100644
index 000000000..e757c435f
--- /dev/null
+++ b/drivers/s390/block/dasd_proc.c
@@ -0,0 +1,116 @@
+/*
+ Structure of the proc filesystem:
+ /proc/dasd/
+ /proc/dasd/devices # List of devices
+ /proc/dasd/ddabcd # Device node for devno abcd
+ /proc/dasd/ddabcd1 # Device node for partition abcd
+ /proc/dasd/abcd # Device information for devno abcd
+*/
+
+#include <linux/proc_fs.h>
+
+#include <linux/dasd.h>
+
+#include "dasd_types.h"
+
+int dasd_proc_read_devices ( char *, char **, off_t, int);
+#ifdef DASD_PROFILE
+extern int dasd_proc_read_statistics ( char *, char **, off_t, int);
+extern int dasd_proc_read_debug ( char *, char **, off_t, int);
+#endif /* DASD_PROFILE */
+
+struct proc_dir_entry dasd_proc_root_entry = {
+ 0,
+ 4,"dasd",
+ S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
+ 1,0,0,
+ 0,
+ NULL,
+};
+
+struct proc_dir_entry dasd_proc_devices_entry = {
+ 0,
+ 7,"devices",
+ S_IFREG | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
+ 1,0,0,
+ 0,
+ NULL,
+ &dasd_proc_read_devices,
+};
+
+#ifdef DASD_PROFILE
+struct proc_dir_entry dasd_proc_stats_entry = {
+ 0,
+ 10,"statistics",
+ S_IFREG | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
+ 1,0,0,
+ 0,
+ NULL,
+ &dasd_proc_read_statistics,
+};
+
+struct proc_dir_entry dasd_proc_debug_entry = {
+ 0,
+ 5,"debug",
+ S_IFREG | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
+ 1,0,0,
+ 0,
+ NULL,
+ &dasd_proc_read_debug,
+};
+#endif /* DASD_PROFILE */
+
+struct proc_dir_entry dasd_proc_device_template = {
+ 0,
+ 6,"dd????",
+ S_IFBLK | S_IRUGO | S_IWUSR | S_IWGRP,
+ 1,0,0,
+ 0,
+ NULL,
+};
+
+void
+dasd_proc_init ( void )
+{
+ proc_register( & proc_root, & dasd_proc_root_entry);
+ proc_register( & dasd_proc_root_entry, & dasd_proc_devices_entry);
+#ifdef DASD_PROFILE
+ proc_register( & dasd_proc_root_entry, & dasd_proc_stats_entry);
+ proc_register( & dasd_proc_root_entry, & dasd_proc_debug_entry);
+#endif /* DASD_PROFILE */
+}
+
+
+int
+dasd_proc_read_devices ( char * buf, char **start, off_t off, int len)
+{
+ int i;
+ len = sprintf ( buf, "dev# MAJ minor node Format\n");
+ for ( i = 0; i < DASD_MAX_DEVICES; i++ ) {
+ dasd_information_t *info = dasd_info[i];
+ if ( ! info )
+ continue;
+ if ( len >= PAGE_SIZE - 80 )
+ len += sprintf ( buf + len, "terminated...\n");
+ len += sprintf ( buf + len,
+ "%04X %3d %5d /dev/dasd%c",
+ dasd_info[i]->info.devno,
+ DASD_MAJOR,
+ i << PARTN_BITS,
+ 'a' + i );
+ if (info->flags == DASD_INFO_FLAGS_NOT_FORMATTED) {
+ len += sprintf ( buf + len, " n/a");
+ } else {
+ len += sprintf ( buf + len, " %6d",
+ info->sizes.bp_block);
+ }
+ len += sprintf ( buf + len, "\n");
+ }
+ return len;
+}
+
+
+void
+dasd_proc_add_node (int di)
+{
+}
diff --git a/drivers/s390/block/dasd_profile.c b/drivers/s390/block/dasd_profile.c
new file mode 100644
index 000000000..7484f2be2
--- /dev/null
+++ b/drivers/s390/block/dasd_profile.c
@@ -0,0 +1,208 @@
+#include <linux/mm.h>
+
+#include <linux/dasd.h>
+
+#include "dasd_types.h"
+
+#define PRINTK_HEADER "dasd_profile:"
+
+static long dasd_io_reqs=0; /* number of requests processed at all */
+static long dasd_io_secs[16]; /* histogram of request's sizes */
+static long dasd_io_times[16]; /* histogram of requests's times */
+static long dasd_io_timps[16]; /* histogram of requests's times per sector */
+static long dasd_io_time1[16]; /* histogram of time from build to start */
+static long dasd_io_time2[16]; /* histogram of time from start to irq */
+static long dasd_io_time2ps[16]; /* histogram of time from start to irq */
+static long dasd_io_time3[16]; /* histogram of time from irq to end */
+
+void
+dasd_profile_add ( cqr_t *cqr )
+{
+ int ind;
+ long strtime,irqtime,endtime,tottime;
+ long tottimeps,sectors;
+ long help;
+ if ( ! cqr -> req )
+ return;
+ sectors = cqr -> req -> nr_sectors;
+ strtime = ((cqr->startclk - cqr->buildclk) >> 12);
+ irqtime = ((cqr->stopclk - cqr->startclk) >> 12);
+ endtime = ((cqr->endclk - cqr->stopclk) >> 12);
+ tottime = ((cqr->endclk - cqr->buildclk) >> 12);
+ tottimeps = tottime / sectors;
+
+ if (! dasd_io_reqs ++){
+ for ( ind = 0; ind < 16; ind ++) {
+ dasd_io_secs[ind] = 0;
+ dasd_io_times[ind]=0;
+ dasd_io_timps[ind]=0;
+ dasd_io_time1[ind]=0;
+ dasd_io_time2[ind]=0;
+ dasd_io_time2ps[ind]=0;
+ dasd_io_time3[ind]=0;
+ }
+ };
+
+ for ( ind = 0, help = sectors >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_secs[ind] ++;
+
+ for ( ind = 0, help = tottime >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_times[ind] ++;
+
+ for ( ind = 0, help = tottimeps >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_timps[ind] ++;
+
+ for ( ind = 0, help = strtime >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_time1[ind] ++;
+
+ for ( ind = 0, help = irqtime >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_time2[ind] ++;
+
+ for ( ind = 0, help = (irqtime/sectors) >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_time2ps[ind] ++;
+
+ for ( ind = 0, help = endtime >> 3;
+ ind < 15 && help;
+ help = help >> 1,ind ++);
+ dasd_io_time3[ind] ++;
+}
+
+int
+dasd_proc_read_statistics ( char * buf, char **start,
+ off_t off, int len, int d)
+{
+ int i;
+ int shift, help;
+
+ for ( shift = 0, help = dasd_io_reqs;
+ help > 8192;
+ help = help >> 1,shift ++);
+ len = sprintf ( buf, "%ld dasd I/O requests\n", dasd_io_reqs);
+ len += sprintf ( buf+len, "__<4 ___8 __16 __32 __64 _128 _256 _512 __1k __2k __4k __8k _16k _32k _64k >64k\n");
+ len += sprintf ( buf+len, "Histogram of sizes (512B secs)\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_secs[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ len += sprintf ( buf+len, "Histogram of I/O times\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_times[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ len += sprintf ( buf+len, "Histogram of I/O times per sector\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_timps[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ len += sprintf ( buf+len, "Histogram of I/O time till ssch\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_time1[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ len += sprintf ( buf+len, "Histogram of I/O time between ssch and irq\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_time2[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ len += sprintf ( buf+len, "Histogram of I/O time between ssch and irq per sector\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_time2ps[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ len += sprintf ( buf+len, "Histogram of I/O time between irq and end\n");
+ for ( i = 0; i < 16; i ++) {
+ len += sprintf ( buf+len, "%4ld ",dasd_io_time3[i] >> shift );
+ }
+ len += sprintf ( buf+len, "\n");
+ return len;
+}
+typedef
+struct {
+ union {
+ unsigned long long clock;
+ struct {
+ unsigned int ts1;
+ unsigned int ts2 : 20;
+ unsigned int unused : 8;
+ unsigned int cpu : 4;
+ } __attribute__ ((packed)) s;
+ } __attribute__ ((packed)) u;
+ unsigned long caller_address;
+ unsigned long tag;
+} __attribute__ ((packed)) dasd_debug_entry;
+
+static dasd_debug_entry *dasd_debug_area = NULL;
+static dasd_debug_entry *dasd_debug_actual;
+static spinlock_t debug_lock = SPIN_LOCK_UNLOCKED;
+
+void
+dasd_debug ( unsigned long tag )
+{
+ long flags;
+ dasd_debug_entry *d;
+ /* initialize in first call ... */
+ if ( ! dasd_debug_area ) {
+ dasd_debug_actual = dasd_debug_area =
+ (dasd_debug_entry *) get_free_page (GFP_ATOMIC);
+ if ( ! dasd_debug_area ) {
+ PRINT_WARN("No debug area allocated\n");
+ return;
+ }
+ memset (dasd_debug_area,0,PAGE_SIZE);
+ }
+ /* renormalize to page */
+ spin_lock_irqsave(&debug_lock,flags);
+ dasd_debug_actual = (dasd_debug_entry *)
+ ( (unsigned long) dasd_debug_area +
+ ( ( (unsigned long)dasd_debug_actual -
+ (unsigned long)dasd_debug_area ) % PAGE_SIZE ) );
+ d = dasd_debug_actual ++;
+ spin_unlock_irqrestore(&debug_lock,flags);
+ /* write CPUID to lowest 12 bits of clock... */
+ __asm__ __volatile__ ( "STCK %0"
+ :"=m" (d->u.clock));
+ d->tag = tag;
+ d -> caller_address = (unsigned long) __builtin_return_address(0);
+ d->u.s.cpu = smp_processor_id();
+}
+
+int
+dasd_proc_read_debug ( char * buf, char **start,
+ off_t off, int len, int dd)
+{
+ dasd_debug_entry *d;
+ char tag[9] = { 0, };
+ long flags;
+ spin_lock_irqsave(&debug_lock,flags);
+ len = 0;
+ for( d = dasd_debug_area;
+ len < 4068 ;
+ d ++ ) {
+ if ( *(char*)(&d->tag) == 'D' ) {
+ memcpy(tag,&(d->tag),4);
+ tag[4]=0;
+ }
+ else {
+ sprintf(tag,"%08lx", d->tag);
+ tag[8]=0;
+ }
+ len += sprintf ( buf+len,
+ "%x %08x%05x %08lx (%8s)\n",
+ d->u.s.cpu, d->u.s.ts1, d->u.s.ts2,
+ d->caller_address,tag);
+ }
+ spin_unlock_irqrestore(&debug_lock,flags);
+ return len;
+}
diff --git a/drivers/s390/block/dasd_types.h b/drivers/s390/block/dasd_types.h
new file mode 100644
index 000000000..b453bc2f8
--- /dev/null
+++ b/drivers/s390/block/dasd_types.h
@@ -0,0 +1,284 @@
+/*
+ * File...........: linux/drivers/s390/block/dasd_types.h
+ * Author.........: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Created........: 08/31/1999
+ * Last Modified..: 09/29/1999
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+
+ * List of Changes:
+ - Initial Release as of 09/29/1999
+
+ * Description
+
+ * Restrictions
+
+ * Known Bugs
+
+ * Todo-List
+
+ */
+
+#ifndef DASD_TYPES_H
+#define DASD_TYPES_H
+
+#include <linux/config.h>
+#include <linux/dasd.h>
+#include <linux/blkdev.h>
+
+#include <asm/irq.h>
+
+#define CCW_DEFINE_EXTENT 0x63
+#define CCW_LOCATE_RECORD 0x43
+#define CCW_READ_DEVICE_CHARACTERISTICS 0x64
+
+typedef
+enum {
+ dasd_none = -1,
+#ifdef CONFIG_DASD_ECKD
+ dasd_eckd,
+#endif /* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_MDSK
+ dasd_mdsk,
+#endif /* CONFIG_DASD_MDSK */
+#ifdef CONFIG_DASD_CKD
+ dasd_ckd,
+#endif /* CONFIG_DASD_CKD */
+ dasd_end
+} dasd_type_t;
+
+typedef
+struct {
+ __u16 cu_type;
+ struct {
+ unsigned char support:2;
+ unsigned char async:1;
+ unsigned char reserved:1;
+ unsigned char cache_info:1;
+ unsigned char model:3;
+ } __attribute__ ((packed)) cu_model;
+ __u16 dev_type;
+ __u8 dev_model;
+ struct {
+ unsigned char mult_burst:1;
+ unsigned char RT_in_LR:1;
+ unsigned char reserved1:1;
+ unsigned char RD_IN_LR:1;
+ unsigned char reserved2:4;
+ unsigned char reserved3:8;
+ unsigned char defect_wr:1;
+ unsigned char reserved4:2;
+ unsigned char striping:1;
+ unsigned char reserved5:4;
+ unsigned char cfw:1;
+ unsigned char reserved6:2;
+ unsigned char cache:1;
+ unsigned char dual_copy:1;
+ unsigned char dfw:1;
+ unsigned char reset_alleg:1;
+ unsigned char sense_down:1;
+ } __attribute__ ((packed)) facilities;
+ __u8 dev_class;
+ __u8 unit_type;
+ __u16 no_cyl;
+ __u16 trk_per_cyl;
+ __u8 sec_per_trk;
+ __u8 byte_per_track[3];
+ __u16 home_bytes;
+ __u8 formula;
+ union {
+ struct {
+ __u8 f1;
+ __u16 f2;
+ __u16 f3;
+ } __attribute__ ((packed)) f_0x01;
+ struct {
+ __u8 f1;
+ __u8 f2;
+ __u8 f3;
+ __u8 f4;
+ __u8 f5;
+ } __attribute__ ((packed)) f_0x02;
+ } __attribute__ ((packed)) factors;
+ __u16 first_alt_trk;
+ __u16 no_alt_trk;
+ __u16 first_dia_trk;
+ __u16 no_dia_trk;
+ __u16 first_sup_trk;
+ __u16 no_sup_trk;
+ __u8 MDR_ID;
+ __u8 OBR_ID;
+ __u8 director;
+ __u8 rd_trk_set;
+ __u16 max_rec_zero;
+ __u8 reserved1;
+ __u8 RWANY_in_LR;
+ __u8 factor6;
+ __u8 factor7;
+ __u8 factor8;
+ __u8 reserved2[3];
+ __u8 reserved3[10];
+} __attribute__ ((packed, aligned (32)))
+
+dasd_eckd_characteristics_t;
+
+/* eckd count area */
+typedef struct {
+ __u16 cyl;
+ __u16 head;
+ __u8 record;
+ __u8 kl;
+ __u16 dl;
+} __attribute__ ((packed))
+
+eckd_count_t;
+
+#ifdef CONFIG_DASD_CKD
+struct dasd_ckd_characteristics {
+ char info[64];
+};
+
+#endif /* CONFIG_DASD_CKD */
+
+#ifdef CONFIG_DASD_ECKD
+struct dasd_eckd_characteristics {
+ char info[64];
+};
+
+#endif /* CONFIG_DASD_ECKD */
+
+typedef
+union {
+ char __attribute__ ((aligned (32))) bytes[64];
+#ifdef CONFIG_DASD_CKD
+ struct dasd_ckd_characteristics ckd;
+#endif /* CONFIG_DASD_CKD */
+#ifdef CONFIG_DASD_ECKD
+ dasd_eckd_characteristics_t eckd;
+#endif /* CONFIG_DASD_ECKD */
+} __attribute__ ((aligned (32)))
+
+dasd_characteristics_t;
+
+#define CQR_STATUS_EMPTY 0x00
+#define CQR_STATUS_FILLED 0x01
+#define CQR_STATUS_QUEUED 0x02
+#define CQR_STATUS_IN_IO 0x04
+#define CQR_STATUS_DONE 0x08
+#define CQR_STATUS_RETRY 0x10
+#define CQR_STATUS_ERROR 0x20
+#define CQR_STATUS_FAILED 0x40
+#define CQR_STATUS_SLEEP 0x80
+
+#define CQR_FLAGS_SLEEP 0x01
+#define CQR_FLAGS_WAIT 0x02
+#define CQR_FLAGS_NOLOCK 0x04
+#define CQR_FLAGS_NORETRY 0x08
+
+typedef
+struct cqr_t {
+ unsigned int magic; /* magic number should be "DASD" */
+ atomic_t status; /* current status of request */
+ unsigned short retries; /* counter for retry in error case */
+ unsigned short cplength;/* Length of channel program (CP) */
+ unsigned short devindex;/* device number */
+ unsigned short flags; /* Flags for execution */
+
+ void * data; /* additional data area for CP */
+ ccw1_t *cpaddr; /* Address of CP */
+ struct request *req; /* backpointer to struct request */
+ struct cqr_t *next; /* forward chain in chanq */
+ struct cqr_t *int4cqr; /* which cqr ist the nect PCI for? */
+ unsigned long long buildclk;
+ unsigned long long startclk;
+ unsigned long long stopclk;
+ unsigned long long endclk;
+ devstat_t *dstat; /* savearea for devstat */
+ spinlock_t lock;
+ int options;
+} __attribute__ ((packed))
+cqr_t;
+
+typedef
+struct {
+ unsigned long int kbytes;
+ unsigned int bp_sector;
+ unsigned int bp_block;
+ unsigned int blocks;
+ unsigned int s2b_shift;
+ unsigned int b2k_shift;
+ unsigned int label_block;
+} dasd_sizes_t;
+
+#define DASD_CHANQ_ACTIVE 0x01
+#define DASD_CHANQ_BUSY 0x02
+#define DASD_REQUEST_Q_BROKEN 0x04
+
+typedef
+struct dasd_chanq_t {
+ volatile cqr_t *head;
+ volatile cqr_t *tail;
+ spinlock_t q_lock; /* lock for queue operations */
+ spinlock_t f_lock; /* lock for flag operations */
+ int queued_requests;
+ atomic_t flags;
+ atomic_t dirty_requests;
+ struct dasd_chanq_t *next_q; /* pointer to next queue */
+} __attribute__ ((packed, aligned (16)))
+dasd_chanq_t;
+
+#define DASD_INFO_FLAGS_INITIALIZED 0x01
+#define DASD_INFO_FLAGS_NOT_FORMATTED 0x02
+#define DASD_INFO_FLAGS_PARTNS_DETECTED 0x04
+
+typedef
+struct dasd_information_t {
+ devstat_t dev_status;
+ dasd_characteristics_t *rdc_data;
+ dasd_volume_label_t *label;
+ dasd_type_t type;
+ dev_info_t info;
+ dasd_sizes_t sizes;
+ dasd_chanq_t queue;
+ int open_count;
+ spinlock_t lock;
+ struct semaphore sem;
+ unsigned long flags;
+ int irq;
+ struct proc_dir_entry *proc_device;
+ devfs_handle_t devfs_entry;
+ union {
+ struct {
+ eckd_count_t count_data;
+ } eckd;
+ struct {
+ char dummy;
+ } fba;
+ struct {
+ char dummy;
+ } mdsk;
+ struct {
+ char dummy;
+ } ckd;
+ } private;
+} dasd_information_t;
+
+typedef struct {
+ int start_unit;
+ int stop_unit;
+ int blksize;
+} format_data_t;
+
+typedef
+struct {
+ int (*ck_devinfo) (dev_info_t *);
+ cqr_t *(*get_req_ccw) (int, struct request *);
+ cqr_t *(*rw_label) (int, int, char *);
+ int (*ck_characteristics) (dasd_characteristics_t *);
+ cqr_t *(*fill_sizes_first) (int);
+ int (*fill_sizes_last) (int);
+ int (*dasd_format) (int, format_data_t *);
+} dasd_operations_t;
+
+extern dasd_information_t *dasd_info[];
+
+#endif /* DASD_TYPES_H */
diff --git a/drivers/s390/block/mdisk.c b/drivers/s390/block/mdisk.c
new file mode 100644
index 000000000..f485cb668
--- /dev/null
+++ b/drivers/s390/block/mdisk.c
@@ -0,0 +1,790 @@
+/*
+ * drivers/s390/block/mdisk.c
+ * VM minidisk device driver.
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Hartmut Penner (hp@de.ibm.com)
+ */
+
+
+#ifndef __KERNEL__
+# define __KERNEL__
+#endif
+
+#define __NO_VERSION__
+#include <linux/config.h>
+#include <linux/version.h>
+
+char kernel_version [] = UTS_RELEASE;
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/malloc.h> /* kmalloc() */
+#include <linux/vmalloc.h> /* vmalloc() */
+#include <linux/fs.h> /* everything... */
+#include <linux/errno.h> /* error codes */
+#include <linux/timer.h>
+#include <linux/types.h> /* size_t */
+#include <linux/fcntl.h> /* O_ACCMODE */
+#include <linux/hdreg.h> /* HDIO_GETGEO */
+#include <linux/init.h> /* initfunc */
+#include <linux/interrupt.h>
+#include <linux/ctype.h>
+
+#include <asm/system.h> /* cli(), *_flags */
+#include <asm/uaccess.h> /* access_ok */
+#include <asm/io.h> /* virt_to_phys */
+
+ /* Added statement HSM 12/03/99 */
+#include <asm/irq.h>
+
+#define MAJOR_NR MDISK_MAJOR /* force definitions on in blk.h */
+
+#include <linux/blk.h>
+
+
+#include "mdisk.h" /* local definitions */
+
+/*
+ * structure for all device specific information
+ */
+
+typedef struct mdisk_Dev {
+ u32 vdev; /* vdev of mindisk */
+ u32 size; /* size in blocks */
+ u32 status; /* status of last io operation */
+ u32 nr_bhs; /* number of buffer of last io operation */
+ u32 blksize; /* blksize from minidisk */
+ u32 blkmult; /* multiplier between blksize and 512 HARDSECT */
+ u32 blkshift; /* loe2 of multiplier above */
+ /*
+ * each device has own iob and bio,
+ * it's possible to run io in parallel
+ * not used yet due to only one CURRENT per MAJOR
+ */
+
+ mdisk_rw_io_t* iob; /* each device has it own iob and bio */
+ mdisk_bio_t* bio;
+ /* Added statement HSM 12/03/99 */
+ devstat_t dev_status; /* Here we hold the I/O status */
+
+ int usage; /* usage counter */
+
+ struct tq_struct tqueue; /* per device task queue */
+} mdisk_Dev;
+
+
+/*
+ * appended to global structures in mdisk_init;
+ */
+
+static int mdisk_blksizes[MDISK_DEVS];
+static int mdisk_sizes[MDISK_DEVS] = { 0 };
+static int mdisk_hardsects[MDISK_DEVS];
+static int mdisk_maxsectors[MDISK_DEVS];
+
+/*
+ * structure hold device specific information
+ */
+
+static mdisk_Dev mdisk_devices[MDISK_DEVS];
+static mdisk_rw_io_t mdisk_iob[MDISK_DEVS] __attribute__ ((aligned(8)));
+static mdisk_bio_t mdisk_bio[MDISK_DEVS][256]__attribute__ ((aligned(8)));
+
+
+/*
+ * Parameter parsing
+ */
+struct {
+ long vdev[MDISK_DEVS];
+ long size[MDISK_DEVS];
+ long offset[MDISK_DEVS];
+ long blksize[MDISK_DEVS];
+} mdisk_setup_data;
+
+/*
+ * Parameter parsing function, called from init/main.c
+ * vdev : virtual device number
+ * size : size in kbyte
+ * offset : offset after which minidisk is available
+ * blksize : blocksize minidisk is formated
+ * Format is: mdisk=<vdev>:<size>:<offset>:<blksize>,<vdev>:<size>:<offset>...
+ * <vdev>:<size>:<offset>:<blksize> can be shortened to <vdev>:<size> with offset=0,blksize=512
+ */
+int __init mdisk_setup(char *str)
+{
+ char *cur = str;
+ int vdev, size, offset=0,blksize;
+ static int i = 0;
+ if (!i)
+ memset(&mdisk_setup_data,0,sizeof(mdisk_setup_data));
+
+ while (*cur != 0) {
+ blksize=MDISK_HARDSECT;
+ vdev = size = offset = 0;
+ if (!isxdigit(*cur)) goto syntax_error;
+ vdev = simple_strtoul(cur,&cur,16);
+ if (*cur != 0 && *cur != ',') {
+ if (*cur++ != ':') goto syntax_error;
+ if (!isxdigit(*cur)) goto syntax_error;
+ size = simple_strtoul(cur,&cur,16);
+ if (*cur == ':') { /* another colon -> offset specified */
+ cur++;
+ if (!isxdigit(*cur)) goto syntax_error;
+ offset = simple_strtoul(cur,&cur,16);
+ if (*cur == ':') { /* another colon -> blksize */
+ cur++;
+ if (!isxdigit(*cur)) goto syntax_error;
+ blksize = simple_strtoul(cur,&cur,16);
+ }
+ }
+ if (*cur != ',' && *cur != 0) goto syntax_error;
+ }
+ if (*cur == ',') cur++;
+ if (i >= MDISK_DEVS) {
+ printk(KERN_WARNING "mnd: too many devices\n");
+ return 1;
+ }
+ mdisk_setup_data.vdev[i] = vdev;
+ mdisk_setup_data.size[i] = size;
+ mdisk_setup_data.offset[i] = offset;
+ mdisk_setup_data.blksize[i] = blksize;
+
+ i++;
+ }
+
+ return 1;
+
+syntax_error:
+ printk(KERN_WARNING "mnd: syntax error in parameter string: %s\n", str);
+ return 0;
+}
+
+__setup("mdisk=", mdisk_setup);
+
+/*
+ * Open and close
+ */
+
+static int mdisk_open (struct inode *inode, struct file *filp)
+{
+ mdisk_Dev *dev; /* device information */
+ int num = MINOR(inode->i_rdev);
+
+ /*
+ * size 0 means device not installed
+ */
+ if ((num >= MDISK_DEVS) || (mdisk_sizes[num] == 0))
+ return -ENODEV;
+ MOD_INC_USE_COUNT;
+ dev = &mdisk_devices[num];
+ dev->usage++;
+ return 0; /* success */
+}
+
+static int mdisk_release (struct inode *inode, struct file *filp)
+{
+ mdisk_Dev *dev = &mdisk_devices[MINOR(inode->i_rdev)];
+
+ /*
+ * flush device
+ */
+
+ fsync_dev(inode->i_rdev);
+ dev->usage--;
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+
+/*
+ * The mdisk() implementation
+ */
+
+static int mdisk_ioctl (struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ int err,rc, size=0;
+ struct hd_geometry *geo = (struct hd_geometry *)arg;
+ mdisk_Dev *dev = mdisk_devices + MINOR(inode->i_rdev);
+
+ switch(cmd) {
+
+ case BLKGETSIZE:
+ rc = copy_to_user ((long *) arg, &dev->size, sizeof (long));
+ printk(KERN_WARNING "mnd: ioctl BLKGETSIZE %d\n",dev->size);
+ return rc;
+ case BLKFLSBUF: /* flush */
+ if (!suser()) return -EACCES; /* only root */
+ fsync_dev(inode->i_rdev);
+ invalidate_buffers(inode->i_rdev);
+ return 0;
+
+ case BLKRAGET: /* return the readahead value */
+ if (!arg) return -EINVAL;
+ err = access_ok(VERIFY_WRITE, (long *) arg, sizeof(long));
+ if (err) return err;
+ put_user(read_ahead[MAJOR(inode->i_rdev)],(long *) arg);
+ return 0;
+
+ case BLKRASET: /* set the readahead value */
+ if (!suser()) return -EACCES;
+ if (arg > 0xff) return -EINVAL; /* limit it */
+ read_ahead[MAJOR(inode->i_rdev)] = arg;
+ return 0;
+
+ case BLKRRPART: /* re-read partition table: can't do it */
+ return -EINVAL;
+
+ case HDIO_GETGEO:
+ /*
+ * get geometry of device -> linear
+ */
+ size = dev->size;
+ if (geo==NULL) return -EINVAL;
+ err = access_ok(VERIFY_WRITE, geo, sizeof(*geo));
+ if (err) return err;
+ put_user(1, &geo->cylinders);
+ put_user(1, &geo->heads);
+ put_user(size, &geo->sectors);
+ put_user(0, &geo->start);
+ return 0;
+ }
+
+ return -EINVAL; /* unknown command */
+}
+
+/*
+ * The file operations
+ */
+
+static struct block_device_operations mdisk_fops = {
+ ioctl: mdisk_ioctl,
+ open: mdisk_open,
+ release: mdisk_release,
+};
+
+/*
+ * The 'low level' IO function
+ */
+
+
+static __inline__ int
+dia250(void* iob,int cmd)
+{
+ int rc;
+
+ iob = (void*) virt_to_phys(iob);
+
+ asm volatile (" lr 2,%1\n"
+ " lr 3,%2\n"
+ " .long 0x83230250\n"
+ " lr %0,3"
+ : "=d" (rc)
+ : "d" (iob) , "d" (cmd)
+ : "2", "3" );
+ return rc;
+}
+/*
+ * Init of minidisk device
+ */
+
+static __inline__ int
+mdisk_init_io(mdisk_Dev *dev,int blocksize,int offset,int size)
+{
+ mdisk_init_io_t *iob = (mdisk_init_io_t*) dev->iob;
+ int rc;
+
+ memset(iob,0,sizeof(mdisk_init_io_t));
+
+ iob->dev_nr = dev->vdev;
+ iob->block_size = blocksize;
+ iob->offset = offset;
+ iob->start_block= 0;
+ iob->end_block = size;
+
+ rc = dia250(iob,INIT_BIO);
+
+ /*
+ * clear for following io once
+ */
+
+ memset(iob,0,sizeof(mdisk_rw_io_t));
+
+ return rc;
+}
+
+/*
+ * release of minidisk device
+ */
+
+static __inline__ int
+mdisk_term_io(mdisk_Dev *dev)
+{
+ mdisk_init_io_t *iob = (mdisk_init_io_t*) dev->iob;
+
+ memset(iob,0,sizeof(mdisk_init_io_t));
+
+ iob->dev_nr = dev->vdev;
+
+ return dia250(iob,TERM_BIO);
+}
+
+/*
+ * setup and start of minidisk io request
+ */
+
+static __inline__ int
+mdisk_rw_io_clustered (mdisk_Dev *dev,
+ mdisk_bio_t* bio_array,
+ int length,
+ int req,
+ int sync)
+{
+ int rc;
+ mdisk_rw_io_t *iob = dev->iob;
+
+ iob->dev_nr = dev->vdev;
+ iob->key = 0;
+ iob->flags = sync;
+
+ iob->block_count = length;
+ iob->interrupt_params = req;
+ iob->bio_list = virt_to_phys(bio_array);
+
+ rc = dia250(iob,RW_BIO);
+ return rc;
+}
+
+
+
+/*
+ * The device characteristics function
+ */
+
+static __inline__ int
+dia210(void* devchar)
+{
+ int rc;
+
+ devchar = (void*) virt_to_phys(devchar);
+
+ asm volatile (" lr 2,%1\n"
+ " .long 0x83200210\n"
+ " ipm %0\n"
+ " srl %0,28"
+ : "=d" (rc)
+ : "d" (devchar)
+ : "2" );
+ return rc;
+}
+/*
+ * read the label of a minidisk and extract its characteristics
+ */
+
+static __inline__ int
+mdisk_read_label (mdisk_Dev *dev, int i)
+{
+ static mdisk_dev_char_t devchar;
+ static long label[1024];
+ int block, b;
+ int rc;
+ mdisk_bio_t *bio;
+
+ devchar.dev_nr = dev -> vdev;
+ devchar.rdc_len = sizeof(mdisk_dev_char_t);
+
+ if (dia210(&devchar) == 0) {
+ if (devchar.vdev_class == DEV_CLASS_FBA) {
+ block = 2;
+ }
+ else {
+ block = 3;
+ }
+ bio = dev->bio;
+ for (b=512;b<4097;b=b*2) {
+ rc = mdisk_init_io(dev, b, 0, 64);
+ if (rc > 4) {
+ continue;
+ }
+ memset(&bio[0], 0, sizeof(mdisk_bio_t));
+ bio[0].type = MDISK_READ_REQ;
+ bio[0].block_number = block;
+ bio[0].buffer = virt_to_phys(&label);
+ dev->nr_bhs = 1;
+ if (mdisk_rw_io_clustered(dev,
+ &bio[0],
+ 1,
+ (unsigned long) dev,
+ MDISK_SYNC)
+ == 0 ) {
+ if (label[0] != 0xc3d4e2f1) { /* CMS1 */
+ printk ( KERN_WARNING "mnd: %4lX "
+ "is not CMS format\n",
+ mdisk_setup_data.vdev[i]);
+ rc = mdisk_term_io(dev);
+ return 1;
+ }
+ if (label[13] == 0) {
+ printk ( KERN_WARNING "mnd: %4lX "
+ "is not reserved\n",
+ mdisk_setup_data.vdev[i]);
+ rc = mdisk_term_io(dev);
+ return 2;
+ }
+ mdisk_setup_data.size[i] =
+ (label[7] - 1 - label[13]) *
+ (label[3] >> 9) >> 1;
+ mdisk_setup_data.blksize[i] = label[3];
+ mdisk_setup_data.offset[i] = label[13] + 1;
+ rc = mdisk_term_io(dev);
+ return rc;
+ }
+ rc = mdisk_term_io(dev);
+ }
+ printk ( KERN_WARNING "mnd: Cannot read label of %4lX "
+ "- is it formatted?\n",
+ mdisk_setup_data.vdev[i]);
+ return 3;
+ }
+ return 4;
+}
+
+
+
+
+
+/*
+ * this handles a clustered request in success case
+ * all buffers are detach and marked uptodate to the kernel
+ * then CURRENT->bh is set to the last processed but not
+ * update buffer
+ */
+
+static __inline__ void
+mdisk_end_request(int nr_bhs)
+{
+ int i;
+ struct buffer_head *bh;
+ struct request *req;
+
+ if (nr_bhs > 1) {
+ req = CURRENT;
+ bh = req->bh;
+
+ for (i=0; i < nr_bhs-1; i++) {
+ req->bh = bh->b_reqnext;
+ bh->b_reqnext = NULL;
+ bh->b_end_io(bh,1);
+ bh = req->bh;
+ }
+
+ /*
+ * set CURRENT to last processed, not marked buffer
+ */
+ req->buffer = bh->b_data;
+ req->current_nr_sectors = bh->b_size >> 9;
+ CURRENT = req;
+ }
+ end_request(1);
+}
+
+
+
+/*
+ * Block-driver specific functions
+ */
+
+void mdisk_request(request_queue_t *queue)
+{
+ mdisk_Dev *dev;
+ mdisk_bio_t *bio;
+ struct buffer_head *bh;
+ unsigned int sector, nr, offset;
+ int rc,rw,i;
+
+ i = 0;
+ while(CURRENT) {
+ INIT_REQUEST;
+
+ /* Check if the minor number is in range */
+ if (DEVICE_NR(CURRENT_DEV) > MDISK_DEVS) {
+ static int count = 0;
+ if (count++ < 5) /* print the message at most five times */
+ printk(KERN_WARNING "mnd: request for minor %d out of range\n",
+ DEVICE_NR(CURRENT_DEV) ) ;
+ end_request(0);
+ continue;
+ }
+
+ /*
+ * Pointer to device structure, from the static array
+ */
+ dev = mdisk_devices + DEVICE_NR(CURRENT_DEV);
+
+ /*
+ * check, if operation is past end of devices
+ */
+ if (CURRENT->nr_sectors + CURRENT->sector > dev->size) {
+ static int count = 0;
+ if (count++ < 5)
+ printk(KERN_WARNING "mnd%c: request past end of device\n",
+ DEVICE_NR(CURRENT_DEV));
+ end_request(0);
+ continue;
+ }
+
+ /*
+ * do command (read or write)
+ */
+ switch(CURRENT->cmd) {
+ case READ:
+ rw = MDISK_READ_REQ;
+ break;
+ case WRITE:
+ rw = MDISK_WRITE_REQ;
+ break;
+ default:
+ /* can't happen */
+ end_request(0);
+ continue;
+ }
+
+ /*
+ * put the clustered requests in mdisk_bio array
+ * nr_sectors is checked against max_sectors in make_request
+ * nr_sectors and sector are always blocks of 512
+ * but bh_size depends on the filesystems size
+ */
+ sector = CURRENT->sector>>dev->blkshift;
+ bh = CURRENT->bh;
+ bio = dev->bio;
+ dev->nr_bhs = 0;
+
+ /*
+ * sector is translated to block in minidisk context
+ *
+ */
+ offset = 0;
+
+
+
+ for (nr = 0,i = 0;
+ nr < CURRENT->nr_sectors && bh;
+ nr+=dev->blkmult, sector++,i++) {
+ memset(&bio[i], 0, sizeof(mdisk_bio_t));
+ bio[i].type = rw;
+ bio[i].block_number = sector;
+ bio[i].buffer = virt_to_phys(bh->b_data+offset);
+ offset += dev->blksize;
+ if (bh->b_size <= offset) {
+ offset = 0;
+ bh = bh->b_reqnext;
+ dev->nr_bhs++;
+ }
+ }
+
+ if (( rc = mdisk_rw_io_clustered(dev, &bio[0], i,
+ (unsigned long) dev,
+#ifdef CONFIG_MDISK_SYNC
+ MDISK_SYNC
+#else
+ MDISK_ASYNC
+#endif
+ )) > 8 ) {
+ printk(KERN_WARNING "mnd%c: %s request failed rc %d"
+ " sector %ld nr_sectors %ld \n",
+ DEVICE_NR(CURRENT_DEV),
+ rw == MDISK_READ_REQ ? "read" : "write",
+ rc, CURRENT->sector, CURRENT->nr_sectors);
+ end_request(0);
+ continue;
+ }
+ i = 0;
+ /*
+ * Synchron: looping to end of request (INIT_REQUEST has return)
+ * Asynchron: end_request done in bottom half
+ */
+#ifdef CONFIG_MDISK_SYNC
+ mdisk_end_request(dev->nr_bhs);
+#else
+ if (rc == 0)
+ mdisk_end_request(dev->nr_bhs);
+ else
+ return;
+#endif
+ }
+}
+
+
+/*
+ * mdisk interrupt handler called when read/write request finished
+ * queues and marks a bottom half.
+ *
+ */
+void do_mdisk_interrupt(void)
+{
+ u16 code;
+ mdisk_Dev *dev;
+
+ code = S390_lowcore.cpu_addr;
+
+ if ((code >> 8) != 0x03) {
+ printk("mnd: wrong sub-interruption code %d",code>>8);
+ return;
+ }
+
+ /*
+ * pointer to devives structure given as external interruption
+ * parameter
+ */
+ dev = (mdisk_Dev*) S390_lowcore.ext_params;
+ dev->status = code & 0x00ff;
+
+ queue_task(&dev->tqueue, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
+
+/*
+ * the bottom half checks the status of request
+ * on success it calls end_request and calls mdisk_request
+ * if more transfer to do
+ */
+
+static void
+do_mdisk_bh(void *data)
+{
+ mdisk_Dev *dev = (mdisk_Dev*) data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ /*
+ * check for status of asynchronous rw
+ */
+ if (dev->status != 0x00) {
+ printk("mnd: status of async rw %d",dev->status);
+ end_request(0);
+ } else {
+ /*
+ * end request for clustered requests
+ */
+ if (CURRENT)
+ mdisk_end_request(dev->nr_bhs);
+ }
+
+ /*
+ * if more to do, call mdisk_request
+ */
+ if (CURRENT)
+ mdisk_request(NULL);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+void /* Added fuction HSM 12/03/99 */
+mdisk_handler (int cpu, void *ds, struct pt_regs *regs)
+{
+ printk (KERN_ERR "mnd: received I/O interrupt... shouldn't happen\n");
+}
+
+int __init mdisk_init(void)
+{
+ int rc,i;
+ mdisk_Dev *dev;
+ request_queue_t *q;
+
+ /*
+ * register block device
+ */
+ if (register_blkdev(MAJOR_NR,"mnd",&mdisk_fops) < 0) {
+ printk("mnd: unable to get major %d for mini disk\n"
+ ,MAJOR_NR);
+ return MAJOR_NR;
+ }
+ q = BLK_DEFAULT_QUEUE(MAJOR_NR);
+ blk_init_queue(q, mdisk_request);
+ blk_queue_headactive(BLK_DEFAULT_QUEUE(major), 0);
+
+ /*
+ * setup sizes for available devices
+ */
+ read_ahead[MAJOR_NR] = MDISK_RAHEAD; /* 8 sector (4kB) read-ahead */
+ blk_size[MAJOR_NR] = mdisk_sizes; /* size of reserved mdisk */
+ blksize_size[MAJOR_NR] = mdisk_blksizes; /* blksize of device */
+ hardsect_size[MAJOR_NR] = mdisk_hardsects;
+ max_sectors[MAJOR_NR] = mdisk_maxsectors;
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
+
+ for (i=0;i<MDISK_DEVS;i++) {
+ if (mdisk_setup_data.vdev[i] == 0) {
+ continue;
+ }
+ /* Added block HSM 12/03/99 */
+ if ( request_irq(get_irq_by_devno(mdisk_setup_data.vdev[i]),
+ mdisk_handler, 0, "mnd",
+ &(mdisk_devices[i].dev_status)) ){
+ printk ( KERN_WARNING "mnd: Cannot acquire I/O irq of"
+ " %4lX for paranoia reasons, skipping\n",
+ mdisk_setup_data.vdev[i]);
+ continue;
+ }
+ /*
+ * open VM minidisk low level device
+ */
+ dev = &mdisk_devices[i];
+ dev->bio=mdisk_bio[i];
+ dev->iob=&mdisk_iob[i];
+ dev->vdev = mdisk_setup_data.vdev[i];
+
+ if ( mdisk_setup_data.size[i] == 0 )
+ rc = mdisk_read_label(dev, i);
+ dev->size = mdisk_setup_data.size[i] * 2; /* buffer 512 b */
+ dev->blksize = mdisk_setup_data.blksize[i];
+ dev->tqueue.routine = do_mdisk_bh;
+ dev->tqueue.data = dev;
+ dev->blkmult = dev->blksize/512;
+ dev->blkshift =
+ dev->blkmult==1?0:
+ dev->blkmult==2?1:
+ dev->blkmult==4?2:
+ dev->blkmult==8?3:-1;
+
+ mdisk_sizes[i] = mdisk_setup_data.size[i];
+ mdisk_blksizes[i] = mdisk_setup_data.blksize[i];
+ mdisk_hardsects[i] = mdisk_setup_data.blksize[i];
+
+ /*
+ * max sectors for one clustered req
+ */
+ mdisk_maxsectors[i] = MDISK_MAXSECTORS*dev->blkmult;
+
+ rc = mdisk_init_io(dev,
+ mdisk_setup_data.blksize[i],
+ mdisk_setup_data.offset[i],/* offset in vdev*/
+ dev->size>>dev->blkshift /* size in blocks */
+ );
+ if (rc > 4) {
+ printk("mnd%c: init failed (rc: %d)\n",'a'+i,rc);
+ mdisk_sizes[i] = 0;
+ continue;
+ }
+
+ /*
+ * set vdev in device structure for further rw access
+ * vdev and size given by linload
+ */
+ printk("mnd%c: register device at major %X with %d blocks %d blksize \n",
+ 'a' + i, MAJOR_NR, dev->size>>dev->blkshift,dev->blkmult*512);
+ }
+
+ /*
+ * enable service-signal external interruptions,
+ * Control Register 0 bit 22 := 1
+ * (besides PSW bit 7 must be set to 1 somewhere for external
+ * interruptions)
+ */
+ ctl_set_bit(0, 9);
+
+ return 0;
+}
diff --git a/drivers/s390/block/mdisk.h b/drivers/s390/block/mdisk.h
new file mode 100644
index 000000000..084293031
--- /dev/null
+++ b/drivers/s390/block/mdisk.h
@@ -0,0 +1,94 @@
+/*
+ * drivers/s390/block/mdisk.h
+ * VM minidisk device driver.
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Hartmut Penner (hp@de.ibm.com)
+ */
+
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+#define MDISK_DEVS 8 /* for disks */
+#define MDISK_RAHEAD 8 /* read ahead */
+#define MDISK_BLKSIZE 1024 /* 1k blocks */
+#define MDISK_HARDSECT 512 /* FIXME -- 512 byte blocks */
+#define MDISK_MAXSECTORS 256 /* max sectors for one request */
+
+
+
+/*
+ * low level io defines for diagnose 250
+ */
+
+#define MDISK_WRITE_REQ 0x01
+#define MDISK_READ_REQ 0x02
+
+#define MDISK_SYNC 0x00
+#define MDISK_ASYNC 0x02
+#define INIT_BIO 0x00
+#define RW_BIO 0x01
+#define TERM_BIO 0x02
+
+/*
+ * This stucture is used for clustered request
+ * up to 256 different request can be handled with one invocation
+ */
+
+typedef struct {
+ u8 type;
+ u8 status;
+ u16 spare1;
+ u32 block_number;
+ u32 alet;
+ u32 buffer;
+} mdisk_bio_t;
+
+typedef struct {
+ u16 dev_nr;
+ u16 spare1[11];
+ u32 block_size;
+ u32 offset;
+ u32 start_block;
+ u32 end_block;
+ u32 spare2[6];
+} mdisk_init_io_t;
+
+typedef struct {
+ u16 dev_nr;
+ u16 spare1[11];
+ u8 key;
+ u8 flags;
+ u16 spare2;
+ u32 block_count;
+ u32 alet;
+ u32 bio_list;
+ u32 interrupt_params;
+ u32 spare3[5];
+} mdisk_rw_io_t;
+
+/*
+ * low level definitions for Diagnose 210
+ */
+
+#define DEV_CLASS_FBA 0x01
+
+/*
+ * Data structures for Diagnose 210
+ */
+
+typedef struct {
+ u16 dev_nr;
+ u16 rdc_len;
+ u8 vdev_class;
+ u8 vdev_type;
+ u8 vdev_status;
+ u8 vdev_flags;
+ u8 rdev_class;
+ u8 rdev_type;
+ u8 rdev_model;
+ u8 rdev_features;
+} mdisk_dev_char_t;
+
+
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
new file mode 100644
index 000000000..1cc89d053
--- /dev/null
+++ b/drivers/s390/char/Makefile
@@ -0,0 +1,16 @@
+all: s390-char.o
+
+CFLAFS +=
+O_TARGET := s390-char.o
+O_OBJS :=
+M_OBJS :=
+
+ifeq ($(CONFIG_3215_CONSOLE),y)
+ O_OBJS += con3215.o
+endif
+
+ifeq ($(CONFIG_HWC),y)
+ O_OBJS += hwc_con.o hwc_rw.o hwc_tty.o
+endif
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
new file mode 100644
index 000000000..96e35aece
--- /dev/null
+++ b/drivers/s390/char/con3215.c
@@ -0,0 +1,1129 @@
+/*
+ * drivers/s390/char/con3215.c
+ * 3215 line mode terminal driver.
+ *
+ * S390 version
+ * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/interrupt.h>
+
+#include <linux/malloc.h>
+#include <linux/bootmem.h>
+#include <asm/io.h>
+#include <asm/ebcdic.h>
+#include <asm/uaccess.h>
+
+#include "../../../arch/s390/kernel/cpcmd.h"
+#include <asm/irq.h>
+
+#define NR_3215 1
+#define NR_3215_REQ (4*NR_3215)
+#define RAW3215_BUFFER_SIZE 65536 /* output buffer size */
+#define RAW3215_INBUF_SIZE 256 /* input buffer size */
+#define RAW3215_MIN_SPACE 128 /* minimum free space for wakeup */
+#define RAW3215_MIN_WRITE 1024 /* min. length for immediate output */
+#define RAW3215_MAX_CCWLEN 3968 /* max. bytes to write with one ccw */
+#define RAW3215_NR_CCWS ((RAW3215_BUFFER_SIZE/RAW3215_MAX_CCWLEN)+2)
+#define RAW3215_TIMEOUT HZ/10 /* time for delayed output */
+
+#define RAW3215_FIXED 1 /* 3215 console device is not be freed */
+#define RAW3215_ACTIVE 2 /* set if the device is in use */
+#define RAW3215_WORKING 4 /* set if a request is being worked on */
+#define RAW3215_THROTTLED 8 /* set if reading is disabled */
+#define RAW3215_STOPPED 16 /* set if writing is disabled */
+#define RAW3215_CLOSING 32 /* set while in close process */
+#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */
+#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */
+#define RAW3215_BH_PENDING 256 /* indication for bh scheduling */
+
+struct _raw3215_info; /* forward declaration ... */
+
+int raw3215_condevice = -1; /* preset console device */
+
+/*
+ * Request types for a 3215 device
+ */
+typedef enum {
+ RAW3215_FREE, RAW3215_READ, RAW3215_WRITE
+} raw3215_type;
+
+/*
+ * Request structure for a 3215 device
+ */
+typedef struct _raw3215_req {
+ raw3215_type type; /* type of the request */
+ int start, end; /* start/end index into output buffer */
+ int residual; /* residual count for read request */
+ ccw1_t ccws[RAW3215_NR_CCWS]; /* space for the channel program */
+ struct _raw3215_info *info; /* pointer to main structure */
+ struct _raw3215_req *next; /* pointer to next request */
+} raw3215_req __attribute__ ((aligned(8)));
+
+typedef struct _raw3215_info {
+ int flags; /* state flags */
+ int irq; /* interrupt number to do_IO */
+ char *buffer; /* pointer to output buffer */
+ char *inbuf; /* pointer to input buffer */
+ int head; /* first free byte in output buffer */
+ int count; /* number of bytes in output buffer */
+ devstat_t devstat; /* device status structure for do_IO */
+ struct tty_struct *tty; /* pointer to tty structure if present */
+ struct tq_struct tqueue; /* task queue to bottom half */
+ raw3215_req *queued_read; /* pointer to queued read requests */
+ raw3215_req *queued_write; /* pointer to queued write requests */
+ wait_queue_head_t empty_wait; /* wait queue for flushing */
+ struct timer_list timer; /* timer for delayed output */
+ char *message; /* pending message from raw3215_irq */
+ int msg_dstat; /* dstat for pending message */
+ int msg_cstat; /* cstat for pending message */
+} raw3215_info;
+
+static raw3215_info *raw3215[NR_3215]; /* array of 3215 devices structures */
+static raw3215_req *raw3215_freelist; /* list of free request structures */
+static spinlock_t raw3215_freelist_lock;/* spinlock to protect free list */
+
+static struct tty_driver tty3215_driver;
+static struct tty_struct *tty3215_table[NR_3215];
+static struct termios *tty3215_termios[NR_3215];
+static struct termios *tty3215_termios_locked[NR_3215];
+static int tty3215_refcount;
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+static int __init con3215_setup(char *str)
+{
+ int vdev;
+
+ vdev = simple_strtoul(str,&str,16);
+ if (vdev >= 0 && vdev < 65536)
+ raw3215_condevice = vdev;
+ return 1;
+}
+
+__setup("condev=", con3215_setup);
+
+/*
+ * Get a request structure from the free list
+ */
+extern inline raw3215_req *raw3215_alloc_req(void) {
+ raw3215_req *req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&raw3215_freelist_lock, flags);
+ req = raw3215_freelist;
+ raw3215_freelist = req->next;
+ spin_unlock_irqrestore(&raw3215_freelist_lock, flags);
+ return req;
+}
+
+/*
+ * Put a request structure back to the free list
+ */
+extern inline void raw3215_free_req(raw3215_req *req) {
+ unsigned long flags;
+
+ if (req->type == RAW3215_FREE)
+ return; /* don't free a free request */
+ req->type = RAW3215_FREE;
+ spin_lock_irqsave(&raw3215_freelist_lock, flags);
+ req->next = raw3215_freelist;
+ raw3215_freelist = req;
+ spin_unlock_irqrestore(&raw3215_freelist_lock, flags);
+}
+
+/*
+ * Get a write request structure. That is either a new or the last
+ * queued write request. The request structure is set up in
+ * raw3215_mk_write_ccw.
+ */
+static raw3215_req *raw3215_mk_write_req(raw3215_info *raw)
+{
+ raw3215_req *req;
+
+ /* check if there is a queued write request */
+ req = raw->queued_write;
+ if (req == NULL) {
+ /* no queued write request, use new req structure */
+ req = raw3215_alloc_req();
+ req->type = RAW3215_WRITE;
+ req->info = raw;
+ req->start = raw->head;
+ } else
+ raw->queued_write = NULL;
+ return req;
+}
+
+/*
+ * Get a read request structure. If there is a queued read request
+ * it is used, but that shouldn't happen because a 3215 terminal
+ * won't accept a new read before the old one is completed.
+ */
+static raw3215_req *raw3215_mk_read_req(raw3215_info *raw)
+{
+ raw3215_req *req;
+
+ /* there can only be ONE read request at a time */
+ req = raw->queued_read;
+ if (req == NULL) {
+ /* no queued read request, use new req structure */
+ req = raw3215_alloc_req();
+ req->type = RAW3215_READ;
+ req->info = raw;
+ } else
+ raw->queued_read = NULL;
+ return req;
+}
+
+/*
+ * Set up a write request with the information from the main structure.
+ * A ccw chain is created that writes everything in the output buffer
+ * to the 3215 device.
+ */
+static int raw3215_mk_write_ccw(raw3215_info *raw, raw3215_req *req)
+{
+ ccw1_t *ccw;
+ int len, count, ix;
+
+ ccw = req->ccws;
+ req->end = (raw->head - 1) & (RAW3215_BUFFER_SIZE - 1);
+ len = ((req->end - req->start) & (RAW3215_BUFFER_SIZE - 1)) + 1;
+ ix = req->start;
+ while (len > 0) {
+ if (ccw > req->ccws)
+ ccw[-1].flags |= 0x40; /* use command chaining */
+ ccw->cmd_code = 0x01; /* write, auto carrier return */
+ ccw->flags = 0x20; /* ignore incorrect length ind. */
+ ccw->cda =
+ (void *) virt_to_phys(raw->buffer + ix);
+ count = (len > RAW3215_MAX_CCWLEN) ?
+ RAW3215_MAX_CCWLEN : len;
+ if (ix + count > RAW3215_BUFFER_SIZE)
+ count = RAW3215_BUFFER_SIZE-ix;
+ ccw->count = count;
+ len -= count;
+ ix = (ix + count) & (RAW3215_BUFFER_SIZE - 1);
+ ccw++;
+ }
+ return len;
+}
+
+/*
+ * Set up a read request that reads up to 160 byte from the 3215 device.
+ */
+static void raw3215_mk_read_ccw(raw3215_info *raw, raw3215_req *req)
+{
+ ccw1_t *ccw;
+
+ ccw = req->ccws;
+ ccw->cmd_code = 0x0A; /* read inquiry */
+ ccw->flags = 0x20; /* ignore incorrect length */
+ ccw->count = 160;
+ ccw->cda = (void *) virt_to_phys(raw->inbuf);
+}
+
+/*
+ * Start a read or a write request
+ */
+static void raw3215_start_io(raw3215_info *raw)
+{
+ raw3215_req *req;
+ int res;
+
+ req = raw->queued_read;
+ if (req != NULL &&
+ !(raw->flags & (RAW3215_WORKING | RAW3215_THROTTLED))) {
+ /* dequeue request */
+ raw->queued_read = NULL;
+ res = do_IO(raw->irq, req->ccws, (__u32) req, 0, 0);
+ if (res != 0) {
+ /* do_IO failed, put request back to queue */
+ raw->queued_read = req;
+ } else {
+ raw->flags |= RAW3215_WORKING;
+ }
+ }
+ req = raw->queued_write;
+ if (req != NULL &&
+ !(raw->flags & (RAW3215_WORKING | RAW3215_STOPPED))) {
+ /* dequeue request */
+ raw->queued_write = NULL;
+ res = do_IO(raw->irq, req->ccws, (__u32) req, 0, 0);
+ if (res != 0) {
+ /* do_IO failed, put request back to queue */
+ raw->queued_write = req;
+ } else {
+ raw->flags |= RAW3215_WORKING;
+ }
+ }
+}
+
+/*
+ * Function to start a delayed output after RAW3215_TIMEOUT seconds
+ */
+static void raw3215_timeout(unsigned long __data)
+{
+ raw3215_info *raw = (raw3215_info *) __data;
+ unsigned long flags;
+
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ if (raw->flags & RAW3215_TIMER_RUNS) {
+ del_timer(&raw->timer);
+ raw->flags &= ~RAW3215_TIMER_RUNS;
+ raw3215_start_io(raw);
+ }
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+}
+
+/*
+ * Function to conditionally start an IO. A read is started immediatly,
+ * a write is only started immediatly if the flush flag is on or the
+ * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
+ * done immediatly a timer is started with a delay of RAW3215_TIMEOUT.
+ */
+extern inline void raw3215_try_io(raw3215_info *raw)
+{
+ if (!(raw->flags & RAW3215_ACTIVE))
+ return;
+ if (raw->queued_read != NULL)
+ raw3215_start_io(raw);
+ else if (raw->queued_write != NULL) {
+ if (raw->count >= RAW3215_MIN_WRITE ||
+ (raw->flags & RAW3215_FLUSHING)) {
+ /* execute write requests bigger than minimum size */
+ raw3215_start_io(raw);
+ if (raw->flags & RAW3215_TIMER_RUNS) {
+ del_timer(&raw->timer);
+ raw->flags &= ~RAW3215_TIMER_RUNS;
+ }
+ } else if (!(raw->flags & RAW3215_TIMER_RUNS)) {
+ /* delay small writes */
+ init_timer(&raw->timer);
+ raw->timer.expires = RAW3215_TIMEOUT + jiffies;
+ raw->timer.data = (unsigned long) raw;
+ raw->timer.function = raw3215_timeout;
+ add_timer(&raw->timer);
+ raw->flags |= RAW3215_TIMER_RUNS;
+ }
+ }
+}
+
+/*
+ * The bottom half handler routine for 3215 devices. It tries to start
+ * the next IO and wakes up processes waiting on the tty.
+ */
+static void raw3215_softint(void *data)
+{
+ raw3215_info *raw;
+ struct tty_struct *tty;
+ unsigned long flags;
+
+ raw = (raw3215_info *) data;
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ raw3215_try_io((raw3215_info *) data);
+ raw->flags &= ~RAW3215_BH_PENDING;
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+ /* Check for pending message from raw3215_irq */
+ if (raw->message != NULL) {
+ printk(raw->message, raw->irq, raw->msg_dstat, raw->msg_cstat);
+ raw->message = NULL;
+ }
+ tty = raw->tty;
+ if (tty != NULL &&
+ RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup)
+ (tty->ldisc.write_wakeup)(tty);
+ wake_up_interruptible(&tty->write_wait);
+ }
+}
+
+/*
+ * Function to safely add raw3215_softint to tq_immediate.
+ * The s390irq spinlock must be held.
+ */
+static inline void raw3215_sched_bh(raw3215_info *raw)
+{
+ if (raw->flags & RAW3215_BH_PENDING)
+ return; /* already pending */
+ raw->flags |= RAW3215_BH_PENDING;
+ raw->tqueue.routine = raw3215_softint;
+ raw->tqueue.data = raw;
+ queue_task(&raw->tqueue, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
+
+/*
+ * Find the raw3215_info structure associated with irq
+ */
+static inline raw3215_info *raw3215_find_info(int irq) {
+ raw3215_info *raw;
+ int i;
+
+ for (i = 0; i < NR_3215; i++) {
+ raw = raw3215[i];
+ if (raw != NULL && raw->irq == irq &&
+ (raw->flags & RAW3215_ACTIVE))
+ break;
+ }
+ return (i >= NR_3215) ? NULL : raw;
+}
+
+/*
+ * Interrupt routine, called from Ingo's I/O layer
+ */
+static void raw3215_irq(int irq, void *int_parm, struct pt_regs *regs)
+{
+ raw3215_info *raw;
+ raw3215_req *req;
+ struct tty_struct *tty;
+ devstat_t *stat;
+ int cstat, dstat;
+ int count, slen;
+
+ stat = (devstat_t *) int_parm;
+ req = (raw3215_req *) stat->intparm;
+ cstat = stat->cstat;
+ dstat = stat->dstat;
+ if (cstat != 0) {
+ raw = raw3215_find_info(irq);
+ if (raw != NULL) {
+ raw->message = KERN_WARNING
+ "Got nonzero channel status in raw3215_irq "
+ "(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
+ raw->msg_dstat = dstat;
+ raw->msg_cstat = cstat;
+ raw3215_sched_bh(raw);
+ }
+ }
+ if (dstat & 0x01) { /* we got a unit exception */
+ dstat &= ~0x01; /* we can ignore it */
+ }
+ switch (dstat) {
+ case 0x80:
+ if (cstat != 0)
+ break;
+ /* Attention interrupt, someone hit the enter key */
+ if ((raw = raw3215_find_info(irq)) == NULL)
+ return; /* That shouldn't happen ... */
+ /* Setup a read request */
+ req = raw3215_mk_read_req(raw);
+ raw3215_mk_read_ccw(raw, req);
+ raw->queued_read = req;
+ if (MACHINE_IS_P390)
+ memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
+ raw3215_sched_bh(raw);
+ break;
+ case 0x08:
+ case 0x0C:
+ /* Channel end interrupt. */
+ raw = req->info;
+ if (req->type == RAW3215_READ) {
+ /* store residual count, then wait for device end */
+ req->residual = stat->rescnt;
+ }
+ if (dstat == 0x08)
+ break;
+ case 0x04:
+ /* Device end interrupt. */
+ raw = req->info;
+ if (req->type == RAW3215_READ && raw->tty != NULL) {
+ tty = raw->tty;
+ count = 160 - req->residual;
+ if (MACHINE_IS_P390) {
+ slen = strnlen(raw->inbuf, RAW3215_INBUF_SIZE);
+ if (count > slen)
+ count = slen;
+ } else
+ if (count >= TTY_FLIPBUF_SIZE - tty->flip.count)
+ count = TTY_FLIPBUF_SIZE - tty->flip.count - 1;
+ EBCASC(raw->inbuf, count);
+ if (count == 2 && (
+ /* hat is 0xb0 in codepage 037 (US etc.) and thus */
+ /* converted to 0x5e in ascii ('^') */
+ strncmp(raw->inbuf, "^c", 2) == 0 ||
+ /* hat is 0xb0 in several other codepages (German,*/
+ /* UK, ...) and thus converted to ascii octal 252 */
+ strncmp(raw->inbuf, "\252c", 2) == 0) ) {
+ /* emulate a control C = break */
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = INTR_CHAR(tty);
+ tty_flip_buffer_push(raw->tty);
+ } else if (count == 2 && (
+ strncmp(raw->inbuf, "^d", 2) == 0 ||
+ strncmp(raw->inbuf, "\252d", 2) == 0) ) {
+ /* emulate a control D = end of file */
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = EOF_CHAR(tty);
+ tty_flip_buffer_push(raw->tty);
+ } else if (count == 2 && (
+ strncmp(raw->inbuf, "^z", 2) == 0 ||
+ strncmp(raw->inbuf, "\252z", 2) == 0) ) {
+ /* emulate a control Z = suspend */
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = SUSP_CHAR(tty);
+ tty_flip_buffer_push(raw->tty);
+ } else {
+ memcpy(tty->flip.char_buf_ptr,
+ raw->inbuf, count);
+ if (count < 2 ||
+ (strncmp(raw->inbuf+count-2, "^n", 2) ||
+ strncmp(raw->inbuf+count-2, "\252n", 2)) ) { /* don't add the auto \n */
+ tty->flip.char_buf_ptr[count] = '\n';
+ memset(tty->flip.flag_buf_ptr,
+ TTY_NORMAL, count + 1);
+ count++;
+ } else
+ count-=2;
+ tty->flip.char_buf_ptr += count;
+ tty->flip.flag_buf_ptr += count;
+ tty->flip.count += count;
+ tty_flip_buffer_push(raw->tty);
+ }
+ } else if (req->type == RAW3215_WRITE) {
+ raw->count -= ((req->end - req->start) &
+ (RAW3215_BUFFER_SIZE - 1)) + 1;
+ }
+ raw->flags &= ~RAW3215_WORKING;
+ raw3215_free_req(req);
+ /* check for empty wait */
+ if (waitqueue_active(&raw->empty_wait) &&
+ raw->queued_write == NULL &&
+ raw->queued_read == NULL) {
+ wake_up_interruptible(&raw->empty_wait);
+ }
+ raw3215_sched_bh(raw);
+ break;
+ default:
+ /* Strange interrupt, I'll do my best to clean up */
+ if ((raw = raw3215_find_info(irq)) == NULL)
+ return; /* That shouldn't happen ... */
+ if (raw == NULL) break;
+ if (req != NULL && req->type != RAW3215_FREE) {
+ if (req->type == RAW3215_WRITE)
+ raw->count -= ((req->end - req->start) &
+ (RAW3215_BUFFER_SIZE-1))+1;
+ raw->flags &= ~RAW3215_WORKING;
+ raw3215_free_req(req);
+ }
+ raw->message = KERN_WARNING
+ "Spurious interrupt in in raw3215_irq "
+ "(dev %i, dev sts 0x%2x, sch sts 0x%2x)";
+ raw->msg_dstat = dstat;
+ raw->msg_cstat = cstat;
+ raw3215_sched_bh(raw);
+ }
+ return;
+}
+
+/*
+ * String write routine for 3215 devices
+ */
+static int
+raw3215_write(raw3215_info *raw, const char *str,
+ int from_user, unsigned int length)
+{
+ raw3215_req *req;
+ unsigned long flags;
+ int ret, c;
+ int count;
+
+ ret = 0;
+ while (length > 0) {
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ count = (length > RAW3215_BUFFER_SIZE) ?
+ RAW3215_BUFFER_SIZE : length;
+ length -= count;
+
+ while (RAW3215_BUFFER_SIZE - raw->count < count) {
+ /* there might be a request pending */
+ raw3215_try_io(raw);
+ if (wait_cons_dev(raw->irq) != 0) {
+ /* that shouldn't happen */
+ raw->count = 0;
+ }
+ }
+
+ req = raw3215_mk_write_req(raw);
+ /* copy string to output buffer and convert it to EBCDIC */
+ if (from_user) {
+ while (1) {
+ c = MIN(count,
+ MIN(RAW3215_BUFFER_SIZE - raw->count,
+ RAW3215_BUFFER_SIZE - raw->head));
+ if (c <= 0)
+ break;
+ c -= copy_from_user(raw->buffer + raw->head,
+ str, c);
+ if (c == 0) {
+ if (!ret)
+ ret = -EFAULT;
+ break;
+ }
+ ASCEBC(raw->buffer + raw->head, c);
+ raw->head = (raw->head + c) &
+ (RAW3215_BUFFER_SIZE - 1);
+ raw->count += c;
+ str += c;
+ count -= c;
+ ret += c;
+ }
+ } else {
+ while (1) {
+ c = MIN(count,
+ MIN(RAW3215_BUFFER_SIZE - raw->count,
+ RAW3215_BUFFER_SIZE - raw->head));
+ if (c <= 0)
+ break;
+ memcpy(raw->buffer + raw->head, str, c);
+ ASCEBC(raw->buffer + raw->head, c);
+ raw->head = (raw->head + c) &
+ (RAW3215_BUFFER_SIZE - 1);
+ raw->count += c;
+ str += c;
+ count -= c;
+ ret += c;
+ }
+ }
+ raw3215_mk_write_ccw(raw, req);
+ raw->queued_write = req;
+ /* start or queue request */
+ raw3215_try_io(raw);
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+
+ }
+
+ return ret;
+}
+
+/*
+ * Put character routine for 3215 devices
+ */
+static void raw3215_putchar(raw3215_info *raw, unsigned char ch)
+{
+ raw3215_req *req;
+ unsigned long flags;
+
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ while (RAW3215_BUFFER_SIZE - raw->count < 1) {
+ /* there might be a request pending */
+ raw3215_try_io(raw);
+ if (wait_cons_dev(raw->irq) != 0) {
+ /* that shouldn't happen */
+ raw->count = 0;
+ }
+ }
+
+ req = raw3215_mk_write_req(raw);
+ raw->buffer[raw->head] = (char) _ascebc[(int) ch];
+ raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1);
+ raw->count++;
+ raw3215_mk_write_ccw(raw, req);
+ raw->queued_write = req;
+ /* start or queue request */
+ raw3215_try_io(raw);
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+}
+
+/*
+ * Flush routine, it simply sets the flush flag and tries to start
+ * pending IO.
+ */
+static void raw3215_flush_buffer(raw3215_info *raw)
+{
+ unsigned long flags;
+
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ if (raw->count > 0) {
+ raw->flags |= RAW3215_FLUSHING;
+ raw3215_try_io(raw);
+ raw->flags &= ~RAW3215_FLUSHING;
+ }
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+}
+
+/*
+ * Fire up a 3215 device.
+ */
+static int raw3215_startup(raw3215_info *raw)
+{
+ unsigned long flags;
+
+ if (raw->flags & RAW3215_ACTIVE)
+ return 0;
+ if (request_irq(raw->irq, raw3215_irq, SA_INTERRUPT,
+ "3215 terminal driver", &raw->devstat) != 0)
+ return -1;
+ raw->flags |= RAW3215_ACTIVE;
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ raw3215_try_io(raw);
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+
+ return 0;
+}
+
+/*
+ * Shutdown a 3215 device.
+ */
+static void raw3215_shutdown(raw3215_info *raw)
+{
+ DECLARE_WAITQUEUE(wait, current);
+ unsigned long flags;
+
+ if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
+ return;
+ /* Wait for outstanding requests, then free irq */
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ if ((raw->flags & RAW3215_WORKING) ||
+ raw->queued_write != NULL ||
+ raw->queued_read != NULL) {
+ raw->flags |= RAW3215_CLOSING;
+ add_wait_queue(&raw->empty_wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+ schedule();
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ current->state = TASK_RUNNING;
+ raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
+ }
+ free_irq(raw->irq, NULL);
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+}
+
+static int
+raw3215_find_dev(int number)
+{
+ dev_info_t dinfo;
+ int irq;
+ int count;
+
+ irq = get_irq_first();
+ count = 0;
+ while (count <= number && irq != -ENODEV) {
+ if (get_dev_info(irq, &dinfo) == -ENODEV)
+ break;
+ if (dinfo.devno == raw3215_condevice ||
+ dinfo.sid_data.cu_type == 0x3215) {
+ count++;
+ if (count > number)
+ return irq;
+ }
+ irq = get_irq_next(irq);
+ }
+ return -1; /* console not found */
+}
+
+#ifdef CONFIG_3215_CONSOLE
+
+/*
+ * Try to request the console IRQ. Called from init/main.c
+ */
+int con3215_activate(void)
+{
+ raw3215_info *raw;
+
+ if (!MACHINE_IS_VM && !MACHINE_IS_P390)
+ return 0;
+ raw = raw3215[0]; /* 3215 console is the first one */
+ if (raw->irq == -1) /* now console device found in con3215_init */
+ return -1;
+ return raw3215_startup(raw);
+}
+
+/*
+ * Write a string to the 3215 console
+ */
+static void
+con3215_write(struct console *co, const char *str, unsigned int count)
+{
+ raw3215_info *raw;
+
+ if (count <= 0)
+ return;
+ raw = raw3215[0]; /* console 3215 is the first one */
+ raw3215_write(raw, str, 0, count);
+}
+
+kdev_t con3215_device(struct console *c)
+{
+ return MKDEV(TTY_MAJOR, c->index);
+}
+
+/*
+ * panic() calls console_unblank before the system enters a
+ * disabled, endless loop.
+ */
+void con3215_unblank(void)
+{
+ raw3215_info *raw;
+ unsigned long flags;
+
+ raw = raw3215[0]; /* console 3215 is the first one */
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ while (raw->count > 0) {
+ /* there might be a request pending */
+ raw->flags |= RAW3215_FLUSHING;
+ raw3215_try_io(raw);
+ if (wait_cons_dev(raw->irq) != 0) {
+ /* that shouldn't happen */
+ raw->count = 0;
+ }
+ raw->flags &= ~RAW3215_FLUSHING;
+ }
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+}
+
+static int __init con3215_consetup(struct console *co, char *options)
+{
+ return 0;
+}
+
+/*
+ * The console structure for the 3215 console
+ */
+static struct console con3215 = {
+ "tty3215",
+ con3215_write,
+ NULL,
+ con3215_device,
+ NULL,
+ con3215_unblank,
+ con3215_consetup,
+ CON_PRINTBUFFER,
+ 0,
+ 0,
+ NULL
+};
+
+#endif
+
+/*
+ * tty3215_open
+ *
+ * This routine is called whenever a 3215 tty is opened.
+ */
+static int tty3215_open(struct tty_struct *tty, struct file * filp)
+{
+ raw3215_info *raw;
+ int retval, line;
+
+ line = MINOR(tty->device) - tty->driver.minor_start;
+ if ((line < 0) || (line >= NR_3215))
+ return -ENODEV;
+
+ raw = raw3215[line];
+ if (raw == NULL) {
+ raw = kmalloc(sizeof(raw3215_info) +
+ RAW3215_INBUF_SIZE, GFP_KERNEL);
+ if (raw == NULL)
+ return -ENOMEM;
+ raw->irq = raw3215_find_dev(line);
+ if (raw->irq == -1) {
+ kfree(raw);
+ return -ENODEV;
+ }
+ raw->inbuf = (char *) raw + sizeof(raw3215_info);
+ memset(raw, 0, sizeof(raw3215_info));
+ raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL);
+ if (raw->buffer == NULL) {
+ kfree_s(raw, sizeof(raw3215_info));
+ return -ENOMEM;
+ }
+ raw->tqueue.routine = raw3215_softint;
+ raw->tqueue.data = raw;
+ init_waitqueue_head(&raw->empty_wait);
+ raw3215[line] = raw;
+ }
+
+ tty->driver_data = raw;
+ raw->tty = tty;
+
+ tty->low_latency = 0; /* don't use bottom half for pushing chars */
+ /*
+ * Start up 3215 device
+ */
+ retval = raw3215_startup(raw);
+ if (retval)
+ return retval;
+
+ return 0;
+}
+
+/*
+ * tty3215_close()
+ *
+ * This routine is called when the 3215 tty is closed. We wait
+ * for the remaining request to be completed. Then we clean up.
+ */
+static void tty3215_close(struct tty_struct *tty, struct file * filp)
+{
+ raw3215_info *raw;
+
+ raw = (raw3215_info *) tty->driver_data;
+ if (raw == NULL || tty->count > 1)
+ return;
+ tty->closing = 1;
+ /* Shutdown the terminal */
+ raw3215_shutdown(raw);
+ tty->closing = 0;
+ raw->tty = NULL;
+}
+
+/*
+ * Returns the amount of free space in the output buffer.
+ */
+static int tty3215_write_room(struct tty_struct *tty)
+{
+ raw3215_info *raw;
+
+ raw = (raw3215_info *) tty->driver_data;
+ return RAW3215_BUFFER_SIZE - raw->count;
+}
+
+/*
+ * String write routine for 3215 ttys
+ */
+static int tty3215_write(struct tty_struct * tty, int from_user,
+ const unsigned char *buf, int count)
+{
+ raw3215_info *raw;
+ int ret;
+
+ if (!tty)
+ return 0;
+ raw = (raw3215_info *) tty->driver_data;
+ ret = raw3215_write(raw, buf, from_user, count);
+ return ret;
+}
+
+/*
+ * Put character routine for 3215 ttys
+ */
+static void tty3215_put_char(struct tty_struct *tty, unsigned char ch)
+{
+ raw3215_info *raw;
+
+ if (!tty)
+ return;
+ raw = (raw3215_info *) tty->driver_data;
+ raw3215_putchar(raw, ch);
+}
+
+static void tty3215_flush_chars(struct tty_struct *tty)
+{
+}
+
+/*
+ * Returns the number of characters in the output buffer
+ */
+static int tty3215_chars_in_buffer(struct tty_struct *tty)
+{
+ raw3215_info *raw;
+
+ raw = (raw3215_info *) tty->driver_data;
+ return raw->count;
+}
+
+static void tty3215_flush_buffer(struct tty_struct *tty)
+{
+ raw3215_info *raw;
+
+ raw = (raw3215_info *) tty->driver_data;
+ raw3215_flush_buffer(raw);
+ wake_up_interruptible(&tty->write_wait);
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ tty->ldisc.write_wakeup)
+ (tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * Currently we don't have any io controls for 3215 ttys
+ */
+static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg)
+{
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+
+ switch (cmd) {
+ default:
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
+
+/*
+ * Disable reading from a 3215 tty
+ */
+static void tty3215_throttle(struct tty_struct * tty)
+{
+ raw3215_info *raw;
+
+ raw = (raw3215_info *) tty->driver_data;
+ raw->flags |= RAW3215_THROTTLED;
+}
+
+/*
+ * Enable reading from a 3215 tty
+ */
+static void tty3215_unthrottle(struct tty_struct * tty)
+{
+ raw3215_info *raw;
+ unsigned long flags;
+
+ raw = (raw3215_info *) tty->driver_data;
+ if (raw->flags & RAW3215_THROTTLED) {
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ raw->flags &= ~RAW3215_THROTTLED;
+ raw3215_try_io(raw);
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+ }
+}
+
+/*
+ * Disable writing to a 3215 tty
+ */
+static void tty3215_stop(struct tty_struct *tty)
+{
+ raw3215_info *raw;
+
+ raw = (raw3215_info *) tty->driver_data;
+ raw->flags |= RAW3215_STOPPED;
+}
+
+/*
+ * Enable writing to a 3215 tty
+ */
+static void tty3215_start(struct tty_struct *tty)
+{
+ raw3215_info *raw;
+ unsigned long flags;
+
+ raw = (raw3215_info *) tty->driver_data;
+ if (raw->flags & RAW3215_STOPPED) {
+ s390irq_spin_lock_irqsave(raw->irq, flags);
+ raw->flags &= ~RAW3215_STOPPED;
+ raw3215_try_io(raw);
+ s390irq_spin_unlock_irqrestore(raw->irq, flags);
+ }
+}
+
+/*
+ * 3215 console driver boottime initialization code.
+ * Register console. We can't request the IRQ here, because
+ * it's too early (kmalloc isn't working yet). We'll have to
+ * buffer all the console requests until we can request the
+ * irq. For this purpose we use some pages of fixed memory.
+ */
+void __init con3215_init(void)
+{
+ raw3215_info *raw;
+ raw3215_req *req;
+ int i;
+
+ if (!MACHINE_IS_VM && !MACHINE_IS_P390)
+ return;
+ if (MACHINE_IS_VM) {
+ cpcmd("TERM CONMODE 3215", NULL, 0);
+ cpcmd("TERM AUTOCR OFF", NULL, 0);
+ }
+
+ /* allocate 3215 request structures */
+ raw3215_freelist = NULL;
+ spin_lock_init(&raw3215_freelist_lock);
+ for (i = 0; i < NR_3215_REQ; i++) {
+ req = (raw3215_req *) alloc_bootmem(sizeof(raw3215_req));
+ req->next = raw3215_freelist;
+ raw3215_freelist = req;
+ }
+
+#ifdef CONFIG_3215_CONSOLE
+ raw3215[0] = raw = (raw3215_info *)
+ alloc_bootmem(sizeof(raw3215_info));
+ memset(raw, 0, sizeof(raw3215_info));
+ raw->buffer = (char *) alloc_bootmem(RAW3215_BUFFER_SIZE);
+ raw->inbuf = (char *) alloc_bootmem(RAW3215_INBUF_SIZE);
+ /* Find the first console */
+ raw->irq = raw3215_find_dev(0);
+ raw->flags |= RAW3215_FIXED;
+ raw->tqueue.routine = raw3215_softint;
+ raw->tqueue.data = raw;
+ init_waitqueue_head(&raw->empty_wait);
+
+ if (raw->irq != -1) {
+ register_console(&con3215);
+ s390irq_spin_lock(raw->irq);
+ set_cons_dev(raw->irq);
+ s390irq_spin_unlock(raw->irq);
+ } else {
+ free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE);
+ free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE);
+ free_bootmem((unsigned long) raw, sizeof(raw3215_info));
+ raw3215[0] = NULL;
+ printk("Couldn't find a 3215 console device\n");
+ }
+#endif
+
+ /*
+ * Initialize the tty_driver structure
+ * Entries in tty3215_driver that are NOT initialized:
+ * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc
+ */
+
+ memset(&tty3215_driver, 0, sizeof(struct tty_driver));
+ tty3215_driver.magic = TTY_DRIVER_MAGIC;
+ tty3215_driver.driver_name = "tty3215";
+ tty3215_driver.name = "ttyS";
+ tty3215_driver.name_base = 0;
+ tty3215_driver.major = TTY_MAJOR;
+ tty3215_driver.minor_start = 64;
+ tty3215_driver.num = NR_3215;
+ tty3215_driver.type = TTY_DRIVER_TYPE_SYSTEM;
+ tty3215_driver.subtype = SYSTEM_TYPE_TTY;
+ tty3215_driver.init_termios = tty_std_termios;
+ tty3215_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
+ tty3215_driver.init_termios.c_oflag = ONLCR;
+ tty3215_driver.init_termios.c_lflag = ISIG;
+ tty3215_driver.flags = TTY_DRIVER_REAL_RAW;
+ tty3215_driver.refcount = &tty3215_refcount;
+ tty3215_driver.table = tty3215_table;
+ tty3215_driver.termios = tty3215_termios;
+ tty3215_driver.termios_locked = tty3215_termios_locked;
+
+ tty3215_driver.open = tty3215_open;
+ tty3215_driver.close = tty3215_close;
+ tty3215_driver.write = tty3215_write;
+ tty3215_driver.put_char = tty3215_put_char;
+ tty3215_driver.flush_chars = tty3215_flush_chars;
+ tty3215_driver.write_room = tty3215_write_room;
+ tty3215_driver.chars_in_buffer = tty3215_chars_in_buffer;
+ tty3215_driver.flush_buffer = tty3215_flush_buffer;
+ tty3215_driver.ioctl = tty3215_ioctl;
+ tty3215_driver.throttle = tty3215_throttle;
+ tty3215_driver.unthrottle = tty3215_unthrottle;
+ tty3215_driver.send_xchar = NULL;
+ tty3215_driver.set_termios = NULL;
+ tty3215_driver.stop = tty3215_stop;
+ tty3215_driver.start = tty3215_start;
+ tty3215_driver.hangup = NULL;
+ tty3215_driver.break_ctl = NULL;
+ tty3215_driver.wait_until_sent = NULL;
+ tty3215_driver.read_proc = NULL;
+
+ if (tty_register_driver(&tty3215_driver))
+ panic("Couldn't register tty3215 driver\n");
+
+}
diff --git a/drivers/s390/char/hwc.h b/drivers/s390/char/hwc.h
new file mode 100644
index 000000000..5de3d1b6f
--- /dev/null
+++ b/drivers/s390/char/hwc.h
@@ -0,0 +1,249 @@
+/*
+ * drivers/s390/char/hwc.h
+ *
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Peschke <peschke@fh-brandenburg.de>
+ *
+ *
+ *
+ */
+
+#ifndef __HWC_H__
+#define __HWC_H__
+
+#define ET_OpCmd 0x01
+#define ET_Msg 0x02
+#define ET_StateChange 0x08
+#define ET_PMsgCmd 0x09
+#define ET_CntlProgOpCmd 0x20
+
+#define ET_OpCmd_Mask 0x80000000
+#define ET_Msg_Mask 0x40000000
+#define ET_StateChange_Mask 0x01000000
+#define ET_PMsgCmd_Mask 0x00800000
+#define ET_CtlProgOpCmd_Mask 0x00000001
+
+#define GMF_DOM 0x8000
+#define GMF_SndAlrm 0x4000
+#define GMF_HoldMsg 0x2000
+
+#define LTF_CntlText 0x8000
+#define LTF_LabelText 0x4000
+#define LTF_DataText 0x2000
+#define LTF_EndText 0x1000
+#define LTF_PromptText 0x0800
+
+#define HWC_COMMAND_INITIATED 0
+#define HWC_BUSY 2
+#define HWC_NOT_OPERATIONAL 3
+
+#define HWC_CMDW_READDATA 0x00770005
+
+#define HWC_CMDW_WRITEDATA 0x00760005
+
+#define HWC_CMDW_WRITEMASK 0x00780005
+
+#define GDS_ID_MDSMU 0x1310
+
+#define GDS_ID_MDSRouteInfo 0x1311
+
+#define GDS_ID_AgUnWrkCorr 0x1549
+
+#define GDS_ID_SNACondReport 0x1532
+
+#define GDS_ID_CPMSU 0x1212
+
+#define GDS_ID_RoutTargInstr 0x154D
+
+#define GDS_ID_OpReq 0x8070
+
+#define GDS_ID_TextCmd 0x1320
+
+#define GDS_KEY_SelfDefTextMsg 0x31
+
+#define _HWCB_HEADER u16 length; \
+ u8 function_code; \
+ u8 control_mask[3]; \
+ u16 response_code;
+
+#define _EBUF_HEADER u16 length; \
+ u8 type; \
+ u8 flags; \
+ u16 _reserved;
+
+typedef struct {
+ _EBUF_HEADER
+} __attribute__ ((packed))
+
+evbuf_t;
+
+#define _MDB_HEADER u16 length; \
+ u16 type; \
+ u32 tag; \
+ u32 revision_code;
+
+#define _GO_HEADER u16 length; \
+ u16 type; \
+ u32 domid; \
+ u8 hhmmss_time[8]; \
+ u8 th_time[3]; \
+ u8 _reserved_0; \
+ u8 dddyyyy_date[7]; \
+ u8 _reserved_1; \
+ u16 general_msg_flags; \
+ u8 _reserved_2[10]; \
+ u8 originating_system_name[8]; \
+ u8 job_guest_name[8];
+
+#define _MTO_HEADER u16 length; \
+ u16 type; \
+ u16 line_type_flags; \
+ u8 alarm_control; \
+ u8 _reserved[3];
+
+typedef struct {
+ _GO_HEADER
+} __attribute__ ((packed))
+
+go_t;
+
+typedef struct {
+ go_t go;
+} __attribute__ ((packed))
+
+mdb_body_t;
+
+typedef struct {
+ _MDB_HEADER
+ mdb_body_t mdb_body;
+} __attribute__ ((packed))
+
+mdb_t;
+
+typedef struct {
+ _EBUF_HEADER
+ mdb_t mdb;
+} __attribute__ ((packed))
+
+msgbuf_t;
+
+typedef struct {
+ _HWCB_HEADER
+ msgbuf_t msgbuf;
+} __attribute__ ((packed))
+
+write_hwcb_t;
+
+typedef struct {
+ _MTO_HEADER
+} __attribute__ ((packed))
+
+mto_t;
+
+static write_hwcb_t write_hwcb_template =
+{
+ sizeof (write_hwcb_t),
+ 0x00,
+ {
+ 0x00,
+ 0x00,
+ 0x00
+ },
+ 0x0000,
+ {
+ sizeof (msgbuf_t),
+ ET_Msg,
+ 0x00,
+ 0x0000,
+ {
+ sizeof (mdb_t),
+ 0x0001,
+ 0xD4C4C240,
+ 0x00000001,
+ {
+ {
+ sizeof (go_t),
+ 0x0001
+
+ }
+ }
+ }
+ }
+};
+
+static mto_t mto_template =
+{
+ sizeof (mto_t),
+ 0x0004,
+ LTF_EndText,
+ 0x00
+};
+
+typedef u32 _hwcb_mask_t;
+
+typedef struct {
+ _HWCB_HEADER
+ u16 _reserved;
+ u16 mask_length;
+ _hwcb_mask_t cp_receive_mask;
+ _hwcb_mask_t cp_send_mask;
+ _hwcb_mask_t hwc_receive_mask;
+ _hwcb_mask_t hwc_send_mask;
+} __attribute__ ((packed))
+
+init_hwcb_t;
+
+static init_hwcb_t init_hwcb_template =
+{
+ sizeof (init_hwcb_t),
+ 0x00,
+ {
+ 0x00,
+ 0x00,
+ 0x00
+ },
+ 0x0000,
+ 0x0000,
+ sizeof (_hwcb_mask_t),
+ ET_OpCmd_Mask | ET_PMsgCmd_Mask,
+ ET_Msg_Mask
+};
+
+#define _GDS_VECTOR_HEADER u16 length; \
+ u16 gds_id;
+
+#define _GDS_SUBVECTOR_HEADER u8 length; \
+ u8 key;
+
+typedef struct {
+ _GDS_VECTOR_HEADER
+} __attribute__ ((packed))
+
+gds_vector_t;
+
+typedef struct {
+ _GDS_SUBVECTOR_HEADER
+} __attribute__ ((packed))
+
+gds_subvector_t;
+
+typedef struct {
+ _HWCB_HEADER
+} __attribute__ ((packed))
+
+read_hwcb_t;
+
+static read_hwcb_t read_hwcb_template =
+{
+ PAGE_SIZE,
+ 0x00,
+ {
+ 0x00,
+ 0x00,
+ 0x80
+ }
+};
+
+#endif /* __HWC_H__ */
diff --git a/drivers/s390/char/hwc_con.c b/drivers/s390/char/hwc_con.c
new file mode 100644
index 000000000..16d5553e8
--- /dev/null
+++ b/drivers/s390/char/hwc_con.c
@@ -0,0 +1,99 @@
+/*
+ * drivers/s390/char/hwc_con.c
+ * HWC line mode console driver
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Peschke <peschke@fh-brandenburg.de>
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/errno.h>
+#include <linux/kdev_t.h>
+#include <linux/string.h>
+#include <linux/console.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+
+#include "hwc_rw.h"
+
+extern void hwc_tty_init (void);
+
+#ifdef CONFIG_HWC_CONSOLE
+
+#define hwc_console_major 4
+#define hwc_console_minor 0
+#define hwc_console_name "console"
+
+void hwc_console_write (struct console *, const char *, unsigned int);
+kdev_t hwc_console_device (struct console *);
+
+#define HWC_CON_PRINT_HEADER "hwc console driver: "
+
+struct console hwc_console =
+{
+
+ hwc_console_name,
+ hwc_console_write,
+ NULL,
+ hwc_console_device,
+ NULL,
+ NULL,
+ NULL,
+ CON_PRINTBUFFER,
+ 0,
+ 0,
+ NULL
+};
+
+void
+hwc_console_write (
+ struct console *console,
+ const char *message,
+ unsigned int count)
+{
+
+ if (console->device (console) != hwc_console.device (&hwc_console)) {
+
+ hwc_printk (KERN_WARNING HWC_CON_PRINT_HEADER
+ "hwc_console_write() called with wrong "
+ "device number");
+ return;
+ }
+ hwc_write (0, message, count);
+}
+
+kdev_t
+hwc_console_device (struct console * c)
+{
+ return MKDEV (hwc_console_major, hwc_console_minor);
+}
+
+#endif
+
+void __init
+hwc_console_init (void)
+{
+
+#ifdef CONFIG_3215
+ if (MACHINE_IS_VM)
+ return;
+#endif
+ if (MACHINE_IS_P390)
+ return;
+
+ if (hwc_init () == 0) {
+
+#ifdef CONFIG_HWC_CONSOLE
+
+ register_console (&hwc_console);
+#endif
+
+ hwc_tty_init ();
+ } else
+ panic (HWC_CON_PRINT_HEADER "hwc initialisation failed !");
+
+ return;
+}
diff --git a/drivers/s390/char/hwc_rw.c b/drivers/s390/char/hwc_rw.c
new file mode 100644
index 000000000..6ffecb799
--- /dev/null
+++ b/drivers/s390/char/hwc_rw.c
@@ -0,0 +1,2016 @@
+/*
+ * drivers/s390/char/hwc_rw.c
+ * driver: reading from and writing to system console on S/390 via HWC
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Peschke <peschke@fh-brandenburg.de>
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ctype.h>
+#include <linux/mm.h>
+#include <linux/timer.h>
+#include <linux/bootmem.h>
+
+#include <asm/ebcdic.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/bitops.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+
+#ifndef MIN
+#define MIN(a,b) ((a<b) ? a : b)
+#endif
+
+#define HWC_RW_PRINT_HEADER "hwc low level driver: "
+
+#define USE_VM_DETECTION
+
+#define DEFAULT_CASE_DELIMITER '%'
+
+#define DUMP_HWC_INIT_ERROR
+
+#define DUMP_HWC_WRITE_ERROR
+
+#define DUMP_HWC_WRITE_LIST_ERROR
+
+#define DUMP_HWC_READ_ERROR
+
+#undef DUMP_HWCB_INPUT
+
+#undef BUFFER_STRESS_TEST
+
+typedef struct {
+ unsigned char *next;
+ unsigned short int mto_char_sum;
+ unsigned char mto_number;
+ unsigned char times_lost;
+ unsigned short int mto_number_lost;
+ unsigned long int mto_char_sum_lost;
+} __attribute__ ((packed))
+
+hwcb_list_t;
+
+#define MAX_HWCB_ROOM (PAGE_SIZE - sizeof(hwcb_list_t))
+
+#define MAX_MESSAGE_SIZE (MAX_HWCB_ROOM - sizeof(write_hwcb_t))
+
+#define BUF_HWCB hwc_data.hwcb_list_tail
+#define OUT_HWCB hwc_data.hwcb_list_head
+#define ALL_HWCB_MTO hwc_data.mto_number
+#define ALL_HWCB_CHAR hwc_data.mto_char_sum
+
+#define _LIST(hwcb) ((hwcb_list_t*)(&(hwcb)[PAGE_SIZE-sizeof(hwcb_list_t)]))
+
+#define _HWCB_CHAR(hwcb) (_LIST(hwcb)->mto_char_sum)
+
+#define _HWCB_MTO(hwcb) (_LIST(hwcb)->mto_number)
+
+#define _HWCB_CHAR_LOST(hwcb) (_LIST(hwcb)->mto_char_sum_lost)
+
+#define _HWCB_MTO_LOST(hwcb) (_LIST(hwcb)->mto_number_lost)
+
+#define _HWCB_TIMES_LOST(hwcb) (_LIST(hwcb)->times_lost)
+
+#define _HWCB_NEXT(hwcb) (_LIST(hwcb)->next)
+
+#define BUF_HWCB_CHAR _HWCB_CHAR(BUF_HWCB)
+
+#define BUF_HWCB_MTO _HWCB_MTO(BUF_HWCB)
+
+#define BUF_HWCB_NEXT _HWCB_NEXT(BUF_HWCB)
+
+#define OUT_HWCB_CHAR _HWCB_CHAR(OUT_HWCB)
+
+#define OUT_HWCB_MTO _HWCB_MTO(OUT_HWCB)
+
+#define OUT_HWCB_NEXT _HWCB_NEXT(OUT_HWCB)
+
+#define BUF_HWCB_CHAR_LOST _HWCB_CHAR_LOST(BUF_HWCB)
+
+#define BUF_HWCB_MTO_LOST _HWCB_MTO_LOST(BUF_HWCB)
+
+#define OUT_HWCB_CHAR_LOST _HWCB_CHAR_LOST(OUT_HWCB)
+
+#define OUT_HWCB_MTO_LOST _HWCB_MTO_LOST(OUT_HWCB)
+
+#define BUF_HWCB_TIMES_LOST _HWCB_TIMES_LOST(BUF_HWCB)
+
+#include "hwc.h"
+
+#define __HWC_RW_C__
+#include "hwc_rw.h"
+#undef __HWC_RW_C__
+
+static unsigned char _obuf[MAX_HWCB_ROOM];
+
+static unsigned char
+ _page[PAGE_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
+
+typedef u32 kmem_pages_t;
+
+#define MAX_KMEM_PAGES (sizeof(kmem_pages_t) << 3)
+
+#define HWC_TIMER_RUNS 1
+#define FLUSH_HWCBS 2
+
+static struct {
+
+ hwc_ioctls_t ioctls;
+
+ hwc_ioctls_t init_ioctls;
+
+ unsigned char *hwcb_list_head;
+
+ unsigned char *hwcb_list_tail;
+
+ unsigned short int mto_number;
+
+ unsigned int mto_char_sum;
+
+ unsigned char hwcb_count;
+
+ unsigned long kmem_start;
+
+ unsigned long kmem_end;
+
+ kmem_pages_t kmem_pages;
+
+ unsigned char *obuf;
+
+ unsigned short int obuf_cursor;
+
+ unsigned short int obuf_count;
+
+ unsigned short int obuf_start;
+
+ unsigned char *page;
+
+ u32 current_servc;
+
+ unsigned char *current_hwcb;
+
+ unsigned char write_nonprio:1;
+ unsigned char write_prio:1;
+ unsigned char read_nonprio:1;
+ unsigned char read_prio:1;
+
+ unsigned char flags;
+
+ spinlock_t lock;
+
+ struct timer_list write_timer;
+} hwc_data =
+{
+ {
+ },
+ {
+ 8,
+ 0,
+ 80,
+ CODE_ASCII,
+ 1,
+ 50,
+ MAX_KMEM_PAGES,
+
+ 0,
+
+ 0x6c
+
+ },
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ _obuf,
+ 0,
+ 0,
+ 0,
+ _page,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+
+};
+
+#define DELAYED_WRITE 0
+#define IMMEDIATE_WRITE 1
+
+static signed int do_hwc_write (int from_user, unsigned char *,
+ unsigned int,
+ unsigned char,
+ unsigned char);
+
+static asmlinkage int
+internal_print (char write_time, const char *fmt,...)
+{
+ va_list args;
+ int i;
+ unsigned char buf[512];
+
+ va_start (args, fmt);
+ i = vsprintf (buf, fmt, args);
+ va_end (args);
+ return do_hwc_write (0, buf, i, CODE_ASCII, write_time);
+}
+
+int
+hwc_printk (const char *fmt,...)
+{
+ va_list args;
+ int i;
+ unsigned char buf[512];
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ i = vsprintf (buf, fmt, args);
+ va_end (args);
+ retval = do_hwc_write (0, buf, i, CODE_ASCII, IMMEDIATE_WRITE);
+
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+
+ return retval;
+}
+
+#ifdef DUMP_HWCB_INPUT
+
+static void
+dump_storage_area (unsigned char *area, unsigned short int count)
+{
+ unsigned short int index;
+ ioctl_nl_t old_final_nl;
+
+ if (!area || !count)
+ return;
+
+ old_final_nl = hwc_data.ioctls.final_nl;
+ hwc_data.ioctls.final_nl = 1;
+
+ internal_print (DELAYED_WRITE, "\n%8x ", area);
+
+ for (index = 0; index < count; index++) {
+
+ if (area[index] <= 0xF)
+ internal_print (DELAYED_WRITE, "0%x", area[index]);
+ else
+ internal_print (DELAYED_WRITE, "%x", area[index]);
+
+ if ((index & 0xF) == 0xF)
+ internal_print (DELAYED_WRITE, "\n%8x ",
+ &area[index + 1]);
+ else if ((index & 3) == 3)
+ internal_print (DELAYED_WRITE, " ");
+ }
+
+ internal_print (IMMEDIATE_WRITE, "\n");
+
+ hwc_data.ioctls.final_nl = old_final_nl;
+}
+#endif
+
+static inline u32
+service_call (
+ u32 hwc_command_word,
+ unsigned char hwcb[])
+{
+ unsigned int condition_code = 1;
+
+ __asm__ __volatile__ ("L 1, 0(0,%0) \n\t"
+ "LRA 2, 0(0,%1) \n\t"
+ ".long 0xB2200012 \n\t"
+ :
+ :"a" (&hwc_command_word), "a" (hwcb)
+ :"1", "2", "memory");
+
+ __asm__ __volatile__ ("IPM %0 \n\t"
+ "SRL %0, 28 \n\t"
+ :"=r" (condition_code));
+
+ return condition_code;
+}
+
+static inline unsigned char *
+ext_int_param (void)
+{
+ u32 param;
+
+ __asm__ __volatile__ ("L %0,128(0,0)\n\t"
+ :"=r" (param));
+
+ return ((unsigned char *) param);
+}
+
+static int
+prepare_write_hwcb (void)
+{
+ write_hwcb_t *hwcb;
+
+ if (!BUF_HWCB)
+ return -ENOMEM;
+
+ BUF_HWCB_MTO = 0;
+ BUF_HWCB_CHAR = 0;
+
+ hwcb = (write_hwcb_t *) BUF_HWCB;
+
+ memcpy (hwcb, &write_hwcb_template, sizeof (write_hwcb_t));
+
+ if (!hwc_data.write_nonprio && hwc_data.write_prio)
+ hwcb->msgbuf.type = ET_PMsgCmd;
+
+ return 0;
+}
+
+static int
+sane_write_hwcb (void)
+{
+ unsigned short int lost_msg;
+ unsigned int lost_char;
+ unsigned char lost_hwcb;
+ unsigned char *bad_addr;
+ unsigned long page;
+ int page_nr;
+
+ if (!OUT_HWCB)
+ return -ENOMEM;
+
+ if ((unsigned long) OUT_HWCB & 0xFFF) {
+
+ bad_addr = OUT_HWCB;
+
+#ifdef DUMP_HWC_WRITE_LIST_ERROR
+ __asm__ ("LHI 1,0xe30\n\t"
+ "LRA 2,0(0,%0) \n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (bad_addr)
+ : "1", "2");
+#endif
+
+ hwc_data.kmem_pages = 0;
+ if ((unsigned long) BUF_HWCB & 0xFFF) {
+
+ lost_hwcb = hwc_data.hwcb_count;
+ lost_msg = ALL_HWCB_MTO;
+ lost_char = ALL_HWCB_CHAR;
+
+ OUT_HWCB = NULL;
+ BUF_HWCB = NULL;
+ ALL_HWCB_MTO = 0;
+ ALL_HWCB_CHAR = 0;
+ hwc_data.hwcb_count = 0;
+ } else {
+
+ lost_hwcb = hwc_data.hwcb_count - 1;
+ lost_msg = ALL_HWCB_MTO - BUF_HWCB_MTO;
+ lost_char = ALL_HWCB_CHAR - BUF_HWCB_CHAR;
+ OUT_HWCB = BUF_HWCB;
+ ALL_HWCB_MTO = BUF_HWCB_MTO;
+ ALL_HWCB_CHAR = BUF_HWCB_CHAR;
+ hwc_data.hwcb_count = 1;
+ page = (unsigned long) BUF_HWCB;
+
+ if (page >= hwc_data.kmem_start &&
+ page < hwc_data.kmem_end) {
+
+ page_nr = (int)
+ ((page - hwc_data.kmem_start) >> 12);
+ set_bit (page_nr, &hwc_data.kmem_pages);
+ }
+ }
+
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "found invalid HWCB at address 0x%x. List corrupted. "
+ "Lost %i HWCBs with %i characters within up to %i "
+ "messages. Saved %i HWCB with last %i characters i"
+ "within up to %i messages.\n",
+ (unsigned int) bad_addr,
+ lost_hwcb, lost_char, lost_msg,
+ hwc_data.hwcb_count,
+ ALL_HWCB_CHAR, ALL_HWCB_MTO);
+ }
+ return 0;
+}
+
+static int
+reuse_write_hwcb (void)
+{
+ int retval;
+
+ if (hwc_data.hwcb_count < 2)
+#ifdef DUMP_HWC_WRITE_LIST_ERROR
+ __asm__ ("LHI 1,0xe31\n\t"
+ "LRA 2,0(0,%0)\n\t"
+ "LRA 3,0(0,%1)\n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (BUF_HWCB), "a" (OUT_HWCB)
+ : "1", "2", "3");
+#else
+ return -EPERM;
+#endif
+
+ if (hwc_data.current_hwcb == OUT_HWCB) {
+
+ if (hwc_data.hwcb_count > 2) {
+
+ BUF_HWCB_NEXT = OUT_HWCB_NEXT;
+
+ BUF_HWCB = OUT_HWCB_NEXT;
+
+ OUT_HWCB_NEXT = BUF_HWCB_NEXT;
+
+ BUF_HWCB_NEXT = NULL;
+ }
+ } else {
+
+ BUF_HWCB_NEXT = OUT_HWCB;
+
+ BUF_HWCB = OUT_HWCB;
+
+ OUT_HWCB = OUT_HWCB_NEXT;
+
+ BUF_HWCB_NEXT = NULL;
+ }
+
+ BUF_HWCB_TIMES_LOST += 1;
+ BUF_HWCB_CHAR_LOST += BUF_HWCB_CHAR;
+ BUF_HWCB_MTO_LOST += BUF_HWCB_MTO;
+ ALL_HWCB_MTO -= BUF_HWCB_MTO;
+ ALL_HWCB_CHAR -= BUF_HWCB_CHAR;
+
+ retval = prepare_write_hwcb ();
+
+ if (hwc_data.hwcb_count == hwc_data.ioctls.max_hwcb)
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "reached my own limit of "
+ "allowed buffer space for output (%i HWCBs = %li "
+ "bytes), skipped content of oldest HWCB %i time(s) "
+ "(%i lines = %i characters)\n",
+ hwc_data.ioctls.max_hwcb,
+ hwc_data.ioctls.max_hwcb * PAGE_SIZE,
+ BUF_HWCB_TIMES_LOST,
+ BUF_HWCB_MTO_LOST,
+ BUF_HWCB_CHAR_LOST);
+ else
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "page allocation failed, "
+ "could not expand buffer for output (currently in "
+ "use: %i HWCBs = %li bytes), skipped content of "
+ "oldest HWCB %i time(s) (%i lines = %i characters)\n",
+ hwc_data.hwcb_count,
+ hwc_data.hwcb_count * PAGE_SIZE,
+ BUF_HWCB_TIMES_LOST,
+ BUF_HWCB_MTO_LOST,
+ BUF_HWCB_CHAR_LOST);
+
+ return retval;
+}
+
+static int
+allocate_write_hwcb (void)
+{
+ unsigned char *page;
+ int page_nr;
+
+ if (hwc_data.hwcb_count == hwc_data.ioctls.max_hwcb)
+ return -ENOMEM;
+
+ page_nr = find_first_zero_bit (&hwc_data.kmem_pages, MAX_KMEM_PAGES);
+ if (page_nr < hwc_data.ioctls.kmem_hwcb) {
+
+ page = (unsigned char *)
+ (hwc_data.kmem_start + (page_nr << 12));
+ set_bit (page_nr, &hwc_data.kmem_pages);
+ } else
+ page = (unsigned char *) __get_free_page (GFP_ATOMIC);
+
+ if (!page)
+ return -ENOMEM;
+
+ if (!OUT_HWCB)
+ OUT_HWCB = page;
+ else
+ BUF_HWCB_NEXT = page;
+
+ BUF_HWCB = page;
+
+ BUF_HWCB_NEXT = NULL;
+
+ hwc_data.hwcb_count++;
+
+ prepare_write_hwcb ();
+
+ BUF_HWCB_TIMES_LOST = 0;
+ BUF_HWCB_MTO_LOST = 0;
+ BUF_HWCB_CHAR_LOST = 0;
+
+#ifdef BUFFER_STRESS_TEST
+
+ internal_print (
+ DELAYED_WRITE,
+ "*** " HWC_RW_PRINT_HEADER
+ "page #%i at 0x%x for buffering allocated. ***\n",
+ hwc_data.hwcb_count, page);
+
+#endif
+
+ return 0;
+}
+
+static int
+release_write_hwcb (void)
+{
+ unsigned long page;
+ int page_nr;
+
+ if (!hwc_data.hwcb_count)
+ return -ENODATA;
+
+ if (hwc_data.hwcb_count == 1) {
+
+ prepare_write_hwcb ();
+
+ ALL_HWCB_CHAR = 0;
+ ALL_HWCB_MTO = 0;
+ BUF_HWCB_TIMES_LOST = 0;
+ BUF_HWCB_MTO_LOST = 0;
+ BUF_HWCB_CHAR_LOST = 0;
+ } else {
+ page = (unsigned long) OUT_HWCB;
+
+ ALL_HWCB_MTO -= OUT_HWCB_MTO;
+ ALL_HWCB_CHAR -= OUT_HWCB_CHAR;
+ hwc_data.hwcb_count--;
+
+ OUT_HWCB = OUT_HWCB_NEXT;
+
+ if (page >= hwc_data.kmem_start &&
+ page < hwc_data.kmem_end) {
+
+ memset ((void *) page, 0, PAGE_SIZE);
+
+ page_nr = (int) ((page - hwc_data.kmem_start) >> 12);
+ clear_bit (page_nr, &hwc_data.kmem_pages);
+ } else
+ free_page (page);
+#ifdef BUFFER_STRESS_TEST
+
+ internal_print (
+ DELAYED_WRITE,
+ "*** " HWC_RW_PRINT_HEADER
+ "page at 0x%x released, %i pages still in use ***\n",
+ page, hwc_data.hwcb_count);
+
+#endif
+ }
+ return 0;
+}
+
+static int
+add_mto (
+ unsigned char *message,
+ unsigned short int count)
+{
+ unsigned short int mto_size;
+ write_hwcb_t *hwcb;
+ mto_t *mto;
+ void *dest;
+
+ if (!BUF_HWCB)
+ return -ENOMEM;
+
+ if (BUF_HWCB == hwc_data.current_hwcb)
+ return -ENOMEM;
+
+ mto_size = sizeof (mto_t) + count;
+
+ hwcb = (write_hwcb_t *) BUF_HWCB;
+
+ if ((MAX_HWCB_ROOM - hwcb->length) < mto_size)
+ return -ENOMEM;
+
+ mto = (mto_t *) (((unsigned long) hwcb) + hwcb->length);
+
+ memcpy (mto, &mto_template, sizeof (mto_t));
+
+ dest = (void *) (((unsigned long) mto) + sizeof (mto_t));
+
+ memcpy (dest, message, count);
+
+ mto->length += count;
+
+ hwcb->length += mto_size;
+ hwcb->msgbuf.length += mto_size;
+ hwcb->msgbuf.mdb.length += mto_size;
+
+ BUF_HWCB_MTO++;
+ ALL_HWCB_MTO++;
+ BUF_HWCB_CHAR += count;
+ ALL_HWCB_CHAR += count;
+
+ return count;
+}
+
+static int
+write_event_data_1 (void)
+{
+ unsigned short int condition_code;
+ int retval;
+
+ if ((!hwc_data.write_prio) && (!hwc_data.write_nonprio))
+ return -EPERM;
+
+ if (hwc_data.current_servc)
+ return -EBUSY;
+
+ retval = sane_write_hwcb ();
+ if (retval < 0)
+ return retval;
+
+ if (!OUT_HWCB_MTO)
+ return -ENODATA;
+
+ condition_code = service_call (HWC_CMDW_WRITEDATA, OUT_HWCB);
+
+#ifdef DUMP_HWC_WRITE_ERROR
+ if (condition_code != HWC_COMMAND_INITIATED)
+ __asm__ ("LHI 1,0xe20\n\t"
+ "L 2,0(0,%0)\n\t"
+ "LRA 3,0(0,%1)\n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (&condition_code), "a" (OUT_HWCB)
+ : "1", "2", "3");
+#endif
+
+ switch (condition_code) {
+ case HWC_COMMAND_INITIATED:
+ hwc_data.current_servc = HWC_CMDW_WRITEDATA;
+ hwc_data.current_hwcb = OUT_HWCB;
+ retval = condition_code;
+ break;
+ case HWC_BUSY:
+ retval = -EBUSY;
+ break;
+ default:
+ retval = -EIO;
+ }
+
+ return retval;
+}
+
+static void
+flush_hwcbs (void)
+{
+ while (hwc_data.hwcb_count > 1)
+ release_write_hwcb ();
+
+ release_write_hwcb ();
+
+ hwc_data.flags &= ~FLUSH_HWCBS;
+}
+
+static int
+write_event_data_2 (void)
+{
+ write_hwcb_t *hwcb;
+ int retval;
+ unsigned char *param;
+
+ param = ext_int_param ();
+ if (param != hwc_data.current_hwcb)
+ return -EINVAL;
+
+ hwcb = (write_hwcb_t *) OUT_HWCB;
+
+#ifdef DUMP_HWC_WRITE_ERROR
+#if 0
+ if (((unsigned char *) hwcb) != param)
+ __asm__ ("LHI 1,0xe22\n\t"
+ "LRA 2,0(0,%0)\n\t"
+ "LRA 3,0(0,%1)\n\t"
+ "LRA 4,0(0,%2)\n\t"
+ "LRA 5,0(0,%3)\n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (OUT_HWCB),
+ "a" (hwc_data.current_hwcb),
+ "a" (BUF_HWCB),
+ "a" (param)
+ : "1", "2", "3", "4", "5");
+#endif
+ if (hwcb->response_code != 0x0020)
+#if 0
+ internal_print (DELAYED_WRITE, HWC_RW_PRINT_HEADER
+ "\n************************ error in write_event_data_2()\n"
+ "OUT_HWCB: 0x%x\n"
+ "BUF_HWCB: 0x%x\n"
+ "response_code: 0x%x\n"
+ "hwc_data.hwcb_count: %d\n"
+ "hwc_data.kmem_pages: 0x%x\n"
+ "hwc_data.ioctls.kmem_hwcb: %d\n"
+ "hwc_data.ioctls.max_hwcb: %d\n"
+ "hwc_data.kmem_start: 0x%x\n"
+ "hwc_data.kmem_end: 0x%x\n"
+ "*****************************************************\n",
+ OUT_HWCB,
+ BUF_HWCB,
+ hwcb->response_code,
+ hwc_data.hwcb_count,
+ hwc_data.kmem_pages,
+ hwc_data.ioctls.kmem_hwcb,
+ hwc_data.ioctls.max_hwcb,
+ hwc_data.kmem_start,
+ hwc_data.kmem_end);
+#endif
+ __asm__ ("LHI 1,0xe21\n\t"
+ "LRA 2,0(0,%0)\n\t"
+ "LRA 3,0(0,%1)\n\t"
+ "LRA 4,0(0,%2)\n\t"
+ "LH 5,0(0,%3)\n\t"
+ "SRL 5,8(0)\n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (OUT_HWCB), "a" (hwc_data.current_hwcb),
+ "a" (BUF_HWCB),
+ "a" (&(hwc_data.hwcb_count))
+ : "1", "2", "3", "4", "5");
+#endif
+
+ if (hwcb->response_code == 0x0020) {
+
+ retval = OUT_HWCB_CHAR;
+ release_write_hwcb ();
+ } else
+ retval = -EIO;
+
+ hwc_data.current_servc = 0;
+ hwc_data.current_hwcb = NULL;
+
+ if (hwc_data.flags & FLUSH_HWCBS)
+ flush_hwcbs ();
+
+ return retval;
+}
+
+static void
+do_put_line (
+ unsigned char *message,
+ unsigned short count)
+{
+
+ if (add_mto (message, count) != count) {
+
+ if (allocate_write_hwcb () < 0)
+ reuse_write_hwcb ();
+
+#ifdef DUMP_HWC_WRITE_LIST_ERROR
+ if (add_mto (message, count) != count)
+ __asm__ ("LHI 1,0xe32\n\t"
+ "LRA 2,0(0,%0)\n\t"
+ "L 3,0(0,%1)\n\t"
+ "LRA 4,0(0,%2)\n\t"
+ "LRA 5,0(0,%3)\n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (message), "a" (&hwc_data.kmem_pages),
+ "a" (BUF_HWCB), "a" (OUT_HWCB)
+ : "1", "2", "3", "4", "5");
+#else
+ add_mto (message, count);
+#endif
+ }
+}
+
+static void
+put_line (
+ unsigned char *message,
+ unsigned short count)
+{
+
+ if ((!hwc_data.obuf_start) && (hwc_data.flags & HWC_TIMER_RUNS)) {
+ del_timer (&hwc_data.write_timer);
+ hwc_data.flags &= ~HWC_TIMER_RUNS;
+ }
+ hwc_data.obuf_start += count;
+
+ do_put_line (message, count);
+
+ hwc_data.obuf_start -= count;
+}
+
+static void
+set_alarm (void)
+{
+ write_hwcb_t *hwcb;
+
+ if ((!BUF_HWCB) || (BUF_HWCB == hwc_data.current_hwcb))
+ allocate_write_hwcb ();
+
+ hwcb = (write_hwcb_t *) BUF_HWCB;
+ hwcb->msgbuf.mdb.mdb_body.go.general_msg_flags |= GMF_SndAlrm;
+}
+
+static void
+hwc_write_timeout (unsigned long data)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ hwc_data.obuf_start = hwc_data.obuf_count;
+ if (hwc_data.obuf_count)
+ put_line (hwc_data.obuf, hwc_data.obuf_count);
+ hwc_data.obuf_start = 0;
+
+ hwc_data.obuf_cursor = 0;
+ hwc_data.obuf_count = 0;
+
+ write_event_data_1 ();
+
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+}
+
+static int
+do_hwc_write (
+ int from_user,
+ unsigned char *msg,
+ unsigned int count,
+ unsigned char code,
+ unsigned char write_time)
+{
+ unsigned int i_msg = 0;
+ unsigned short int spaces = 0;
+ unsigned int processed_characters = 0;
+ unsigned char ch, orig_ch;
+ unsigned short int obuf_count;
+ unsigned short int obuf_cursor;
+ unsigned short int obuf_columns;
+
+ if (hwc_data.obuf_start) {
+ obuf_cursor = 0;
+ obuf_count = 0;
+ obuf_columns = MIN (hwc_data.ioctls.columns,
+ MAX_MESSAGE_SIZE - hwc_data.obuf_start);
+ } else {
+ obuf_cursor = hwc_data.obuf_cursor;
+ obuf_count = hwc_data.obuf_count;
+ obuf_columns = hwc_data.ioctls.columns;
+ }
+
+ for (i_msg = 0; i_msg < count; i_msg++) {
+
+ if (from_user)
+ get_user (orig_ch, msg + i_msg);
+ else
+ orig_ch = msg[i_msg];
+ if (code == CODE_EBCDIC)
+ ch = _ebcasc[orig_ch];
+ else
+ ch = orig_ch;
+
+ processed_characters++;
+
+ if ((obuf_cursor == obuf_columns) &&
+
+ (ch != '\n') &&
+
+ (ch != '\t')) {
+ put_line (&hwc_data.obuf[hwc_data.obuf_start],
+ obuf_columns);
+ obuf_cursor = 0;
+ obuf_count = 0;
+ }
+ switch (ch) {
+
+ case '\n':
+
+ put_line (&hwc_data.obuf[hwc_data.obuf_start],
+ obuf_count);
+ obuf_cursor = 0;
+ obuf_count = 0;
+ break;
+
+ case '\a':
+
+ hwc_data.obuf_start += obuf_count;
+ set_alarm ();
+ hwc_data.obuf_start -= obuf_count;
+
+ break;
+
+ case '\t':
+
+ do {
+ if (obuf_cursor < obuf_columns) {
+ hwc_data.obuf[hwc_data.obuf_start +
+ obuf_cursor]
+ = 0x20;
+ obuf_cursor++;
+ } else
+ break;
+ } while (obuf_cursor % hwc_data.ioctls.width_htab);
+
+ break;
+
+ case '\f':
+ case '\v':
+
+ spaces = obuf_cursor;
+ put_line (&hwc_data.obuf[hwc_data.obuf_start],
+ obuf_count);
+ obuf_count = obuf_cursor;
+ while (spaces) {
+ hwc_data.obuf[hwc_data.obuf_start +
+ obuf_cursor - spaces]
+ = 0x20;
+ spaces--;
+ }
+
+ break;
+
+ case '\b':
+
+ if (obuf_cursor)
+ obuf_cursor--;
+ break;
+
+ case '\r':
+
+ obuf_cursor = 0;
+ break;
+
+ case 0x00:
+
+ put_line (&hwc_data.obuf[hwc_data.obuf_start],
+ obuf_count);
+ obuf_cursor = 0;
+ obuf_count = 0;
+ goto out;
+
+ default:
+
+ if (isprint (ch))
+ hwc_data.obuf[hwc_data.obuf_start +
+ obuf_cursor++]
+ = (code == CODE_ASCII) ?
+ _ascebc[orig_ch] : orig_ch;
+ }
+ if (obuf_cursor > obuf_count)
+ obuf_count = obuf_cursor;
+ }
+
+ if (obuf_cursor) {
+
+ if (hwc_data.obuf_start ||
+ (hwc_data.ioctls.final_nl == 0)) {
+
+ put_line (&hwc_data.obuf[hwc_data.obuf_start],
+ obuf_count);
+ obuf_cursor = 0;
+ obuf_count = 0;
+ } else {
+
+ if (hwc_data.ioctls.final_nl > 0) {
+
+ if (hwc_data.flags & HWC_TIMER_RUNS) {
+
+ hwc_data.write_timer.expires =
+ jiffies +
+ hwc_data.ioctls.final_nl * HZ / 10;
+ } else {
+
+ init_timer (&hwc_data.write_timer);
+ hwc_data.write_timer.function =
+ hwc_write_timeout;
+ hwc_data.write_timer.data =
+ (unsigned long) NULL;
+ hwc_data.write_timer.expires =
+ jiffies +
+ hwc_data.ioctls.final_nl * HZ / 10;
+ add_timer (&hwc_data.write_timer);
+ hwc_data.flags |= HWC_TIMER_RUNS;
+ }
+ } else;
+
+ }
+ } else;
+
+ out:
+
+ if (!hwc_data.obuf_start) {
+ hwc_data.obuf_cursor = obuf_cursor;
+ hwc_data.obuf_count = obuf_count;
+ }
+ if (write_time == IMMEDIATE_WRITE)
+ write_event_data_1 ();
+
+ return processed_characters;
+}
+
+signed int
+hwc_write (int from_user, const unsigned char *msg, unsigned int count)
+{
+ unsigned long flags;
+ int retval;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ retval = do_hwc_write (from_user, msg, count, hwc_data.ioctls.code,
+ IMMEDIATE_WRITE);
+
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+
+ return retval;
+}
+
+unsigned int
+hwc_chars_in_buffer (unsigned char flag)
+{
+ unsigned short int number = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ if (flag & IN_HWCB)
+ number += ALL_HWCB_CHAR;
+
+ if (flag & IN_WRITE_BUF)
+ number += hwc_data.obuf_cursor;
+
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+
+ return number;
+}
+
+static inline int
+nr_setbits (kmem_pages_t arg)
+{
+ int i;
+ int nr = 0;
+
+ for (i = 0; i < (sizeof (arg) << 3); i++) {
+ if (arg & 1)
+ nr++;
+ arg >>= 1;
+ }
+
+ return nr;
+}
+
+unsigned int
+hwc_write_room (unsigned char flag)
+{
+ unsigned int number = 0;
+ unsigned long flags;
+ write_hwcb_t *hwcb;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ if (flag & IN_HWCB) {
+
+ if (BUF_HWCB) {
+ hwcb = (write_hwcb_t *) BUF_HWCB;
+ number += MAX_HWCB_ROOM - hwcb->length;
+ }
+ number += (hwc_data.ioctls.kmem_hwcb -
+ nr_setbits (hwc_data.kmem_pages)) *
+ (MAX_HWCB_ROOM -
+ (sizeof (write_hwcb_t) + sizeof (mto_t)));
+ }
+ if (flag & IN_WRITE_BUF)
+ number += MAX_HWCB_ROOM - hwc_data.obuf_cursor;
+
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+
+ return number;
+}
+
+void
+hwc_flush_buffer (unsigned char flag)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ if (flag & IN_HWCB) {
+ if (hwc_data.current_servc != HWC_CMDW_WRITEDATA)
+ flush_hwcbs ();
+ else
+ hwc_data.flags |= FLUSH_HWCBS;
+ }
+ if (flag & IN_WRITE_BUF) {
+ hwc_data.obuf_cursor = 0;
+ hwc_data.obuf_count = 0;
+ }
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+}
+
+unsigned short int
+seperate_cases (unsigned char *buf, unsigned short int count)
+{
+
+ unsigned short int i_in;
+
+ unsigned short int i_out = 0;
+
+ unsigned char _case = 0;
+
+ for (i_in = 0; i_in < count; i_in++) {
+
+ if (buf[i_in] == hwc_data.ioctls.delim) {
+
+ if ((i_in + 1 < count) &&
+ (buf[i_in + 1] == hwc_data.ioctls.delim)) {
+
+ buf[i_out] = hwc_data.ioctls.delim;
+
+ i_out++;
+
+ i_in++;
+
+ } else
+ _case = ~_case;
+
+ } else {
+
+ if (_case) {
+
+ if (hwc_data.ioctls.tolower)
+ buf[i_out] = _ebc_toupper[buf[i_in]];
+
+ else
+ buf[i_out] = _ebc_tolower[buf[i_in]];
+
+ } else
+ buf[i_out] = buf[i_in];
+
+ i_out++;
+ }
+ }
+
+ return i_out;
+}
+
+#ifdef DUMP_HWCB_INPUT
+
+static int
+gds_vector_name (u16 id, unsigned char name[])
+{
+ int retval = 0;
+
+ switch (id) {
+ case GDS_ID_MDSMU:
+ name = "Multiple Domain Support Message Unit";
+ break;
+ case GDS_ID_MDSRouteInfo:
+ name = "MDS Routing Information";
+ break;
+ case GDS_ID_AgUnWrkCorr:
+ name = "Agent Unit of Work Correlator";
+ break;
+ case GDS_ID_SNACondReport:
+ name = "SNA Condition Report";
+ break;
+ case GDS_ID_CPMSU:
+ name = "CP Management Services Unit";
+ break;
+ case GDS_ID_RoutTargInstr:
+ name = "Routing and Targeting Instructions";
+ break;
+ case GDS_ID_OpReq:
+ name = "Operate Request";
+ break;
+ case GDS_ID_TextCmd:
+ name = "Text Command";
+ break;
+
+ default:
+ name = "unknown GDS variable";
+ retval = -EINVAL;
+ }
+
+ return retval;
+}
+#endif
+
+inline static gds_vector_t *
+find_gds_vector (
+ gds_vector_t * start, void *end, u16 id)
+{
+ gds_vector_t *vec;
+ gds_vector_t *retval = NULL;
+
+ vec = start;
+
+ while (((void *) vec) < end) {
+ if (vec->gds_id == id) {
+
+#ifdef DUMP_HWCB_INPUT
+ int retval_name;
+ unsigned char name[64];
+
+ retval_name = gds_vector_name (id, name);
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "%s at 0x%x up to 0x%x, length: %d",
+ name,
+ (unsigned long) vec,
+ ((unsigned long) vec) + vec->length - 1,
+ vec->length);
+ if (retval_name < 0)
+ internal_print (
+ IMMEDIATE_WRITE,
+ ", id: 0x%x\n",
+ vec->gds_id);
+ else
+ internal_print (
+ IMMEDIATE_WRITE,
+ "\n");
+#endif
+
+ retval = vec;
+ break;
+ }
+ vec = (gds_vector_t *) (((unsigned long) vec) + vec->length);
+ }
+
+ return retval;
+}
+
+inline static gds_subvector_t *
+find_gds_subvector (
+ gds_subvector_t * start, void *end, u8 key)
+{
+ gds_subvector_t *subvec;
+ gds_subvector_t *retval = NULL;
+
+ subvec = start;
+
+ while (((void *) subvec) < end) {
+ if (subvec->key == key) {
+ retval = subvec;
+ break;
+ }
+ subvec = (gds_subvector_t *)
+ (((unsigned long) subvec) + subvec->length);
+ }
+
+ return retval;
+}
+
+inline static int
+get_input (void *start, void *end)
+{
+ int count;
+
+ count = ((unsigned long) end) - ((unsigned long) start);
+
+ if (hwc_data.ioctls.tolower)
+ EBC_TOLOWER (start, count);
+
+ if (hwc_data.ioctls.delim)
+ count = seperate_cases (start, count);
+
+ if (hwc_data.ioctls.echo)
+ do_hwc_write (0, start, count, CODE_EBCDIC, IMMEDIATE_WRITE);
+
+ if (hwc_data.ioctls.code == CODE_ASCII)
+ EBCASC (start, count);
+
+ store_hwc_input (start, count);
+
+ return count;
+}
+
+inline static int
+eval_selfdeftextmsg (gds_subvector_t * start, void *end)
+{
+ gds_subvector_t *subvec;
+ void *subvec_data;
+ void *subvec_end;
+ int retval = 0;
+
+ subvec = start;
+
+ while (((void *) subvec) < end) {
+ subvec = find_gds_subvector (subvec, end, 0x30);
+ if (!subvec)
+ break;
+ subvec_data = (void *)
+ (((unsigned long) subvec) +
+ sizeof (gds_subvector_t));
+ subvec_end = (void *)
+ (((unsigned long) subvec) + subvec->length);
+ retval += get_input (subvec_data, subvec_end);
+ subvec = (gds_subvector_t *) subvec_end;
+ }
+
+ return retval;
+}
+
+inline static int
+eval_textcmd (gds_subvector_t * start, void *end)
+{
+ gds_subvector_t *subvec;
+ gds_subvector_t *subvec_data;
+ void *subvec_end;
+ int retval = 0;
+
+ subvec = start;
+
+ while (((void *) subvec) < end) {
+ subvec = find_gds_subvector (
+ subvec, end, GDS_KEY_SelfDefTextMsg);
+ if (!subvec)
+ break;
+ subvec_data = (gds_subvector_t *)
+ (((unsigned long) subvec) +
+ sizeof (gds_subvector_t));
+ subvec_end = (void *)
+ (((unsigned long) subvec) + subvec->length);
+ retval += eval_selfdeftextmsg (subvec_data, subvec_end);
+ subvec = (gds_subvector_t *) subvec_end;
+ }
+
+ return retval;
+}
+
+inline static int
+eval_cpmsu (gds_vector_t * start, void *end)
+{
+ gds_vector_t *vec;
+ gds_subvector_t *vec_data;
+ void *vec_end;
+ int retval = 0;
+
+ vec = start;
+
+ while (((void *) vec) < end) {
+ vec = find_gds_vector (vec, end, GDS_ID_TextCmd);
+ if (!vec)
+ break;
+ vec_data = (gds_subvector_t *)
+ (((unsigned long) vec) + sizeof (gds_vector_t));
+ vec_end = (void *) (((unsigned long) vec) + vec->length);
+ retval += eval_textcmd (vec_data, vec_end);
+ vec = (gds_vector_t *) vec_end;
+ }
+
+ return retval;
+}
+
+inline static int
+eval_mdsmu (gds_vector_t * start, void *end)
+{
+ gds_vector_t *vec;
+ gds_vector_t *vec_data;
+ void *vec_end;
+ int retval = 0;
+
+ vec = find_gds_vector (start, end, GDS_ID_CPMSU);
+ if (vec) {
+ vec_data = (gds_vector_t *)
+ (((unsigned long) vec) + sizeof (gds_vector_t));
+ vec_end = (void *) (((unsigned long) vec) + vec->length);
+ retval = eval_cpmsu (vec_data, vec_end);
+ }
+ return retval;
+}
+
+inline static int
+eval_evbuf (gds_vector_t * start, void *end)
+{
+ gds_vector_t *vec;
+ gds_vector_t *vec_data;
+ void *vec_end;
+ int retval = 0;
+
+ vec = find_gds_vector (start, end, GDS_ID_MDSMU);
+ if (vec) {
+ vec_data = (gds_vector_t *)
+ (((unsigned long) vec) + sizeof (gds_vector_t));
+ vec_end = (void *) (((unsigned long) vec) + vec->length);
+ retval = eval_mdsmu (vec_data, vec_end);
+ }
+ return retval;
+}
+
+static int
+process_evbufs (void *start, void *end)
+{
+ int retval = 0;
+ evbuf_t *evbuf;
+ void *evbuf_end;
+ gds_vector_t *evbuf_data;
+
+ evbuf = (evbuf_t *) start;
+ while (((void *) evbuf) < end) {
+ evbuf_data = (gds_vector_t *)
+ (((unsigned long) evbuf) + sizeof (evbuf_t));
+ evbuf_end = (void *) (((unsigned long) evbuf) + evbuf->length);
+ switch (evbuf->type) {
+ case ET_OpCmd:
+ case ET_CntlProgOpCmd:
+ case ET_PMsgCmd:
+#ifdef DUMP_HWCB_INPUT
+
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "event buffer "
+ "at 0x%x up to 0x%x, length: %d\n",
+ (unsigned long) evbuf,
+ (unsigned long) (evbuf_end - 1),
+ evbuf->length);
+ dump_storage_area ((void *) evbuf, evbuf->length);
+#endif
+ retval += eval_evbuf (evbuf_data, evbuf_end);
+ break;
+ case ET_StateChange:
+
+ retval = -ENOSYS;
+ break;
+ default:
+ printk (
+ KERN_WARNING
+ HWC_RW_PRINT_HEADER
+ "unconditional read: "
+ "unknown event buffer found, "
+ "type 0x%x",
+ evbuf->type);
+ retval = -ENOSYS;
+ }
+ evbuf = (evbuf_t *) evbuf_end;
+ }
+ return retval;
+}
+
+static int
+unconditional_read_1 (void)
+{
+ unsigned short int condition_code;
+ read_hwcb_t *hwcb = (read_hwcb_t *) hwc_data.page;
+ int retval;
+
+ if ((!hwc_data.read_prio) && (!hwc_data.read_nonprio))
+ return -EOPNOTSUPP;
+
+ if (hwc_data.current_servc)
+ return -EBUSY;
+
+ memset (hwcb, 0x00, PAGE_SIZE);
+ memcpy (hwcb, &read_hwcb_template, sizeof (read_hwcb_t));
+
+ condition_code = service_call (HWC_CMDW_READDATA, hwc_data.page);
+
+#ifdef DUMP_HWC_READ_ERROR
+ if (condition_code == HWC_NOT_OPERATIONAL)
+ __asm__ ("LHI 1,0xe40\n\t"
+ "L 2,0(0,%0)\n\t"
+ "LRA 3,0(0,%1)\n\t"
+ "J .+0 \n\t"
+ :
+ : "a" (&condition_code), "a" (hwc_data.page)
+ : "1", "2", "3");
+#endif
+
+ switch (condition_code) {
+ case HWC_COMMAND_INITIATED:
+ hwc_data.current_servc = HWC_CMDW_READDATA;
+ hwc_data.current_hwcb = hwc_data.page;
+ retval = condition_code;
+ break;
+ case HWC_BUSY:
+ retval = -EBUSY;
+ break;
+ default:
+ retval = -EIO;
+ }
+
+ return retval;
+}
+
+static int
+unconditional_read_2 (void)
+{
+ read_hwcb_t *hwcb = (read_hwcb_t *) hwc_data.page;
+
+#ifdef DUMP_HWC_READ_ERROR
+ if ((hwcb->response_code != 0x0020) &&
+ (hwcb->response_code != 0x0220) &&
+ (hwcb->response_code != 0x60F0) &&
+ (hwcb->response_code != 0x62F0))
+ __asm__ ("LHI 1,0xe41\n\t"
+ "LRA 2,0(0,%0)\n\t"
+ "L 3,0(0,%1)\n\t"
+ "J .+0\n\t"
+ :
+ : "a" (hwc_data.page), "a" (&(hwcb->response_code))
+ : "1", "2", "3");
+#endif
+
+ hwc_data.current_servc = 0;
+ hwc_data.current_hwcb = NULL;
+
+ switch (hwcb->response_code) {
+
+ case 0x0020:
+ case 0x0220:
+ return process_evbufs (
+ (void *) (((unsigned long) hwcb) + sizeof (read_hwcb_t)),
+ (void *) (((unsigned long) hwcb) + hwcb->length));
+
+ case 0x60F0:
+ case 0x62F0:
+ return 0;
+
+ case 0x0100:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: HWCB boundary violation - this "
+ "must not occur in a correct driver, please contact "
+ "author\n");
+ return -EIO;
+
+ case 0x0300:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: "
+ "insufficient HWCB length - this must not occur in a "
+ "correct driver, please contact author\n");
+ return -EIO;
+
+ case 0x01F0:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: "
+ "invalid command - this must not occur in a correct "
+ "driver, please contact author\n");
+ return -EIO;
+
+ case 0x40F0:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: invalid function code - this "
+ "must not occur in a correct driver, please contact "
+ "author\n");
+ return -EIO;
+
+ case 0x70F0:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: invalid selection mask - this "
+ "must not occur in a correct driver, please contact "
+ "author\n");
+ return -EIO;
+
+ case 0x0040:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: HWC equipment check - don't "
+ "know how to handle this case\n");
+ return -EIO;
+
+ default:
+ internal_print (
+ IMMEDIATE_WRITE,
+ HWC_RW_PRINT_HEADER
+ "unconditional read: invalid response code %x - this "
+ "must not occur in a correct driver, please contact "
+ "author\n",
+ hwcb->response_code);
+ return -EIO;
+ }
+}
+
+static int
+write_event_mask_1 (void)
+{
+ unsigned int condition_code;
+ int retval;
+
+ memcpy (hwc_data.page, &init_hwcb_template, sizeof (init_hwcb_t));
+
+ condition_code = service_call (HWC_CMDW_WRITEMASK, hwc_data.page);
+
+#ifdef DUMP_HWC_INIT_ERROR
+
+ if (condition_code != HWC_COMMAND_INITIATED)
+ __asm__ ("LHI 1,0xe10\n\t"
+ "L 2,0(0,%0)\n\t"
+ "LRA 3,0(0,%1)\n\t"
+ "J .+0\n\t"
+ :
+ : "a" (&condition_code), "a" (hwc_data.page)
+ : "1", "2", "3");
+#endif
+
+ switch (condition_code) {
+ case HWC_COMMAND_INITIATED:
+ hwc_data.current_servc = HWC_CMDW_WRITEMASK;
+ hwc_data.current_hwcb = hwc_data.page;
+ retval = condition_code;
+ break;
+ case HWC_BUSY:
+ retval = -EBUSY;
+ break;
+ default:
+ retval = -EIO;
+ }
+
+ return retval;
+}
+
+static int
+write_event_mask_2 (void)
+{
+ init_hwcb_t *hwcb = (init_hwcb_t *) hwc_data.page;
+ int retval = 0;
+
+ if (hwcb->hwc_receive_mask & ET_Msg_Mask)
+ hwc_data.write_nonprio = 1;
+
+ if (hwcb->hwc_receive_mask & ET_PMsgCmd_Mask)
+ hwc_data.write_prio = 1;
+
+ if (hwcb->hwc_send_mask & ET_OpCmd_Mask)
+ hwc_data.read_nonprio = 1;
+
+ if (hwcb->hwc_send_mask & ET_PMsgCmd_Mask)
+ hwc_data.read_nonprio = 1;
+
+ if ((hwcb->response_code != 0x0020) ||
+ (!hwc_data.write_nonprio) ||
+ ((!hwc_data.read_nonprio) && (!hwc_data.read_prio)))
+#ifdef DUMP_HWC_INIT_ERROR
+ __asm__ ("LHI 1,0xe11\n\t"
+ "LRA 2,0(0,%0)\n\t"
+ "L 3,0(0,%1)\n\t"
+ "J .+0\n\t"
+ :
+ : "a" (hwcb), "a" (&(hwcb->response_code))
+ : "1", "2", "3");
+#else
+ retval = -EIO
+#endif
+
+ hwc_data.current_servc = 0;
+ hwc_data.current_hwcb = NULL;
+
+ return retval;
+}
+
+static int
+set_hwc_ioctls (hwc_ioctls_t * ioctls, char correct)
+{
+ int retval = 0;
+ hwc_ioctls_t tmp;
+
+ if (ioctls->width_htab > MAX_MESSAGE_SIZE) {
+ if (correct)
+ tmp.width_htab = MAX_MESSAGE_SIZE;
+ else
+ retval = -EINVAL;
+ } else
+ tmp.width_htab = ioctls->width_htab;
+
+ tmp.echo = ioctls->echo;
+
+ if (ioctls->columns > MAX_MESSAGE_SIZE) {
+ if (correct)
+ tmp.columns = MAX_MESSAGE_SIZE;
+ else
+ retval = -EINVAL;
+ } else
+ tmp.columns = ioctls->columns;
+
+ switch (ioctls->code) {
+ case CODE_EBCDIC:
+ case CODE_ASCII:
+ tmp.code = ioctls->code;
+ break;
+ default:
+ if (correct)
+ tmp.code = CODE_ASCII;
+ else
+ retval = -EINVAL;
+ }
+
+ tmp.final_nl = ioctls->final_nl;
+
+ if (ioctls->max_hwcb < 2) {
+ if (correct)
+ tmp.max_hwcb = 2;
+ else
+ retval = -EINVAL;
+ } else
+ tmp.max_hwcb = ioctls->max_hwcb;
+
+ tmp.tolower = ioctls->tolower;
+
+ if (ioctls->kmem_hwcb > ioctls->max_hwcb) {
+ if (correct)
+ tmp.kmem_hwcb = ioctls->max_hwcb;
+ else
+ retval = -EINVAL;
+ } else
+ tmp.kmem_hwcb = ioctls->kmem_hwcb;
+
+ if (ioctls->kmem_hwcb > MAX_KMEM_PAGES) {
+ if (correct)
+ ioctls->kmem_hwcb = MAX_KMEM_PAGES;
+ else
+ retval = -EINVAL;
+ }
+ if (ioctls->kmem_hwcb < 2) {
+ if (correct)
+ ioctls->kmem_hwcb = 2;
+ else
+ retval = -EINVAL;
+ }
+ tmp.delim = ioctls->delim;
+
+ if (!(retval < 0))
+ hwc_data.ioctls = tmp;
+
+ return retval;
+}
+
+int
+hwc_init (void)
+{
+ int retval;
+#ifdef BUFFER_STRESS_TEST
+
+ init_hwcb_t *hwcb;
+ int i;
+
+#endif
+
+#ifdef CONFIG_3215
+ if (MACHINE_IS_VM)
+ return 0;
+#endif
+
+ spin_lock_init (&hwc_data.lock);
+
+ retval = write_event_mask_1 ();
+ if (retval < 0)
+ return retval;
+
+#ifdef USE_VM_DETECTION
+
+ if (MACHINE_IS_VM) {
+
+ if (hwc_data.init_ioctls.columns > 76)
+ hwc_data.init_ioctls.columns = 76;
+ hwc_data.init_ioctls.tolower = 1;
+ if (!hwc_data.init_ioctls.delim)
+ hwc_data.init_ioctls.delim = DEFAULT_CASE_DELIMITER;
+ } else {
+ hwc_data.init_ioctls.tolower = 0;
+ hwc_data.init_ioctls.delim = 0;
+ }
+#endif
+ retval = set_hwc_ioctls (&hwc_data.init_ioctls, 1);
+
+ hwc_data.kmem_start = (unsigned long)
+ alloc_bootmem_pages (hwc_data.ioctls.kmem_hwcb * PAGE_SIZE);
+ hwc_data.kmem_end = hwc_data.kmem_start +
+ hwc_data.ioctls.kmem_hwcb * PAGE_SIZE - 1;
+
+ ctl_set_bit (0, 9);
+
+#ifdef BUFFER_STRESS_TEST
+
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "use %i bytes for buffering.\n",
+ hwc_data.ioctls.kmem_hwcb * PAGE_SIZE);
+ for (i = 0; i < 500; i++) {
+ hwcb = (init_hwcb_t *) BUF_HWCB;
+ internal_print (
+ DELAYED_WRITE,
+ HWC_RW_PRINT_HEADER
+ "This is stress test message #%i, free: %i bytes\n",
+ i,
+ MAX_HWCB_ROOM - (hwcb->length + sizeof (mto_t)));
+ }
+
+#endif
+
+ return retval;
+}
+
+void
+do_hwc_interrupt (void)
+{
+
+ spin_lock (&hwc_data.lock);
+
+ if (!hwc_data.current_servc) {
+
+ unconditional_read_1 ();
+
+ } else {
+
+ switch (hwc_data.current_servc) {
+
+ case HWC_CMDW_WRITEMASK:
+
+ write_event_mask_2 ();
+ break;
+
+ case HWC_CMDW_WRITEDATA:
+
+ write_event_data_2 ();
+ break;
+
+ case HWC_CMDW_READDATA:
+
+ unconditional_read_2 ();
+ break;
+ }
+
+ write_event_data_1 ();
+ }
+
+ wake_up_hwc_tty ();
+
+ spin_unlock (&hwc_data.lock);
+}
+
+int
+hwc_ioctl (unsigned int cmd, unsigned long arg)
+{
+ hwc_ioctls_t tmp = hwc_data.ioctls;
+ int retval = 0;
+ unsigned long flags;
+ unsigned int obuf;
+
+ spin_lock_irqsave (&hwc_data.lock, flags);
+
+ switch (cmd) {
+
+ case TIOCHWCSHTAB:
+ if (get_user (tmp.width_htab, (ioctl_htab_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCSECHO:
+ if (get_user (tmp.echo, (ioctl_echo_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCSCOLS:
+ if (get_user (tmp.columns, (ioctl_cols_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCSCODE:
+ if (get_user (tmp.code, (ioctl_code_t *) arg))
+ goto fault;
+
+ break;
+
+ case TIOCHWCSNL:
+ if (get_user (tmp.final_nl, (ioctl_nl_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCSOBUF:
+ if (get_user (obuf, (unsigned int *) arg))
+ goto fault;
+ if (obuf & 0xFFF)
+ tmp.max_hwcb = (((obuf | 0xFFF) + 1) >> 12);
+ else
+ tmp.max_hwcb = (obuf >> 12);
+ break;
+
+ case TIOCHWCSCASE:
+ if (get_user (tmp.tolower, (ioctl_case_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCSDELIM:
+ if (get_user (tmp.delim, (ioctl_delim_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCSINIT:
+ retval = set_hwc_ioctls (&hwc_data.init_ioctls, 1);
+ break;
+
+ case TIOCHWCGHTAB:
+ if (put_user (tmp.width_htab, (ioctl_htab_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGECHO:
+ if (put_user (tmp.echo, (ioctl_echo_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGCOLS:
+ if (put_user (tmp.columns, (ioctl_cols_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGCODE:
+ if (put_user (tmp.code, (ioctl_code_t *) arg))
+ goto fault;
+
+ break;
+
+ case TIOCHWCGNL:
+ if (put_user (tmp.final_nl, (ioctl_nl_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGOBUF:
+ if (put_user (tmp.max_hwcb, (ioctl_obuf_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGKBUF:
+ if (put_user (tmp.kmem_hwcb, (ioctl_obuf_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGCASE:
+ if (put_user (tmp.tolower, (ioctl_case_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGDELIM:
+ if (put_user (tmp.delim, (ioctl_delim_t *) arg))
+ goto fault;
+ break;
+#if 0
+
+ case TIOCHWCGINIT:
+ if (put_user (&hwc_data.init_ioctls, (hwc_ioctls_t *) arg))
+ goto fault;
+ break;
+
+ case TIOCHWCGCURR:
+ if (put_user (&hwc_data.ioctls, (hwc_ioctls_t *) arg))
+ goto fault;
+ break;
+#endif
+
+ default:
+ goto noioctlcmd;
+ }
+
+ if (_IOC_DIR (cmd) == _IOC_WRITE)
+ retval = set_hwc_ioctls (&tmp, 0);
+
+ goto out;
+
+ fault:
+ retval = -EFAULT;
+ goto out;
+ noioctlcmd:
+ retval = -ENOIOCTLCMD;
+ out:
+ spin_unlock_irqrestore (&hwc_data.lock, flags);
+ return retval;
+}
diff --git a/drivers/s390/char/hwc_rw.h b/drivers/s390/char/hwc_rw.h
new file mode 100644
index 000000000..04c939cd8
--- /dev/null
+++ b/drivers/s390/char/hwc_rw.h
@@ -0,0 +1,113 @@
+/*
+ * drivers/s390/char/hwc_rw.h
+ * interface to the HWC-read/write driver
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Peschke <peschke@fh-brandenburg.de>
+ */
+
+#ifndef __HWC_RW_H__
+#define __HWC_RW_H__
+
+#include <linux/ioctl.h>
+
+#ifndef __HWC_RW_C__
+
+extern int hwc_init (void);
+
+extern int hwc_write (int from_user, const unsigned char *, unsigned int);
+
+extern unsigned int hwc_chars_in_buffer (unsigned char);
+
+extern unsigned int hwc_write_room (unsigned char);
+
+extern void hwc_flush_buffer (unsigned char);
+
+extern signed int hwc_ioctl (unsigned int, unsigned long);
+
+extern void do_hwc_interrupt (void);
+
+extern int hwc_printk (const char *,...);
+
+#else
+
+extern void store_hwc_input (unsigned char *, unsigned int);
+
+extern void wake_up_hwc_tty (void);
+
+#endif
+
+#define IN_HWCB 1
+#define IN_WRITE_BUF 2
+#define IN_BUFS_TOTAL (IN_HWCB | IN_WRITE_BUF)
+
+typedef unsigned short int ioctl_htab_t;
+typedef unsigned char ioctl_echo_t;
+typedef unsigned short int ioctl_cols_t;
+typedef unsigned char ioctl_code_t;
+typedef signed char ioctl_nl_t;
+typedef unsigned short int ioctl_obuf_t;
+typedef unsigned char ioctl_case_t;
+typedef unsigned char ioctl_delim_t;
+
+typedef struct {
+ ioctl_htab_t width_htab;
+ ioctl_echo_t echo;
+ ioctl_cols_t columns;
+ ioctl_code_t code;
+ ioctl_nl_t final_nl;
+ ioctl_obuf_t max_hwcb;
+ ioctl_obuf_t kmem_hwcb;
+ ioctl_case_t tolower;
+ ioctl_delim_t delim;
+} hwc_ioctls_t;
+
+static hwc_ioctls_t _hwc_ioctls;
+
+#define HWC_IOCTL_LETTER 'B'
+
+#define TIOCHWCSHTAB _IOW(HWC_IOCTL_LETTER, 0, _hwc_ioctls.width_htab)
+
+#define TIOCHWCSECHO _IOW(HWC_IOCTL_LETTER, 1, _hwc_ioctls.echo)
+
+#define TIOCHWCSCOLS _IOW(HWC_IOCTL_LETTER, 2, _hwc_ioctls.columns)
+
+#define TIOCHWCSCODE _IOW(HWC_IOCTL_LETTER, 3, _hwc_ioctls.code)
+
+#define TIOCHWCSNL _IOW(HWC_IOCTL_LETTER, 4, _hwc_ioctls.final_nl)
+
+#define TIOCHWCSOBUF _IOW(HWC_IOCTL_LETTER, 5, _hwc_ioctls.max_hwcb)
+
+#define TIOCHWCSINIT _IO(HWC_IOCTL_LETTER, 6)
+
+#define TIOCHWCSCASE _IOW(HWC_IOCTL_LETTER, 7, _hwc_ioctls.tolower)
+
+#define TIOCHWCSDELIM _IOW(HWC_IOCTL_LETTER, 9, _hwc_ioctls.delim)
+
+#define TIOCHWCGHTAB _IOR(HWC_IOCTL_LETTER, 10, _hwc_ioctls.width_htab)
+
+#define TIOCHWCGECHO _IOR(HWC_IOCTL_LETTER, 11, _hwc_ioctls.echo)
+
+#define TIOCHWCGCOLS _IOR(HWC_IOCTL_LETTER, 12, _hwc_ioctls.columns)
+
+#define TIOCHWCGCODE _IOR(HWC_IOCTL_LETTER, 13, _hwc_ioctls.code)
+
+#define TIOCHWCGNL _IOR(HWC_IOCTL_LETTER, 14, _hwc_ioctls.final_nl)
+
+#define TIOCHWCGOBUF _IOR(HWC_IOCTL_LETTER, 15, _hwc_ioctls.max_hwcb)
+
+#define TIOCHWCGINIT _IOR(HWC_IOCTL_LETTER, 16, _hwc_ioctls)
+
+#define TIOCHWCGCASE _IOR(HWC_IOCTL_LETTER, 17, _hwc_ioctls.tolower)
+
+#define TIOCHWCGDELIM _IOR(HWC_IOCTL_LETTER, 19, _hwc_ioctls.delim)
+
+#define TIOCHWCGKBUF _IOR(HWC_IOCTL_LETTER, 20, _hwc_ioctls.max_hwcb)
+
+#define TIOCHWCGCURR _IOR(HWC_IOCTL_LETTER, 21, _hwc_ioctls)
+
+#define CODE_ASCII 0x0
+#define CODE_EBCDIC 0x1
+
+#endif
diff --git a/drivers/s390/char/hwc_tty.c b/drivers/s390/char/hwc_tty.c
new file mode 100644
index 000000000..d58504168
--- /dev/null
+++ b/drivers/s390/char/hwc_tty.c
@@ -0,0 +1,265 @@
+/*
+ * drivers/s390/char/hwc_tty.c
+ * HWC line mode terminal driver.
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Martin Peschke <peschke@fh-brandenburg.de>
+ *
+ * Thanks to Martin Schwidefsky.
+ */
+
+#include <linux/major.h>
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+
+#include <asm/uaccess.h>
+
+#include "hwc_rw.h"
+
+#define HWC_TTY_PRINT_HEADER "hwc tty driver: "
+
+#define HWC_TTY_BUF_SIZE 512
+
+typedef struct {
+
+ struct tty_struct *tty;
+
+ unsigned char buf[HWC_TTY_BUF_SIZE];
+
+ unsigned short int buf_count;
+
+ spinlock_t lock;
+} hwc_tty_data_struct;
+
+static hwc_tty_data_struct hwc_tty_data;
+static struct tty_driver hwc_tty_driver;
+static struct tty_struct *hwc_tty_table[1];
+static struct termios *hwc_tty_termios[1];
+static struct termios *hwc_tty_termios_locked[1];
+static int hwc_tty_refcount = 0;
+
+extern struct termios tty_std_termios;
+
+static int
+hwc_tty_open (struct tty_struct *tty,
+ struct file *filp)
+{
+
+ if (MINOR (tty->device) - tty->driver.minor_start)
+ return -ENODEV;
+
+ tty->driver_data = &hwc_tty_data;
+ hwc_tty_data.buf_count = 0;
+ hwc_tty_data.tty = tty;
+ tty->low_latency = 0;
+
+ return 0;
+}
+
+void
+wake_up_hwc_tty (void)
+{
+ if (hwc_tty_data.tty == NULL)
+ return;
+ if ((hwc_tty_data.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+ hwc_tty_data.tty->ldisc.write_wakeup)
+ (hwc_tty_data.tty->ldisc.write_wakeup) (hwc_tty_data.tty);
+ wake_up_interruptible (&hwc_tty_data.tty->write_wait);
+}
+
+static void
+hwc_tty_close (struct tty_struct *tty,
+ struct file *filp)
+{
+ if (MINOR (tty->device) != tty->driver.minor_start) {
+ printk (KERN_WARNING HWC_TTY_PRINT_HEADER
+ "do not close hwc tty because of wrong device number");
+ return;
+ }
+ hwc_tty_data.tty = NULL;
+}
+
+static int
+hwc_tty_write_room (struct tty_struct *tty)
+{
+ int retval;
+
+ retval = hwc_write_room (IN_BUFS_TOTAL);
+ return retval;
+}
+
+static int
+hwc_tty_write (struct tty_struct *tty,
+ int from_user,
+ const unsigned char *buf,
+ int count)
+{
+ int retval;
+
+ if (hwc_tty_data.buf_count > 0) {
+ hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
+ hwc_tty_data.buf_count = 0;
+ }
+ retval = hwc_write (from_user, buf, count);
+ return retval;
+}
+
+static void
+hwc_tty_put_char (struct tty_struct *tty,
+ unsigned char ch)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave (&hwc_tty_data.lock, flags);
+ if (hwc_tty_data.buf_count >= HWC_TTY_BUF_SIZE) {
+ hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
+ hwc_tty_data.buf_count = 0;
+ }
+ hwc_tty_data.buf[hwc_tty_data.buf_count] = ch;
+ hwc_tty_data.buf_count++;
+ spin_unlock_irqrestore (&hwc_tty_data.lock, flags);
+}
+
+static void
+hwc_tty_flush_chars (struct tty_struct *tty)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave (&hwc_tty_data.lock, flags);
+ hwc_write (0, hwc_tty_data.buf, hwc_tty_data.buf_count);
+ hwc_tty_data.buf_count = 0;
+ spin_unlock_irqrestore (&hwc_tty_data.lock, flags);
+}
+
+static int
+hwc_tty_chars_in_buffer (struct tty_struct *tty)
+{
+ int retval;
+
+ retval = hwc_chars_in_buffer (IN_BUFS_TOTAL);
+ return retval;
+}
+
+static void
+hwc_tty_flush_buffer (struct tty_struct *tty)
+{
+ wake_up_hwc_tty ();
+}
+
+static int
+hwc_tty_ioctl (
+ struct tty_struct *tty,
+ struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ if (tty->flags & (1 << TTY_IO_ERROR))
+ return -EIO;
+
+ return hwc_ioctl (cmd, arg);
+}
+
+void
+store_hwc_input (unsigned char *buf, unsigned int count)
+{
+ struct tty_struct *tty = hwc_tty_data.tty;
+
+ if (tty != NULL) {
+
+ if (count == 2 && (
+ /* hat is 0xb0 in codepage 037 (US etc.) and thus */
+ /* converted to 0x5e in ascii ('^') */
+ strncmp (buf, "^c", 2) == 0 ||
+ /* hat is 0xb0 in several other codepages (German, */
+ /* UK, ...) and thus converted to ascii octal 252 */
+ strncmp (buf, "\0252c", 2) == 0)) {
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = INTR_CHAR (tty);
+ } else if (count == 2 && (
+ strncmp (buf, "^d", 2) == 0 ||
+ strncmp (buf, "\0252d", 2) == 0)) {
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = EOF_CHAR (tty);
+ } else if (count == 2 && (
+ strncmp (buf, "^z", 2) == 0 ||
+ strncmp (buf, "\0252z", 2) == 0)) {
+ tty->flip.count++;
+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
+ *tty->flip.char_buf_ptr++ = SUSP_CHAR (tty);
+ } else {
+
+ memcpy (tty->flip.char_buf_ptr, buf, count);
+ if (count < 2 || (
+ strncmp (buf + count - 2, "^n", 2) ||
+ strncmp (buf + count - 2, "\0252n", 2))) {
+ tty->flip.char_buf_ptr[count] = '\n';
+ count++;
+ } else
+ count -= 2;
+ memset (tty->flip.flag_buf_ptr, TTY_NORMAL, count);
+ tty->flip.char_buf_ptr += count;
+ tty->flip.flag_buf_ptr += count;
+ tty->flip.count += count;
+ }
+ tty_flip_buffer_push (tty);
+ wake_up_hwc_tty ();
+ }
+}
+
+void
+hwc_tty_init (void)
+{
+ memset (&hwc_tty_driver, 0, sizeof (struct tty_driver));
+ memset (&hwc_tty_data, 0, sizeof (hwc_tty_data_struct));
+ hwc_tty_driver.magic = TTY_DRIVER_MAGIC;
+ hwc_tty_driver.driver_name = "tty_hwc";
+ hwc_tty_driver.name = "ttyS";
+ hwc_tty_driver.name_base = 0;
+ hwc_tty_driver.major = TTY_MAJOR;
+ hwc_tty_driver.minor_start = 64;
+ hwc_tty_driver.num = 1;
+ hwc_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;
+ hwc_tty_driver.subtype = SYSTEM_TYPE_TTY;
+ hwc_tty_driver.init_termios = tty_std_termios;
+ hwc_tty_driver.init_termios.c_iflag = IGNBRK | IGNPAR;
+ hwc_tty_driver.init_termios.c_oflag = ONLCR;
+ hwc_tty_driver.init_termios.c_lflag = ISIG | ECHO;
+ hwc_tty_driver.flags = TTY_DRIVER_REAL_RAW;
+ hwc_tty_driver.refcount = &hwc_tty_refcount;
+
+ hwc_tty_driver.table = hwc_tty_table;
+ hwc_tty_driver.termios = hwc_tty_termios;
+ hwc_tty_driver.termios_locked = hwc_tty_termios_locked;
+
+ hwc_tty_driver.open = hwc_tty_open;
+ hwc_tty_driver.close = NULL /* hwc_tty_close */ ;
+ hwc_tty_driver.write = hwc_tty_write;
+ hwc_tty_driver.put_char = hwc_tty_put_char;
+ hwc_tty_driver.flush_chars = hwc_tty_flush_chars;
+ hwc_tty_driver.write_room = hwc_tty_write_room;
+ hwc_tty_driver.chars_in_buffer = hwc_tty_chars_in_buffer;
+ hwc_tty_driver.flush_buffer = hwc_tty_flush_buffer;
+ hwc_tty_driver.ioctl = hwc_tty_ioctl;
+
+ hwc_tty_driver.throttle = NULL;
+ hwc_tty_driver.unthrottle = NULL;
+ hwc_tty_driver.send_xchar = NULL;
+ hwc_tty_driver.set_termios = NULL;
+ hwc_tty_driver.set_ldisc = NULL;
+ hwc_tty_driver.stop = NULL;
+ hwc_tty_driver.start = NULL;
+ hwc_tty_driver.hangup = NULL;
+ hwc_tty_driver.break_ctl = NULL;
+ hwc_tty_driver.wait_until_sent = NULL;
+ hwc_tty_driver.read_proc = NULL;
+ hwc_tty_driver.write_proc = NULL;
+
+ if (tty_register_driver (&hwc_tty_driver))
+ panic ("Couldn't register hwc_tty driver\n");
+}
diff --git a/drivers/s390/misc/Makefile b/drivers/s390/misc/Makefile
new file mode 100644
index 000000000..3d8c93271
--- /dev/null
+++ b/drivers/s390/misc/Makefile
@@ -0,0 +1,13 @@
+all: s390-misc.o
+
+CFLAFS +=
+O_TARGET := s390-misc.o
+O_OBJS :=
+M_OBJS :=
+
+ifeq ($(CONFIG_CHANDEV),y)
+ O_OBJS += chandev.o
+endif
+
+include $(TOPDIR)/Rules.make
+
diff --git a/drivers/s390/misc/chandev.c b/drivers/s390/misc/chandev.c
new file mode 100644
index 000000000..4345f1211
--- /dev/null
+++ b/drivers/s390/misc/chandev.c
@@ -0,0 +1,759 @@
+/*
+ * drivers/s390/misc/chandev.c
+ * common channel device layer
+ *
+ * S390 version
+ * Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ */
+
+#define __KERNEL_SYSCALLS__
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <asm/queue.h>
+#include <asm/uaccess.h>
+#include <linux/slab.h>
+#include <asm/irq.h>
+#include <linux/init.h>
+#include <linux/unistd.h>
+#include <asm/chandev.h>
+#include <linux/proc_fs.h>
+#include <linux/vmalloc.h>
+
+static chandev_model_info *chandev_models_head=NULL;
+static chandev *chandev_head=NULL;
+static chandev_noauto_range *chandev_noauto_head=NULL;
+static chandev_force *chandev_force_head=NULL;
+static chandev_probelist *chandev_probelist_head=NULL;
+static int use_devno_names=FALSE;
+static int chandev_conf_read=FALSE;
+
+static void *chandev_alloc_listmember(list **listhead,size_t size)
+{
+ void *newmember=kmalloc(GFP_KERNEL,size);
+ if(newmember)
+ add_to_list(listhead,newmember);
+ return(newmember);
+}
+
+void chandev_free_listmember(list **listhead,list *member)
+{
+ if(remove_from_list(listhead,member))
+ kfree(member);
+ else
+ printk(KERN_CRIT"chandev_free_listmember detected nonexistant"
+ "listmember listhead=%p member %p\n",listhead,member);
+}
+
+void chandev_free_all(list **listhead)
+{
+ while(*listhead)
+ chandev_free_listmember(listhead,*listhead);
+}
+
+void chandev_add_model(chandev_type chan_type,u16 cu_type,u8 cu_model,u8 max_port_no)
+{
+ chandev_model_info *newmodel;
+
+ if((newmodel=chandev_alloc_listmember(
+ (list **)&chandev_models_head,sizeof(chandev_model_info))))
+ {
+ newmodel->chan_type=chan_type;
+ newmodel->cu_type=cu_type;
+ newmodel->cu_model=cu_model;
+ newmodel->max_port_no=max_port_no;
+ }
+}
+
+
+void chandev_remove(chandev *member)
+{
+ chandev_free_listmember((list **)&chandev_head,(list *)member);
+}
+
+
+void chandev_remove_all(void)
+{
+ chandev_free_all((list **)&chandev_head);
+}
+
+void chandev_remove_model(chandev_model_info *model)
+{
+ chandev *curr_chandev;
+ for(curr_chandev=chandev_head;curr_chandev!=NULL;
+ curr_chandev=curr_chandev->next)
+ if(curr_chandev->model_info==model)
+ chandev_remove(curr_chandev);
+ chandev_free_listmember((list **)&chandev_models_head,(list *)model);
+}
+
+void chandev_remove_all_models(void)
+{
+ while(chandev_models_head)
+ chandev_remove_model(chandev_models_head);
+}
+
+void chandev_del_model(u16 cu_type,u8 cu_model)
+{
+ chandev_model_info *curr_model;
+ for(curr_model=chandev_models_head;curr_model!=NULL;
+ curr_model=curr_model->next)
+ if(curr_model->cu_type==cu_type&&curr_model->cu_model==cu_model)
+ chandev_remove_model(curr_model);
+}
+
+static void chandev_init_default_models(void)
+{
+ /* P390/Planter 3172 emulation assume maximum 16 to be safe. */
+ chandev_add_model(lcs,0x3088,0x1,15);
+
+ /* 3172/2216 Paralell the 2216 allows 16 ports per card the */
+ /* the original 3172 only allows 4 we will assume the max of 16 */
+ chandev_add_model(lcs|ctc,0x3088,0x8,15);
+
+ /* 3172/2216 Escon serial the 2216 allows 16 ports per card the */
+ /* the original 3172 only allows 4 we will assume the max of 16 */
+ chandev_add_model(lcs|escon,0x3088,0x1F,15);
+
+ /* Only 2 ports allowed on OSA2 cards model 0x60 */
+ chandev_add_model(lcs,0x3088,0x60,1);
+
+ /* Osa-D we currently aren't too emotionally involved with this */
+ chandev_add_model(osad,0x3088,0x62,0);
+}
+
+void chandev_add(dev_info_t *newdevinfo,chandev_model_info *newmodelinfo)
+{
+ chandev *new_chandev;
+
+ if((new_chandev=chandev_alloc_listmember(
+ (list **)&chandev_head,sizeof(chandev))))
+ {
+ new_chandev->model_info=newmodelinfo;
+ new_chandev->devno=newdevinfo->devno;
+ new_chandev->irq=newdevinfo->irq;
+ }
+}
+
+
+void chandev_collect_devices(void)
+{
+ int curr_irq,loopcnt=0,err;
+ dev_info_t curr_devinfo;
+ chandev_model_info *curr_model;
+
+
+ for(curr_irq=get_irq_first();curr_irq>=0; curr_irq=get_irq_next(curr_irq))
+ {
+ /* check read chandev
+ * we had to do the cu_model check also because ctc devices
+ * have the same cutype & after asking some people
+ * the model numbers are given out pseudo randomly so
+ * we can't just take a range of them also the dev_type & models are 0
+ */
+ loopcnt++;
+ if(loopcnt>0x10000)
+ {
+ printk(KERN_ERR"chandev_collect_devices detected infinite loop bug in get_irq_next\n");
+ break;
+ }
+ if((err=get_dev_info_by_irq(curr_irq,&curr_devinfo)))
+ {
+ printk("chandev_collect_devices get_dev_info_by_irq reported err=%X on irq %d\n"
+ "should not happen\n",err,curr_irq);
+ continue;
+ }
+ for(curr_model=chandev_models_head;curr_model!=NULL;
+ curr_model=curr_model->next)
+ {
+ if((curr_model->cu_type==curr_devinfo.sid_data.cu_type)&&
+ (curr_model->cu_model==curr_devinfo.sid_data.cu_model)
+ &&((curr_devinfo.status&DEVSTAT_DEVICE_OWNED)==0))
+ chandev_add(&curr_devinfo,curr_model);
+ }
+ }
+}
+
+void chandev_add_force(chandev_type chan_type,s32 devif_num,u16 read_devno,
+u16 write_devno,s16 port_no,u8 do_ip_checksumming,u8 use_hw_stats)
+
+{
+ chandev_force *new_chandev_force;
+
+ if((new_chandev_force=chandev_alloc_listmember(
+ (list **)&chandev_force_head,sizeof(chandev_force))))
+ {
+ new_chandev_force->chan_type=chan_type;
+ new_chandev_force->devif_num=devif_num;
+ new_chandev_force->read_devno=read_devno;
+ new_chandev_force->write_devno=write_devno;
+ new_chandev_force->port_no=port_no;
+ new_chandev_force->do_ip_checksumming=do_ip_checksumming;
+ new_chandev_force->use_hw_stats=use_hw_stats;
+ }
+}
+
+void chandev_del_force(u16 read_devno)
+{
+ chandev_force *curr_force;
+ for(curr_force=chandev_force_head;curr_force!=NULL;
+ curr_force=curr_force->next)
+ {
+ if(curr_force->read_devno==read_devno)
+ chandev_free_listmember((list **)&chandev_force_head,
+ (list *)curr_force);
+ }
+}
+
+void chandev_pack_args(char *str)
+{
+ char *newstr=str;
+ while(*str)
+ {
+ if(isspace(*str))
+ str++;
+ else
+ *newstr++=*str++;
+ }
+ *newstr=0;
+}
+
+typedef enum
+{
+ isnull=0,
+ isstr=1,
+ isnum=2,
+ iscomma=4,
+} chandev_strval;
+
+chandev_strval chandev_strcmp(char *teststr,char **str,long *endlong)
+{
+ char *cur=*str;
+ chandev_strval retval=isnull;
+
+ int len=strlen(teststr);
+ if(strncmp(teststr,*str,len)==0)
+ {
+ *str+=len;
+ retval=isstr;
+ *endlong=simple_strtol(cur,str,0);
+ if(cur!=*str)
+ retval|=isnum;
+ if(**str==',')
+ retval|=iscomma;
+ }
+ return(retval);
+}
+
+static char *argstrs[]=
+{
+ "noauto",
+ "lcs",
+ "ctc",
+ "escon",
+ "del_force",
+ "use_devno_names"
+ "dont_use_devno_names",
+ "add_model"
+ "del_model"
+ "del_all_models"
+};
+
+typedef enum
+{
+ stridx_mult=16,
+ first_stridx=0,
+ noauto_stridx=first_stridx,
+ lcs_stridx,
+ ctc_stridx,
+ escon_stridx,
+ del_force_stridx,
+ use_devno_names_stridx,
+ dont_use_devno_names_stridx,
+ add_model_stridx,
+ del_model_stridx,
+ del_all_models_stridx,
+ last_stridx,
+} chandev_str_enum;
+
+void chandev_add_noauto(u16 lo_devno,u16 hi_devno)
+{
+ chandev_noauto_range *new_range;
+
+ if((new_range=chandev_alloc_listmember(
+ (list **)&chandev_noauto_head,sizeof(chandev_noauto_range))))
+ {
+ new_range->lo_devno=lo_devno;
+ new_range->hi_devno=hi_devno;
+ }
+}
+
+static char chandev_keydescript[]=
+"chan_type key bitfield\nctc=0x1,escon=0x2,lcs=0x4,lcs=0x4,osad=0x8,claw=0x16\n";
+
+static void chandev_print_args(void)
+{
+ printk("valid chandev arguments are"
+ "<> indicate optional parameters | indicate a choice.\n");
+ printk("noauto,<lo_devno>,<hi_devno>\n"
+ "don't probe a range of device numbers for channel devices\n");
+ printk("lcs|ctc|escon<devif_num>,read_devno,write_devno,<port_no>,"
+ "<do_ip_checksumming>,<use_hw_stats>\n");
+ printk("e.g. ctc0,0x7c00,0x7c01,-1,0,0\n");
+ printk(" tells the channel layer to force ctc0 if detected to use\n"
+ " cuu's 7c00 & 7c01 port ( rel adapter no ) is invalid for\n"
+ " ctc's so use -1 don't do checksumming on received ip\n"
+ " packets & as ctc doesn't have hardware stats ignore this\n"
+ " parameter\n\n");
+ printk("del_force read_devno\n"
+ "delete a forced channel device from force list.\n");
+ printk("use_devno_names, tells the channel layer to assign device\n"
+ "names based on the read channel cuu number\n"
+ "e.g. a token ring read channel 0x7c00 would have an interface"
+ "called tr0x7c00 this avoids name collisions on devices.");
+ printk("add_model chan_type cu_model max_port no\n"
+ "tells the channel layer to probe for the device described\n");
+ printk("%s use max_port_no of 0 for devices where this field "
+ "is invalid.\n",chandev_keydescript);
+ printk("del_model cu_type cu_model\n");
+ printk("del_all_models\n");
+}
+
+
+static int chandev_setup(char *str)
+{
+ chandev_strval val=isnull;
+ chandev_str_enum stridx;
+ long endlong;
+ chandev_type chan_type;
+#define CHANDEV_MAX_EXTRA_INTS 5
+ int ints[CHANDEV_MAX_EXTRA_INTS+1];
+ memset(ints,0,sizeof(ints));
+ chandev_pack_args(str);
+ for(stridx=first_stridx;stridx<last_stridx;stridx++)
+ if((val=chandev_strcmp(argstrs[stridx],&str,&endlong)))
+ break;
+ if(val)
+ {
+ if(val&iscomma)
+ get_options(str,CHANDEV_MAX_EXTRA_INTS,ints);
+ else
+ ints[0]=0;
+ val=(((chandev_strval)stridx)*stridx_mult)+(val&~isstr);
+ switch(val)
+ {
+ case noauto_stridx*stridx_mult:
+ case (noauto_stridx*stridx_mult)|iscomma:
+ switch(ints[0])
+ {
+ case 0:
+ chandev_free_all((list **)&chandev_noauto_head);
+ chandev_add_noauto(0,0xffff);
+ break;
+ case 1:
+ ints[2]=ints[1];
+ case 2:
+ chandev_add_noauto(ints[1],ints[2]);
+
+ }
+ break;
+ case (ctc_stridx*stridx_mult)|isnum|iscomma:
+ case (escon_stridx*stridx_mult)|isnum|iscomma:
+ case (lcs_stridx*stridx_mult)|isnum|iscomma:
+ switch(val)
+ {
+ case (ctc_stridx*stridx_mult)|isnum|iscomma:
+ chan_type=ctc;
+ break;
+ case (escon_stridx*stridx_mult)|isnum|iscomma:
+ chan_type=escon;
+ break;
+ case (lcs_stridx*stridx_mult)|isnum|iscomma:
+ chan_type=lcs;
+ break;
+ default:
+ goto BadArgs;
+ }
+ chandev_add_force(chan_type,endlong,ints[1],ints[2],
+ ints[3],ints[4],ints[5]);
+ break;
+ case (del_force_stridx*stridx_mult)|iscomma:
+ if(ints[0]!=1)
+ goto BadArgs;
+ chandev_del_force(ints[1]);
+ break;
+ case (use_devno_names_stridx*stridx_mult):
+ use_devno_names=1;
+ break;
+ case (dont_use_devno_names_stridx*stridx_mult):
+ use_devno_names=0;
+ case (add_model_stridx*stridx_mult)|iscomma:
+ if(ints[0]<3)
+ goto BadArgs;
+ if(ints[0]==3)
+ {
+ ints[0]=4;
+ ints[4]=-1;
+ }
+ chandev_add_model(ints[1],ints[2],ints[3],ints[4]);
+ break;
+ case (del_model_stridx*stridx_mult)|iscomma:
+ if(ints[0]!=2)
+ goto BadArgs;
+ chandev_del_model(ints[1],ints[2]);
+ break;
+ case del_all_models_stridx*stridx_mult:
+ chandev_remove_all_models();
+ break;
+ default:
+ goto BadArgs;
+ }
+ }
+ return(1);
+ BadArgs:
+ chandev_print_args();
+ return(0);
+}
+
+__setup("chandev=",chandev_setup);
+
+int chandev_doprobe(chandev_force *force,chandev *read_chandev,
+chandev *write_chandev)
+{
+ chandev_probelist *probe;
+ chandev_model_info *model_info;
+ chandev_probeinfo probeinfo;
+ int retval=-1,hint=-1;
+
+ model_info=read_chandev->model_info;
+ if(read_chandev->model_info!=write_chandev->model_info||
+ (force&&((force->chan_type&model_info->chan_type)==0)))
+ return(-1); /* inconsistent */
+ for(probe=chandev_probelist_head;
+ probe!=NULL;
+ probe=probe->next)
+ {
+ if(probe->chan_type&model_info->chan_type)
+ {
+ if(use_devno_names)
+ probeinfo.devif_num=read_chandev->devno;
+ else
+ probeinfo.devif_num=-1;
+ probeinfo.read_irq=read_chandev->irq;
+ probeinfo.write_irq=write_chandev->irq;
+
+ probeinfo.max_port_no=model_info->max_port_no;
+ if(force)
+ {
+ probeinfo.forced_port_no=force->port_no;
+ if(force->devif_num!=-1)
+ probeinfo.devif_num=force->devif_num;
+ probeinfo.do_ip_checksumming=force->do_ip_checksumming;
+ probeinfo.use_hw_stats=force->use_hw_stats;
+
+ }
+ else
+ {
+ probeinfo.forced_port_no=-1;
+ probeinfo.do_ip_checksumming=FALSE;
+ probeinfo.use_hw_stats=FALSE;
+ if(probe->chan_type&lcs)
+ {
+ hint=(read_chandev->devno&0xFF)>>1;
+ if(hint>model_info->max_port_no)
+ {
+ /* The card is possibly emulated e.g P/390 */
+ /* or possibly configured to use a shared */
+ /* port configured by osa-sf. */
+ hint=0;
+ }
+ }
+ }
+ probeinfo.hint_port_no=hint;
+ retval=probe->probefunc(&probeinfo);
+ if(retval==0)
+ break;
+ }
+ }
+ return(retval);
+}
+
+void chandev_probe(void)
+{
+ chandev *read_chandev,*write_chandev,*curr_chandev;
+ chandev_force *curr_force;
+ chandev_noauto_range *curr_noauto;
+
+ chandev_collect_devices();
+ for(curr_force=chandev_force_head;curr_force!=NULL;
+ curr_force=curr_force->next)
+ {
+ for(read_chandev=chandev_head;
+ read_chandev!=NULL;
+ read_chandev=read_chandev->next)
+ if(read_chandev->devno==curr_force->read_devno)
+ {
+ for(write_chandev=chandev_head;
+ write_chandev!=NULL;
+ write_chandev=write_chandev->next)
+ if(write_chandev->devno==
+ curr_force->write_devno)
+ {
+ if(chandev_doprobe(curr_force,
+ read_chandev,
+ write_chandev)==0)
+ {
+ chandev_remove(read_chandev);
+ chandev_remove(write_chandev);
+ goto chandev_probe_skip;
+ }
+ }
+ }
+ chandev_probe_skip:
+ }
+ for(curr_chandev=chandev_head;
+ curr_chandev!=NULL;
+ curr_chandev=curr_chandev->next)
+ {
+ for(curr_noauto=chandev_noauto_head;curr_noauto!=NULL;
+ curr_noauto=curr_noauto->next)
+ {
+ if(curr_chandev->devno>=curr_noauto->lo_devno&&
+ curr_chandev->devno<=curr_noauto->hi_devno)
+ {
+ chandev_remove(curr_chandev);
+ break;
+ }
+ }
+ }
+ for(curr_chandev=chandev_head;curr_chandev!=NULL;
+ curr_chandev=curr_chandev->next)
+ {
+ if(curr_chandev->next&&curr_chandev->model_info==
+ curr_chandev->next->model_info)
+ {
+
+ chandev_doprobe(NULL,curr_chandev,curr_chandev->next);
+ curr_chandev=curr_chandev->next;
+ }
+ }
+ chandev_remove_all();
+}
+
+int chandev_do_setup(char *buff,int size)
+{
+ int curr,startline=0,comment=FALSE,newline=FALSE,oldnewline=TRUE;
+ int rc=1;
+
+ buff[size]=0;
+ for(curr=0;curr<=size;curr++)
+ {
+ if(buff[curr]=='#')
+ {
+ comment=TRUE;
+ newline=FALSE;
+ }
+ else if(buff[curr]==10||buff[curr]==13||buff[curr]==0)
+ {
+ buff[curr]=0;
+ comment=FALSE;
+ newline=TRUE;
+ }
+ if(comment==FALSE&&curr>startline
+ &&((oldnewline==TRUE&&newline==FALSE)||curr==size))
+ {
+ if((rc=chandev_setup(&buff[startline]))==0)
+ break;
+ startline=curr+1;
+ }
+ oldnewline=newline;
+ }
+ return(rc);
+}
+void chandev_read_conf(void)
+{
+#define CHANDEV_FILE "/etc/chandev.conf"
+ struct stat statbuf;
+ char *buff;
+ int curr,left,len,fd;
+
+ chandev_conf_read=TRUE;
+ set_fs(KERNEL_DS);
+ if(stat(CHANDEV_FILE,&statbuf)==0)
+ {
+ set_fs(USER_DS);
+ buff=vmalloc(statbuf.st_size+1);
+ if(buff)
+ {
+ set_fs(KERNEL_DS);
+ if((fd=open(CHANDEV_FILE,O_RDONLY,0))!=-1)
+ {
+ curr=0;
+ left=statbuf.st_size;
+ while((len=read(fd,&buff[curr],left))>0)
+ {
+ curr+=len;
+ left-=len;
+ }
+ close(fd);
+ }
+ set_fs(USER_DS);
+ chandev_do_setup(buff,statbuf.st_size);
+ vfree(buff);
+ }
+ }
+ set_fs(USER_DS);
+}
+
+void chandev_register_and_probe(chandev_probefunc probefunc,chandev_type chan_type)
+{
+ chandev_probelist *new_probe;
+ if(!chandev_conf_read)
+ chandev_read_conf();
+ if((new_probe=chandev_alloc_listmember((list **)&
+ chandev_probelist_head,sizeof(chandev_probelist))))
+ {
+ new_probe->probefunc=probefunc;
+ new_probe->chan_type=chan_type;
+ chandev_probe();
+ }
+}
+
+void chandev_unregister(chandev_probefunc probefunc)
+{
+ chandev_probelist *curr_probe=NULL;
+
+ for(curr_probe=chandev_probelist_head;curr_probe!=NULL;
+ curr_probe=curr_probe->next)
+ {
+ if(curr_probe->probefunc==probefunc)
+ chandev_free_listmember((list **)&chandev_probelist_head,
+ (list *)curr_probe);
+ }
+}
+
+
+#ifdef CONFIG_PROC_FS
+#define chandev_printf(exitchan,args...) \
+splen=sprintf(spbuff,##args); \
+spoffset+=splen; \
+if(spoffset>offset) { \
+ spbuff+=splen; \
+ currlen+=splen; \
+} \
+if(currlen>=length) \
+ goto exitchan;
+
+
+
+static int chandev_read_proc(char *page, char **start, off_t offset,
+ int length, int *eof, void *data)
+{
+ char *spbuff=*start=page;
+ int currlen=0,splen;
+ off_t spoffset=0;
+ chandev_model_info *curr_model;
+ chandev_noauto_range *curr_noauto;
+ chandev_force *curr_force;
+
+
+ chandev_printf(chan_exit,"Channels enabled for detection\n");
+ chandev_printf(chan_exit,"chan_type cu_type cu_model max_port_no\n");
+ chandev_printf(chan_exit,"=================================================\n");
+ for(curr_model=chandev_models_head;curr_model!=NULL;
+ curr_model=curr_model->next)
+ {
+ chandev_printf(chan_exit,"0x%02x 0x%04x 0x%02x %d\n",
+ curr_model->chan_type,(int)curr_model->cu_type,
+ (int)curr_model->cu_model,(int)curr_model->max_port_no);
+ }
+
+ chandev_printf(chan_exit,"%s",chandev_keydescript);
+ chandev_printf(chan_exit,"No auto devno ranges\n");
+ chandev_printf(chan_exit," From To \n");
+ chandev_printf(chan_exit,"====================\n");
+ for(curr_noauto=chandev_noauto_head;curr_noauto!=NULL;
+ curr_noauto=curr_noauto->next)
+ {
+ chandev_printf(chan_exit,"0x%4x 0x%4x\n",
+ curr_noauto->lo_devno,
+ curr_noauto->hi_devno);
+ }
+ chandev_printf(chan_exit,"\nForced devices\n");
+ chandev_printf(chan_exit,"chan_type defif_num read_devno write_devno port_no ip_cksum hw_stats\n");
+ chandev_printf(chan_exit,"====================================================================\n");
+ for(curr_force=chandev_force_head;curr_force!=NULL;
+ curr_force=curr_force->next)
+ {
+ chandev_printf(chan_exit,"0x%2x %d 0x%4x 0x%4x %4d %1d %1d\n",
+ curr_force->chan_type,curr_force->devif_num,
+ curr_force->read_devno,curr_force->write_devno,
+ curr_force->port_no,curr_force->do_ip_checksumming,
+ curr_force->use_hw_stats);
+ }
+ *eof=TRUE;
+ chan_exit:
+ if(currlen>length) {
+ /* rewind to previous printf so that we are correctly
+ * aligned if we get called to print another page.
+ */
+ currlen-=splen;
+ }
+ return(currlen);
+}
+
+
+static int chandev_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int rc;
+ char *buff;
+
+ buff=vmalloc(count+1);
+ if(buff)
+ {
+ rc = copy_from_user(buff,buffer,count);
+ if (rc)
+ goto chandev_write_exit;
+ chandev_do_setup(buff,count);
+ rc=count;
+ chandev_write_exit:
+ vfree(buff);
+ return rc;
+ }
+ else
+ return -ENOMEM;
+ return(0);
+}
+
+static void __init chandev_create_proc(void)
+{
+ struct proc_dir_entry *dir_entry=
+ create_proc_entry("chandev",0644,
+ &proc_root);
+ if(dir_entry)
+ {
+ dir_entry->read_proc=&chandev_read_proc;
+ dir_entry->write_proc=&chandev_write_proc;
+ }
+}
+
+
+#endif
+static int __init chandev_init(void)
+{
+ chandev_init_default_models();
+#if CONFIG_PROC_FS
+ chandev_create_proc();
+#endif
+ return(0);
+}
+__initcall(chandev_init);
+
+
+
+
+
+
+
diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile
new file mode 100644
index 000000000..2c2a182b6
--- /dev/null
+++ b/drivers/s390/net/Makefile
@@ -0,0 +1,16 @@
+all: s390-net.o
+
+CFLAFS +=
+O_TARGET := s390-net.o
+O_OBJS :=
+M_OBJS :=
+
+ifeq ($(CONFIG_CTC),y)
+ O_OBJS += ctc.o
+endif
+
+ifeq ($(CONFIG_IUCV),y)
+ O_OBJS += iucv.o
+endif
+
+include $(TOPDIR)/Rules.make
diff --git a/drivers/s390/net/ctc.c b/drivers/s390/net/ctc.c
new file mode 100644
index 000000000..4acc6e543
--- /dev/null
+++ b/drivers/s390/net/ctc.c
@@ -0,0 +1,1581 @@
+/*
+ * drivers/s390/net/ctc.c
+ * CTC / ESCON network driver
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Dieter Wellerdiek (wel@de.ibm.com)
+ *
+ * 2.3 Updates Martin Schwidefsky (schwidefsky@de.ibm.com)
+ * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ *
+ *
+ * Description of the Kernel Parameter
+ * Normally the CTC driver selects the channels in order (automatic channel
+ * selection). If your installation needs to use the channels in a different
+ * order or doesn't want to have automatic channel selection on, you can do
+ * this with the "ctc= kernel keyword".
+ *
+ * ctc=0,0xrrrr,0xwwww,ddddd
+ *
+ * Where:
+ *
+ * "rrrr" is the read channel address
+ * "wwww" is the write channel address
+ * "dddd" is the network device (ctc0 to ctc7 for a parallel channel, escon0
+ * to escon7 for ESCON channels).
+ *
+ * To switch the automatic channel selection off use the ctc= keyword with
+ * parameter "noauto". This may be necessary if you 3271 devices or other devices
+ * which use the ctc device type and model, but operate with a different protocol.
+ *
+ * ctc=noauto
+ *
+ * Change History
+ * 0.50 Initial release shipped
+ * 0.51 Bug fixes
+ * - CTC / ESCON network device can now handle up to 64 channels
+ * - 3088-61 info message supperssed - CISCO 7206 - CLAW - ESCON
+ * - 3088-62 info message suppressed - OSA/D
+ * - channel: def ffffffed ... error message suppressed
+ * - CTC / ESCON device was not recoverable after a lost connection with
+ * IFCONFIG dev DOWN and IFCONFIG dev UP
+ * - Possibility to switch the automatic selection off
+ * - Minor bug fixes
+ */
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+
+#include <linux/signal.h>
+#include <linux/string.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ip.h>
+#include <linux/if_arp.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#include <asm/irq.h>
+
+
+//#define DEBUG
+
+/* Redefine message level, so that all messages occur on 3215 console in DEBUG mode */
+#ifdef DEBUG
+ #undef KERN_INFO
+ #undef KERN_WARNING
+ #undef KERN_DEBUG
+ #define KERN_INFO KERN_EMERG
+ #define KERN_WARNING KERN_EMERG
+ #define KERN_DEBUG KERN_EMERG
+#endif
+//#undef DEBUG
+
+#define CCW_CMD_WRITE 0x01
+#define CCW_CMD_READ 0x02
+#define CCW_CMD_SET_EXTENDED 0xc3
+#define CCW_CMD_PREPARE 0xe3
+
+#define MAX_CHANNEL_DEVICES 64
+#define MAX_ADAPTERS 8
+#define CTC_DEFAULT_MTU_SIZE 1500
+#define READ 0
+#define WRITE 1
+#define CTC 0
+#define ESCON 1
+#define CHANNEL_MEDIA 2
+#define CTC_BLOCKS 8 /* 8 blocks * 2 times * 64k = 1M */
+
+#define TB_TX 0 /* sk buffer handling in process */
+#define TB_STOP 1 /* network device stop in process */
+#define TB_RETRY 2 /* retry in process */
+#define TB_NOBUFFER 3 /* no buffer on free queue */
+
+/* state machine codes used in ctc_irq_handler */
+#define CTC_STOP 0
+#define CTC_START_HALT_IO 1
+#define CTC_START_SET_X_MODE 2
+#define CTC_START_SELECT 4
+#define CTC_START_READ_TEST 32
+#define CTC_START_READ 33
+#define CTC_START_WRITE_TEST 64
+#define CTC_START_WRITE 65
+
+
+typedef enum {
+ channel_type_none, /* Device is not a channel */
+ channel_type_undefined, /* Device is a channel but we don't know anything about it */
+ channel_type_ctca, /* Device is a CTC/A and we can deal with it */
+ channel_type_escon, /* Device is a ESCON channel and we can deal with it */
+ channel_type_unsupported /* Device is a unsupported model */
+} channel_type_t;
+
+
+
+/*
+ * Structures needed in the initial phase
+ *
+ */
+
+static int channel_tab_initialized = 0; /* channel[] structure initialized */
+
+struct devicelist {
+ unsigned int devno;
+ __u8 flag;
+#define CHANNEL_IN_USE 0x08 /* - Show that channel is in use */
+};
+
+static struct {
+ struct devicelist list[MAX_CHANNEL_DEVICES];
+ int count;
+ int left;
+} channel[CHANNEL_MEDIA];
+
+
+
+static int ctc_no_auto = 0;
+
+struct adapterlist{
+ unsigned int devno[2];
+ __u16 protocol;
+};
+
+static struct adapterlist ctc_adapter[CHANNEL_MEDIA][MAX_ADAPTERS]; /* 0 = CTC / 1 = ESCON */
+
+
+/*
+ * Structure used after the initial phase
+ *
+ */
+
+struct buffer {
+ struct buffer *next;
+ int packets;
+ struct block *block;
+};
+
+#if LINUX_VERSION_CODE>=0x020300
+typedef struct net_device net_device;
+#else
+typedef struct device net_device;
+typedef struct wait_queue* wait_queue_head_t;
+#define DECLARE_WAITQUEUE(waitqname,waitqtask) struct wait_queue waitqname = {waitqtask, NULL }
+#define init_waitqueue_head(nothing)
+#endif
+
+
+struct channel {
+ unsigned int devno;
+ int irq;
+ unsigned long IO_active;
+ ccw1_t ccw[3];
+ __u32 state;
+ int buffer_count;
+ struct buffer *free_anchor;
+ struct buffer *proc_anchor;
+ devstat_t *devstat;
+ net_device *dev; /* backward pointer to the network device */
+ wait_queue_head_t wait;
+ struct tq_struct tq;
+ struct timer_list timer;
+ unsigned long flag_a; /* atomic flags */
+#define CTC_BH_ACTIVE 0
+ __u8 last_dstat;
+ __u8 flag;
+#define CTC_WRITE 0x01 /* - Set if this is a write channel */
+#define CTC_TIMER 0x80 /* - Set if timer made the wake_up */
+};
+
+
+struct ctc_priv {
+ struct net_device_stats stats;
+#if LINUX_VERSION_CODE>=0x02032D
+ int tbusy;
+#endif
+ struct channel channel[2];
+ __u16 protocol;
+};
+
+/*
+ * This structure works as shuttle between two systems
+ * - A block can contain one or more packets
+ */
+
+#define PACKET_HEADER_LENGTH 6
+struct packet {
+ __u16 length;
+ __u16 type;
+ __u16 unused;
+ __u8 data;
+};
+
+#define BLOCK_HEADER_LENGTH 2
+struct block {
+ __u16 length;
+ struct packet data;
+};
+
+#if LINUX_VERSION_CODE>=0x02032D
+#define ctc_protect_busy(dev) \
+s390irq_spin_lock(((struct ctc_priv *)dev->priv)->channel[WRITE].irq)
+#define ctc_unprotect_busy(dev) \
+s390irq_spin_unlock(((struct ctc_priv *)dev->priv)->channel[WRITE].irq)
+
+#define ctc_protect_busy_irqsave(dev,flags) \
+s390irq_spin_lock_irqsave(((struct ctc_priv *)dev->priv)->channel[WRITE].irq,flags)
+#define ctc_unprotect_busy_irqrestore(dev,flags) \
+s390irq_spin_unlock_irqrestore(((struct ctc_priv *)dev->priv)->channel[WRITE].irq,flags)
+
+static __inline__ void ctc_set_busy(net_device *dev)
+{
+ ((struct ctc_priv *)dev->priv)->tbusy=1;
+ netif_stop_queue(dev);
+}
+
+static __inline__ void ctc_clear_busy(net_device *dev)
+{
+ ((struct ctc_priv *)dev->priv)->tbusy=0;
+ netif_start_queue(dev);
+}
+
+static __inline__ int ctc_check_busy(net_device *dev)
+{
+ eieio();
+ return(((struct ctc_priv *)dev->priv)->tbusy);
+}
+
+
+static __inline__ void ctc_setbit_busy(int nr,net_device *dev)
+{
+ set_bit(nr,&(((struct ctc_priv *)dev->priv)->tbusy));
+ netif_stop_queue(dev);
+}
+
+static __inline__ void ctc_clearbit_busy(int nr,net_device *dev)
+{
+ clear_bit(nr,&(((struct ctc_priv *)dev->priv)->tbusy));
+ if(((struct ctc_priv *)dev->priv)->tbusy==0)
+ netif_start_queue(dev);
+}
+
+static __inline__ int ctc_test_and_setbit_busy(int nr,net_device *dev)
+{
+ netif_stop_queue(dev);
+ return(test_and_set_bit(nr,&((struct ctc_priv *)dev->priv)->tbusy));
+}
+#else
+
+#define ctc_protect_busy(dev)
+#define ctc_unprotect_busy(dev)
+#define ctc_protect_busy_irqsave(dev,flags)
+#define ctc_unprotect_busy_irqrestore(dev,flags)
+
+static __inline__ void ctc_set_busy(net_device *dev)
+{
+ dev->tbusy=1;
+ eieio();
+}
+
+static __inline__ void ctc_clear_busy(net_device *dev)
+{
+ dev->tbusy=0;
+ eieio();
+}
+
+static __inline__ int ctc_check_busy(net_device *dev)
+{
+ eieio();
+ return(dev->tbusy);
+}
+
+
+static __inline__ void ctc_setbit_busy(int nr,net_device *dev)
+{
+ set_bit(nr,(void *)&dev->tbusy);
+}
+
+static __inline__ void ctc_clearbit_busy(int nr,net_device *dev)
+{
+ clear_bit(nr,(void *)&dev->tbusy);
+}
+
+static __inline__ int ctc_test_and_setbit_busy(int nr,net_device *dev)
+{
+ return(test_and_set_bit(nr,(void *)&dev->tbusy));
+}
+#endif
+
+
+
+
+
+/* Interrupt handler */
+static void ctc_irq_handler(int irq, void *initparm, struct pt_regs *regs);
+static void ctc_irq_bh(struct channel *ctc);
+static void ctc_read_retry (struct channel *ctc);
+static void ctc_write_retry (struct channel *ctc);
+
+
+/* Functions for the DEV methods */
+int ctc_probe(net_device *dev);
+
+
+static int ctc_open(net_device *dev);
+static void ctc_timer (struct channel *ctc);
+static int ctc_release(net_device *dev);
+static int ctc_tx(struct sk_buff *skb, net_device *dev);
+static int ctc_change_mtu(net_device *dev, int new_mtu);
+struct net_device_stats* ctc_stats(net_device *dev);
+
+
+/*
+ * Channel Routines
+ *
+ */
+
+static void channel_init(void);
+static void channel_scan(void);
+static int channel_get(int media, int devno);
+static int channel_get_next(int media);
+static int channel_free(int media, int devno);
+static channel_type_t channel_check_for_type (senseid_t *id);
+static void channel_sort(struct devicelist list[], int n);
+
+
+/*
+ * initialize the channel[].list
+ */
+static void channel_init(void)
+{
+ int m;
+#ifdef DEBUG
+ int c;
+#endif
+
+ if (!test_and_set_bit(0, (void *)& channel_tab_initialized)){
+ channel_scan();
+ for (m = 0; m < CHANNEL_MEDIA; m++) {
+ channel_sort (channel[m].list, MAX_CHANNEL_DEVICES);
+ channel[m].left = channel[m].count;
+ }
+ if (channel[CTC].count == 0 && channel[ESCON].count == 0)
+ printk(KERN_INFO "channel: no Channel devices recognized\n");
+ else
+ printk(KERN_INFO "channel: %d Parallel channel found - %d ESCON channel found\n",
+ channel[CTC].count, channel[ESCON].count);
+#ifdef DEBUG
+ for (m = 0; m < CHANNEL_MEDIA; m++) {
+ for (c = 0; c < MAX_CHANNEL_DEVICES; c++){
+ printk(KERN_DEBUG "channel: Adapter=%x Entry=%x devno=%04x\n",
+ m, c, channel[m].list[c].devno);
+ }
+ }
+#endif
+ }
+}
+
+
+/*
+* scan for all channels and put the device numbers into the channel[].list
+*/
+static void channel_scan(void)
+{
+ int m;
+ int c;
+ int irq;
+ dev_info_t temp;
+
+ for (m = 0; m < CHANNEL_MEDIA; m++) {
+ for (c = 0; c < MAX_CHANNEL_DEVICES; c++){
+ channel[m].list[c].devno = -ENODEV;
+ }
+ }
+
+ for (irq = 0; irq < NR_IRQS; irq++) {
+ /* CTC/A */
+ if (channel[CTC].count < MAX_CHANNEL_DEVICES ) {
+ if (get_dev_info(irq, &temp) == 0 &&
+ channel_check_for_type(&temp.sid_data) == channel_type_ctca) {
+ channel[CTC].list[channel[CTC].count].devno = temp.devno;
+ channel[CTC].count++;
+ }
+ }
+
+ /* ESCON */
+ if (channel[ESCON].count < MAX_CHANNEL_DEVICES ) {
+ if (get_dev_info(irq, &temp) == 0 &&
+ channel_check_for_type(&temp.sid_data) == channel_type_escon) {
+ channel[ESCON].list[channel[ESCON].count].devno = temp.devno;
+ channel[ESCON].count++;
+
+ }
+ }
+ }
+}
+
+
+/*
+ * free specific channel from the channel[].list
+ */
+static int channel_free(int media, int devno)
+{
+ int i;
+
+ for (i = 0; i < channel[media].count; i++) {
+ if ((devno == channel[media].list[i].devno) &&
+ ((channel[media].list[i].flag & CHANNEL_IN_USE) != 0x00)) {
+ channel[media].list[i].flag &= ~CHANNEL_IN_USE;
+ return 0;
+ }
+ }
+ printk(KERN_WARNING "channel: dev %04x is not a channel or in use\n", devno);
+ return -ENODEV;
+}
+
+
+/*
+ * get specific channel from the channel[].list
+ */
+static int channel_get(int media, int devno)
+{
+ int i;
+
+ for (i = 0; i < channel[media].count; i++) {
+ if ((devno == channel[media].list[i].devno) &&
+ ((channel[media].list[i].flag & CHANNEL_IN_USE) == 0x00)) {
+ channel[media].list[i].flag |= CHANNEL_IN_USE;
+ return channel[media].list[i].devno;
+ }
+ }
+ printk(KERN_WARNING "channel: dev %04x is not a channel or in use\n", devno);
+ return -ENODEV;
+
+}
+
+
+/*
+ * get the next free channel from the channel[].list
+ */
+static int channel_get_next(int media)
+{
+ int i;
+
+ for (i = 0; i < channel[media].count; i++) {
+ if ((channel[media].list[i].flag & CHANNEL_IN_USE) == 0x00) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "channel: picked=%04x\n", channel[media].list[i].devno);
+#endif
+ channel[media].list[i].flag |= CHANNEL_IN_USE;
+ return channel[media].list[i].devno;
+ }
+ }
+ return -ENODEV;
+}
+
+
+/*
+ * picks the next free channel from the channel[].list
+ */
+static int channel_left(int media)
+{
+ return channel[media].left;
+}
+
+
+/*
+ * defines all devices which are channels
+ */
+static channel_type_t channel_check_for_type (senseid_t *id)
+ {
+ channel_type_t type;
+
+ switch (id->cu_type) {
+ case 0x3088:
+
+ switch (id->cu_model) {
+ case 0x08:
+ type = channel_type_ctca; /* 3088-08 ==> CTCA */
+ break;
+
+ case 0x1F:
+ type = channel_type_escon; /* 3088-1F ==> ESCON channel */
+ break;
+
+ case 0x01: /* 3088-01 ==> P390 OSA emulation */
+ case 0x60: /* 3088-60 ==> OSA/2 adapter */
+ case 0x61: /* 3088-61 ==> CISCO 7206 CLAW protocol ESCON connected */
+ case 0x62: /* 3088-62 ==> OSA/D device */
+ type = channel_type_unsupported;
+ break;
+
+ default:
+ type = channel_type_undefined;
+ printk(KERN_INFO "channel: Unknown model found 3088-%02x\n",id->cu_model);
+ }
+ break;
+
+ default:
+ type = channel_type_none;
+
+ }
+ return type;
+}
+
+
+/*
+ * sort the channel[].list
+ */
+static void channel_sort(struct devicelist list[], int n)
+{
+ int i;
+ int sorted = 0;
+ struct devicelist tmp;
+
+ while (!sorted) {
+ sorted = 1;
+
+ for (i = 0; i < n-1; i++) {
+ if (list[i].devno > list[i+1].devno) {
+ tmp = list[i];
+ list[i] = list[i+1];
+ list[i+1] = tmp;
+ sorted = 0;
+ }
+ }
+ }
+}
+
+
+/*
+ * General routines
+ *
+ */
+
+static int inline extract_channel_id(char *name)
+{
+ if (name[0] == 'c')
+ return (name[3]-'0');
+ else
+ return (name[5]-'0');
+}
+
+
+static int inline extract_channel_media(char *name)
+{
+ if (name[0] == 'c')
+ return CTC;
+ else
+ return ESCON;
+}
+
+
+static void ctc_tab_init(void)
+{
+ int m;
+ int i;
+ static int t;
+
+ if (t == 0){
+ for (m = 0; m < CHANNEL_MEDIA; m++) {
+ for (i = 0; i < MAX_ADAPTERS; i++) {
+ ctc_adapter[m][i].devno[WRITE] = -ENODEV;
+ ctc_adapter[m][i].devno[READ] = -ENODEV;
+ }
+ }
+ t = 1;
+ }
+}
+
+
+static int ctc_buffer_alloc(struct channel *ctc) {
+
+ struct buffer *p;
+ struct buffer *q;
+
+ p = kmalloc(sizeof(p), GFP_KERNEL);
+ if (p == NULL)
+ return -ENOMEM;
+ else {
+ p->next = NULL;
+ p->packets = 0;
+ p->block = (struct block *) __get_free_pages(GFP_KERNEL+GFP_DMA, 4);
+ if (p->block == NULL) {
+ kfree(p);
+ return -ENOMEM;
+ }
+ }
+
+ if (ctc->free_anchor == NULL)
+ ctc->free_anchor = p;
+ else {
+ q = ctc->free_anchor;
+ while (q->next != NULL)
+ q = q->next;
+ q->next = p;
+ }
+ ctc->buffer_count++;
+ return 0;
+}
+
+
+static int ctc_buffer_free(struct channel *ctc) {
+
+ struct buffer *p;
+
+
+ if (ctc->free_anchor == NULL)
+ return -ENOMEM;
+
+ p = ctc->free_anchor;
+ ctc->free_anchor = p->next;
+ free_pages((__u32)p->block, 4);
+ kfree(p);
+
+ return 0;
+}
+
+
+static int inline ctc_buffer_swap(struct buffer **from, struct buffer **to) {
+
+ struct buffer *p = NULL;
+ struct buffer *q = NULL;
+
+ if (*from == NULL)
+ return -ENOMEM;
+
+ p = *from;
+ *from = p->next;
+ p->next = NULL;
+
+ if (*to == NULL)
+ *to = p;
+ else {
+ q = *to;
+ while (q->next != NULL)
+ q = q->next;
+ q->next = p;
+
+ }
+ return 0;
+}
+
+
+/*
+ * ctc_setup function
+ * this function is called for each ctc= keyword passed into the kernel
+ *
+ * valid parameter are: ctc=n,0xnnnn,0xnnnn,ctcx
+ * where n is the channel protocol always 0
+ * 0xnnnn is the cu number read
+ * 0xnnnn is the cu number write
+ * ctcx can be ctc0 to ctc7 or escon0 to escon7
+ */
+#if LINUX_VERSION_CODE>=0x020300
+static int __init ctc_setup(char *dev_name)
+#else
+__initfunc(void ctc_setup(char *dev_name,int *ints))
+#endif
+{
+ struct adapterlist tmp;
+#if LINUX_VERSION_CODE>=0x020300
+ #define CTC_MAX_PARMS 4
+ int ints[CTC_MAX_PARMS+1];
+ get_options(dev_name,CTC_MAX_PARMS,ints);
+ #define ctc_setup_return return(1)
+#else
+ #define ctc_setup_return return
+#endif
+ ctc_tab_init();
+
+ ctc_no_auto = 1;
+
+ if (!strcmp(dev_name,"noauto")) {
+ printk(KERN_INFO "ctc: automatic channel selection deactivated\n");
+ ctc_setup_return;
+ }
+
+ tmp.devno[WRITE] = -ENODEV;
+ tmp.devno[READ] = -ENODEV;
+
+ switch (ints[0]) {
+
+ case 3: /* write channel passed */
+ tmp.devno[WRITE] = ints[3];
+
+ case 2: /* read channel passed */
+ tmp.devno[READ] = ints[2];
+ if (tmp.devno[WRITE] == -ENODEV)
+ tmp.devno[WRITE] = tmp.devno[READ] + 1;
+
+ case 1: /* protocol type passed */
+ tmp.protocol = ints[1];
+ if (tmp.protocol == 0) {
+ break;
+ } else {
+ printk(KERN_WARNING "%s: wrong Channel protocol type passed\n", dev_name);
+ ctc_setup_return;
+ }
+ break;
+
+ default:
+ printk(KERN_WARNING "ctc: wrong number of parameter passed\n");
+ ctc_setup_return;
+ }
+ ctc_adapter[extract_channel_media(dev_name)][extract_channel_id(dev_name)] = tmp;
+#ifdef DEBUG
+ printk(DEBUG "%s: protocol=%x read=%04x write=%04x\n",
+ dev_name, tmp.protocol, tmp.devno[READ], tmp.devno[WRITE]);
+#endif
+ ctc_setup_return;
+
+}
+#if LINUX_VERSION_CODE>=0x020300
+__setup("ctc=", ctc_setup);
+#endif
+
+/*
+ * ctc_probe
+ * this function is called for each channel network device,
+ * which is defined in the /init/main.c
+ */
+int ctc_probe(net_device *dev)
+{
+ int rc;
+ int c;
+ int i;
+ int m;
+
+ struct ctc_priv *privptr;
+
+ /* Only the first time the ctc_probe gets control */
+ if (channel_tab_initialized == 0) {
+ channel_init();
+
+
+ }
+
+ ctc_tab_init();
+
+ m = extract_channel_media(dev->name);
+ i = extract_channel_id(dev->name);
+
+ if (channel_left(m) <=1)
+ return -ENODEV;
+
+ if (ctc_no_auto == 1 && (ctc_adapter[m][i].devno[READ] == -ENODEV || ctc_adapter[m][i].devno[WRITE] == -ENODEV))
+ return -ENODEV;
+
+ dev->priv = kmalloc(sizeof(struct ctc_priv), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ memset(dev->priv, 0, sizeof(struct ctc_priv));
+ privptr = (struct ctc_priv *) (dev->priv);
+
+
+ for (c = 0; c < 2; c++) {
+
+ privptr->channel[c].devstat = kmalloc(sizeof(devstat_t), GFP_KERNEL);
+ if (privptr->channel[c].devstat == NULL){
+ if (i == WRITE)
+ kfree(privptr->channel[READ].devstat);
+ return -ENOMEM;
+ }
+ memset(privptr->channel[c].devstat, 0, sizeof(devstat_t));
+
+ if (ctc_no_auto == 0)
+ ctc_adapter[m][i].devno[c] = channel_get_next(m);
+ else
+ ctc_adapter[m][i].devno[c] = channel_get(m, ctc_adapter[m][i].devno[c]);
+
+ if ( ctc_adapter[m][i].devno[c] != -ENODEV){
+ rc = request_irq(get_irq_by_devno(ctc_adapter[m][i].devno[c]),
+ (void *)ctc_irq_handler, SA_INTERRUPT, dev->name,
+ privptr->channel[c].devstat);
+ if (rc) {
+ printk(KERN_WARNING "%s: requested device busy %02x\n", dev->name, rc);
+ return -EBUSY;
+ }
+ } else {
+ if (i == WRITE) {
+ free_irq(get_irq_by_devno(ctc_adapter[m][i].devno[c]), privptr->channel[i].devstat);
+ channel_free(m, ctc_adapter[m][i].devno[READ]);
+ kfree(privptr->channel[READ].devstat);
+ }
+ kfree(privptr->channel[i].devstat);
+ return -ENODEV;
+ }
+ }
+
+ privptr->channel[READ].devno = ctc_adapter[m][i].devno[READ];
+ privptr->channel[READ].irq = get_irq_by_devno(ctc_adapter[m][i].devno[READ]);
+ privptr->channel[WRITE].devno = ctc_adapter[m][i].devno[WRITE];
+ privptr->channel[WRITE].irq = get_irq_by_devno(ctc_adapter[m][i].devno[WRITE]);
+ privptr->protocol = ctc_adapter[m][i].protocol;
+ channel[m].left = channel[m].left - 2;
+
+ printk(KERN_INFO "%s: read dev: %04x irq: %04x - write dev: %04x irq: %04x \n",
+ dev->name, privptr->channel[READ].devno, privptr->channel[READ].irq,
+ privptr->channel[WRITE].devno, privptr->channel[WRITE].irq);
+
+ dev->mtu = CTC_DEFAULT_MTU_SIZE;
+ dev->hard_start_xmit = ctc_tx;
+ dev->open = ctc_open;
+ dev->stop = ctc_release;
+ dev->get_stats = ctc_stats;
+ dev->change_mtu = ctc_change_mtu;
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->type = ARPHRD_SLIP;
+ dev->tx_queue_len = 100;
+ dev_init_buffers(dev);
+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+
+ return 0;
+}
+
+
+/*
+ * Interrupt processing
+ *
+ */
+
+static void inline ccw_check_return_code (net_device *dev, int return_code)
+{
+ if (return_code != 0) {
+ switch (return_code) {
+ case -EBUSY:
+ printk(KERN_INFO "%s: Busy !\n", dev->name);
+ break;
+ case -ENODEV:
+ printk(KERN_EMERG "%s: Invalid device called for IO\n", dev->name);
+ break;
+ case -EIO:
+ printk(KERN_EMERG "%s: Status pending... \n", dev->name);
+ break;
+ default:
+ printk(KERN_EMERG "%s: Unknown error in Do_IO %04x\n",
+ dev->name, return_code);
+ }
+ }
+}
+
+
+static void inline ccw_check_unit_check (net_device *dev, char sense)
+{
+#ifdef DEBUG
+ printk(KERN_INFO "%s: Unit Check with sense code: %02x\n",
+ dev->name, sense);
+#endif
+
+ if (sense & 0x40) {
+#ifdef DEBUG
+ if (sense & 0x01)
+ printk(KERN_DEBUG "%s: Interface disconnect or Selective reset occurred (remote side)\n", dev->name);
+ else
+ printk(KERN_DEBUG "%s: System reset occured (remote side)\n", dev->name);
+#endif
+ } else if (sense & 0x20) {
+ if (sense & 0x04)
+ printk(KERN_WARNING "%s: Data-streaming timeout)\n", dev->name);
+ else
+ printk(KERN_WARNING "%s: Data-transfer parity error\n", dev->name);
+ } else if (sense & 0x10) {
+ if (sense & 0x20)
+ printk(KERN_WARNING "%s: Hardware malfunction (remote side)\n", dev->name);
+ else
+ printk(KERN_WARNING "%s: Read-data parity error (remote side)\n", dev->name);
+ }
+
+}
+
+
+static void ctc_irq_handler (int irq, void *initparm, struct pt_regs *regs)
+{
+ int rc = 0;
+ __u32 parm;
+ __u8 flags = 0x00;
+ struct channel *ctc = NULL;
+ struct ctc_priv *privptr = NULL;
+ net_device *dev = NULL;
+
+ ccw1_t ccw_set_x_mode[2] = {{CCW_CMD_SET_EXTENDED, CCW_FLAG_SLI | CCW_FLAG_CC, 0, NULL},
+ {CCW_CMD_NOOP, CCW_FLAG_SLI, 0, NULL}};
+
+ devstat_t *devstat = ((devstat_t *)initparm);
+
+ /* Bypass all 'unsolited interrupts' */
+ if (devstat->intparm == 0) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "ctc: unsolited interrupt for device: %04x received c-%02x d-%02x f-%02x\n",
+ devstat->devno, devstat->cstat, devstat->dstat, devstat->flag);
+#endif
+ /* FIXME - find the related intparm!!! No IO outstanding!!!! */
+ return;
+ }
+
+ ctc = (struct channel *) (devstat->intparm);
+ dev = (net_device *) ctc->dev;
+ privptr = dev->priv;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: interrupt for device: %04x received c-%02x d-%02x f-%02x state-%02x\n",
+ dev->name, ctc->devno, devstat->cstat, devstat->dstat, devstat->flag, ctc->state);
+#endif
+
+ /* Check for good subchannel return code, otherwise error message */
+ if (devstat->cstat) {
+ printk(KERN_WARNING "%s: subchannel check for device: %04x - %02x\n",
+ dev->name, ctc->devno, devstat->cstat);
+ return;
+ }
+
+
+ /* Check the reason-code of a unit check */
+ if (devstat->dstat & DEV_STAT_UNIT_CHECK)
+ ccw_check_unit_check(dev, devstat->ii.sense.data[0]);
+
+
+ /* State machine to bring the connection up / down and to restart */
+
+ ctc->last_dstat = devstat->dstat;
+
+ switch (ctc->state) {
+
+ case CTC_STOP: /* HALT_IO issued by ctc_release (halt sequence) */
+ if (!devstat->flag & DEVSTAT_FINAL_STATUS)
+ return;
+ wake_up(&ctc->wait); /* wake up ctc_release */
+ return;
+
+
+ case CTC_START_HALT_IO: /* HALT_IO issued by ctc_open (start sequence) */
+ if (!devstat->flag & DEVSTAT_FINAL_STATUS)
+ return;
+
+ ctc->state = CTC_START_SET_X_MODE;
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ccw_set_x_mode[0], parm, 0xff, flags);
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ return;
+
+
+ case CTC_START_SET_X_MODE:
+ if (devstat->dstat & DEV_STAT_UNIT_CHECK) {
+ if ((devstat->ii.sense.data[0] & 0x41) != 0x41 ||
+ (devstat->ii.sense.data[0] & 0x40) != 0x40) {
+ wake_up(&ctc->wait); /* wake up ctc_open (READ or WRITE) */
+ return;
+ }
+ }
+ if (!devstat->flag & DEVSTAT_FINAL_STATUS)
+ return;
+ ctc->state = CTC_START_SELECT;
+
+
+ case CTC_START_SELECT:
+ if (!ctc->flag & CTC_WRITE) {
+ ctc->state = CTC_START_READ_TEST;
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->free_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ wake_up(&ctc->wait); /* wake up ctc_open (READ) */
+
+ } else {
+ ctc->state = CTC_START_WRITE_TEST;
+ /* ADD HERE THE RIGHT PACKET TO ISSUE A ROUND TRIP - PART 1 */
+ ctc->ccw[1].count = 0;
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->free_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags);
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ }
+ return;
+
+
+ case CTC_START_READ_TEST:
+ if (devstat->dstat & DEV_STAT_UNIT_CHECK) {
+ if ((devstat->ii.sense.data[0] & 0x41) == 0x41 ||
+ (devstat->ii.sense.data[0] & 0x40) == 0x40 ||
+ devstat->ii.sense.data[0] == 0 ) {
+ init_timer(&ctc->timer);
+ ctc->timer.function = (void *)ctc_read_retry;
+ ctc->timer.data = (__u32)ctc;
+ ctc->timer.expires = jiffies + 10*HZ;
+ add_timer(&ctc->timer);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: read connection restarted\n",dev->name);
+#endif
+ }
+ return;
+ }
+
+ if ((devstat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) {
+ if ((devstat->dstat & DEV_STAT_ATTENTION) &&
+ (devstat->dstat & DEV_STAT_BUSY)) {
+ printk(KERN_WARNING "%s: read channel is connected with the remote side read channel\n", dev->name);
+ }
+ wake_up(&privptr->channel[WRITE].wait); /* wake up ctc_open (WRITE) */
+ return;
+ }
+
+ ctc->state = CTC_START_READ;
+ set_bit(0, (void *)&ctc->IO_active);
+
+ /* ADD HERE THE RIGHT PACKET TO ISSUE A ROUND TRIP - PART 2 */
+ /* wake_up(&privptr->channel[WRITE].wait);*/ /* wake up ctc_open (WRITE) */
+
+
+ case CTC_START_READ:
+ if (devstat->dstat & DEV_STAT_UNIT_CHECK) {
+ if ((devstat->ii.sense.data[0] & 0x41) == 0x41 ||
+ (devstat->ii.sense.data[0] & 0x40) == 0x40 ||
+ devstat->ii.sense.data[0] == 0 ) {
+ privptr->stats.rx_errors++;
+ /* Need protection here cos we are in the read irq */
+ /* handler the tbusy is for the write subchannel */
+ ctc_protect_busy(dev);
+ ctc_setbit_busy(TB_RETRY,dev);
+ ctc_unprotect_busy(dev);
+ init_timer(&ctc->timer);
+ ctc->timer.function = (void *)ctc_read_retry;
+ ctc->timer.data = (__u32)ctc;
+ ctc->timer.expires = jiffies + 30*HZ;
+ add_timer(&ctc->timer);
+ printk(KERN_INFO "%s: connection restarted!! problem on remote side\n",dev->name);
+ }
+ return;
+ }
+
+ if(!devstat->flag & DEVSTAT_FINAL_STATUS)
+ return;
+ ctc_protect_busy(dev);
+ ctc_clearbit_busy(TB_RETRY,dev);
+ ctc_unprotect_busy(dev);
+ ctc_buffer_swap(&ctc->free_anchor, &ctc->proc_anchor);
+
+ if (ctc->free_anchor != NULL) {
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->free_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ } else {
+ clear_bit(0, (void *)&ctc->IO_active);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: No HOT READ started in IRQ\n",dev->name);
+#endif
+ }
+
+ if (test_and_set_bit(CTC_BH_ACTIVE, (void *)&ctc->flag_a) == 0) {
+ queue_task(&ctc->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+ }
+ return;
+
+
+ case CTC_START_WRITE_TEST:
+ if (devstat->dstat & DEV_STAT_UNIT_CHECK) {
+ if ((devstat->ii.sense.data[0] & 0x41) == 0x41 ||
+ (devstat->ii.sense.data[0] & 0x40) == 0x40 ||
+ devstat->ii.sense.data[0] == 0 ) {
+ init_timer(&ctc->timer);
+ ctc->timer.function = (void *)ctc_write_retry;
+ ctc->timer.data = (__u32)ctc;
+ ctc->timer.expires = jiffies + 10*HZ;
+ add_timer(&ctc->timer);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: write connection restarted\n",dev->name);
+#endif
+ }
+ return;
+ }
+
+ ctc->state = CTC_START_WRITE;
+ wake_up(&ctc->wait); /* wake up ctc_open (WRITE) */
+ return;
+
+
+ case CTC_START_WRITE:
+ if (devstat->dstat & DEV_STAT_UNIT_CHECK) {
+ privptr->stats.tx_errors += ctc->proc_anchor->packets;
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: Unit Check on write channel\n",dev->name);
+#endif
+ } else {
+ if (!devstat->flag & DEVSTAT_FINAL_STATUS)
+ return;
+ privptr->stats.tx_packets += ctc->proc_anchor->packets;
+ }
+
+ ctc->proc_anchor->block->length = 0;
+ ctc_buffer_swap(&ctc->proc_anchor, &ctc->free_anchor);
+ ctc_clearbit_busy(TB_NOBUFFER,dev);
+ if (ctc->proc_anchor != NULL) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: IRQ early swap buffer\n",dev->name);
+#endif
+ ctc->ccw[1].count = ctc->proc_anchor->block->length;
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->proc_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ dev->trans_start = jiffies;
+ return;
+
+ }
+
+ if (ctc->free_anchor->block->length != 0) {
+ if (ctc_test_and_setbit_busy(TB_TX,dev) == 0) {
+ /* set transmission to busy */
+ ctc_buffer_swap(&ctc->free_anchor, &ctc->proc_anchor);
+ ctc_clearbit_busy(TB_TX,dev);
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: last buffer move in IRQ\n",dev->name);
+#endif
+ ctc->ccw[1].count = ctc->proc_anchor->block->length;
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->proc_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ dev->trans_start = jiffies;
+ return;
+ }
+ }
+
+ clear_bit(0, (void *)&ctc->IO_active); /* set by ctc_tx or ctc_bh */
+ return;
+
+
+ default:
+ printk(KERN_WARNING "%s: wrong selection code - irq\n",dev->name);
+ return;
+ }
+}
+
+
+static void ctc_irq_bh (struct channel *ctc)
+{
+ int rc = 0;
+ __u16 data_len;
+ __u32 parm;
+
+ __u8 flags = 0x00;
+ __u32 saveflags;
+ net_device *dev;
+ struct ctc_priv *privptr;
+ struct packet *lp;
+ struct sk_buff *skb;
+
+ dev = (net_device *) ctc->dev;
+ privptr = (struct ctc_priv *) dev->priv;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: bh routine - state-%02x\n" ,dev->name, ctc->state);
+#endif
+
+ while (ctc->proc_anchor != NULL) {
+
+ lp = &ctc->proc_anchor->block->data;
+
+ while ((__u8 *) lp < (__u8 *) &ctc->proc_anchor->block->length + ctc->proc_anchor->block->length) {
+ data_len = lp->length - PACKET_HEADER_LENGTH;
+ skb = dev_alloc_skb(data_len);
+ if (skb) {
+ memcpy(skb_put(skb, data_len),&lp->data, data_len);
+ skb->mac.raw = skb->data;
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_IP);
+ skb->ip_summed = CHECKSUM_UNNECESSARY; /* no UC happened!!! */
+ netif_rx(skb);
+ privptr->stats.rx_packets++;
+ } else {
+ privptr->stats.rx_dropped++;
+ printk(KERN_WARNING "%s: is low on memory\n",dev->name);
+ }
+ (__u8 *)lp += lp->length;
+ }
+
+ s390irq_spin_lock_irqsave(ctc->irq, saveflags);
+ ctc_buffer_swap(&ctc->proc_anchor, &ctc->free_anchor);
+
+ if (test_and_set_bit(0, (void *)&ctc->IO_active) == 0) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: HOT READ started in bh routine\n" ,dev->name);
+#endif
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->free_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ }
+ s390irq_spin_unlock_irqrestore(ctc->irq, saveflags);
+ }
+ clear_bit(CTC_BH_ACTIVE, (void *)&ctc->flag_a);
+ return;
+}
+
+
+static void ctc_read_retry (struct channel *ctc)
+{
+ int rc = 0;
+ __u32 parm;
+ __u8 flags = 0x00;
+ __u32 saveflags;
+ net_device *dev;
+
+ dev = (net_device *) ctc->dev;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: read retry - state-%02x\n" ,dev->name, ctc->state);
+#endif
+ s390irq_spin_lock_irqsave(ctc->irq, saveflags);
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->free_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ s390irq_spin_unlock_irqrestore(ctc->irq, saveflags);
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ return;
+}
+
+
+static void ctc_write_retry (struct channel *ctc)
+{
+ int rc = 0;
+ __u32 parm;
+ __u8 flags = 0x00;
+ __u32 saveflags;
+ net_device *dev;
+
+ dev = (net_device *) ctc->dev;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: write retry - state-%02x\n" ,dev->name, ctc->state);
+#endif
+ s390irq_spin_lock_irqsave(ctc->irq, saveflags);
+ ctc->ccw[1].count = 0;
+ ctc->ccw[1].cda = (char *)virt_to_phys(ctc->proc_anchor->block);
+ parm = (__u32) ctc;
+ rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
+ s390irq_spin_unlock_irqrestore(ctc->irq, saveflags);
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ return;
+}
+
+
+
+/*
+ * ctc_open
+ *
+ */
+static int ctc_open(net_device *dev)
+{
+ int rc;
+ int i;
+ int j;
+ __u8 flags = 0x00;
+ __u32 saveflags;
+ __u32 parm;
+ struct ctc_priv *privptr;
+ DECLARE_WAITQUEUE(wait, current);
+ struct timer_list timer;
+
+
+ ctc_set_busy(dev);
+
+ privptr = (struct ctc_priv *) (dev->priv);
+
+ privptr->channel[READ].flag = 0x00;
+ privptr->channel[WRITE].flag = CTC_WRITE;
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < CTC_BLOCKS; j++) {
+ rc = ctc_buffer_alloc(&privptr->channel[i]);
+ if (rc != 0)
+ return -ENOMEM;
+ }
+ init_waitqueue_head(&privptr->channel[i].wait);
+ privptr->channel[i].tq.next = NULL;
+ privptr->channel[i].tq.sync = 0;
+ privptr->channel[i].tq.routine = (void *)(void *)ctc_irq_bh;
+ privptr->channel[i].tq.data = &privptr->channel[i];
+
+ privptr->channel[i].dev = dev;
+
+ privptr->channel[i].flag_a = 0;
+ privptr->channel[i].IO_active = 0;
+
+ privptr->channel[i].ccw[0].cmd_code = CCW_CMD_PREPARE;
+ privptr->channel[i].ccw[0].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
+ privptr->channel[i].ccw[0].count = 0;
+ privptr->channel[i].ccw[0].cda = NULL;
+ if (i == READ) {
+ privptr->channel[i].ccw[1].cmd_code = CCW_CMD_READ;
+ privptr->channel[i].ccw[1].flags = CCW_FLAG_SLI;
+ privptr->channel[i].ccw[1].count = 0xffff; /* MAX size */
+ privptr->channel[i].ccw[1].cda = NULL;
+ } else {
+ privptr->channel[i].ccw[1].cmd_code = CCW_CMD_WRITE;
+ privptr->channel[i].ccw[1].flags = CCW_FLAG_SLI | CCW_FLAG_CC;
+ privptr->channel[i].ccw[1].count = 0;
+ privptr->channel[i].ccw[1].cda = NULL;
+ }
+ privptr->channel[i].ccw[2].cmd_code = CCW_CMD_NOOP; /* jointed CE+DE */
+ privptr->channel[i].ccw[2].flags = CCW_FLAG_SLI;
+ privptr->channel[i].ccw[2].count = 0;
+ privptr->channel[i].ccw[2].cda = NULL;
+
+ privptr->channel[i].flag &= ~CTC_TIMER;
+ init_timer(&timer);
+ timer.function = (void *)ctc_timer;
+ timer.data = (__u32)&privptr->channel[i];
+ timer.expires = jiffies + 150*HZ; /* time to connect with the remote side */
+ add_timer(&timer);
+
+ s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);
+ parm = (unsigned long) &privptr->channel[i];
+ privptr->channel[i].state = CTC_START_HALT_IO;
+ rc = halt_IO(privptr->channel[i].irq, parm, flags);
+ add_wait_queue(&privptr->channel[i].wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+ s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);
+ schedule();
+ remove_wait_queue(&privptr->channel[i].wait, &wait);
+ if(rc != 0)
+ ccw_check_return_code(dev, rc);
+ if((privptr->channel[i].flag & CTC_TIMER) == 0x00)
+ del_timer(&timer);
+ }
+
+ if ((((privptr->channel[READ].last_dstat | privptr->channel[WRITE].last_dstat) &
+ ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) ||
+ (((privptr->channel[READ].flag | privptr->channel[WRITE].flag) & CTC_TIMER) != 0x00)) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: channel problems during open - read: %02x - write: %02x\n",
+ dev->name, privptr->channel[READ].last_dstat, privptr->channel[WRITE].last_dstat);
+#endif
+ printk(KERN_INFO "%s: remote side is currently not ready\n", dev->name);
+
+ for (i = 0; i < 2; i++) {
+ s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);
+ parm = (unsigned long) &privptr->channel[i];
+ privptr->channel[i].state = CTC_STOP;
+ rc = halt_IO(privptr->channel[i].irq, parm, flags);
+ s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);
+ if (rc != 0)
+ ccw_check_return_code(dev, rc);
+ for (j = 0; j < CTC_BLOCKS; j++)
+ ctc_buffer_free(&privptr->channel[i]);
+ }
+ return -EIO;
+ }
+
+ printk(KERN_INFO "%s: connected with remote side\n",dev->name);
+ ctc_clear_busy(dev);
+ return 0;
+}
+
+
+static void ctc_timer (struct channel *ctc)
+{
+#ifdef DEBUG
+ net_device *dev;
+
+ dev = (net_device *) ctc->dev;
+ printk(KERN_DEBUG "%s: timer return\n" ,dev->name);
+#endif
+ ctc->flag |= CTC_TIMER;
+ wake_up(&ctc->wait);
+ return;
+}
+
+/*
+ * ctc_release
+ *
+ */
+static int ctc_release(net_device *dev)
+{
+ int rc;
+ int i;
+ int j;
+ __u8 flags = 0x00;
+ __u32 saveflags;
+ __u32 parm;
+ struct ctc_priv *privptr;
+ DECLARE_WAITQUEUE(wait, current);
+
+ privptr = (struct ctc_priv *) dev->priv;
+
+ ctc_protect_busy_irqsave(dev,saveflags);
+ ctc_setbit_busy(TB_STOP,dev);
+ ctc_unprotect_busy_irqrestore(dev,flags);
+ for (i = 0; i < 2; i++) {
+ s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);
+ privptr->channel[i].state = CTC_STOP;
+ parm = (__u32) &privptr->channel[i];
+ rc = halt_IO (privptr->channel[i].irq, parm, flags );
+ add_wait_queue(&privptr->channel[i].wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+ s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);
+ schedule();
+ remove_wait_queue(&privptr->channel[i].wait, &wait);
+ if (rc != 0) {
+ ccw_check_return_code(dev, rc);
+ }
+
+ for (j = 0; j < CTC_BLOCKS; j++) {
+ ctc_buffer_swap(&privptr->channel[i].proc_anchor, &privptr->channel[i].free_anchor);
+ ctc_buffer_free(&privptr->channel[i]);
+ }
+ }
+
+ if (((privptr->channel[READ].last_dstat | privptr->channel[WRITE].last_dstat) &
+ ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) != 0x00) {
+ printk(KERN_WARNING "%s: channel problems during close - read: %02x - write: %02x\n",
+ dev->name, privptr->channel[READ].last_dstat, privptr->channel[WRITE].last_dstat);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/*
+ * ctc_tx
+ *
+ *
+ */
+static int ctc_tx(struct sk_buff *skb, net_device *dev)
+{
+ int rc=0,rc2;
+ __u32 parm;
+ __u8 flags = 0x00;
+ __u32 saveflags;
+ struct ctc_priv *privptr;
+ struct packet *lp;
+
+
+ privptr = (struct ctc_priv *) (dev->priv);
+
+ if (skb == NULL) {
+ printk(KERN_WARNING "%s: NULL pointer as sk_buffer passed\n", dev->name);
+ privptr->stats.tx_dropped++;
+ return -EIO;
+ }
+
+ s390irq_spin_lock_irqsave(privptr->channel[WRITE].irq, saveflags);
+ if (ctc_check_busy(dev)) {
+ rc=-EBUSY;
+ goto Done;
+ }
+
+ if (ctc_test_and_setbit_busy(TB_TX,dev)) { /* set transmission to busy */
+ rc=-EBUSY;
+ goto Done;
+ }
+
+ if (65535 - privptr->channel[WRITE].free_anchor->block->length - PACKET_HEADER_LENGTH <= skb->len + PACKET_HEADER_LENGTH + 2) {
+#ifdef DEBUG
+ printk(KERN_DEBUG "%s: early swap\n", dev->name);
+#endif
+
+ ctc_buffer_swap(&privptr->channel[WRITE].free_anchor, &privptr->channel[WRITE].proc_anchor);
+ if (privptr->channel[WRITE].free_anchor == NULL){
+ ctc_setbit_busy(TB_NOBUFFER,dev);
+ rc=-EBUSY;
+ goto Done2;
+ }
+ }
+
+ if (privptr->channel[WRITE].free_anchor->block->length == 0) {
+ privptr->channel[WRITE].free_anchor->block->length = BLOCK_HEADER_LENGTH;
+ privptr->channel[WRITE].free_anchor->packets = 0;
+ }
+
+
+ (__u8 *)lp = (__u8 *) &privptr->channel[WRITE].free_anchor->block->length + privptr->channel[WRITE].free_anchor->block->length;
+ privptr->channel[WRITE].free_anchor->block->length += skb->len + PACKET_HEADER_LENGTH;
+ lp->length = skb->len + PACKET_HEADER_LENGTH;
+ lp->type = 0x0800;
+ lp->unused = 0;
+ memcpy(&lp->data, skb->data, skb->len);
+ (__u8 *) lp += lp->length;
+ lp->length = 0;
+ dev_kfree_skb(skb);
+ privptr->channel[WRITE].free_anchor->packets++;
+
+ if (test_and_set_bit(0, (void *)&privptr->channel[WRITE].IO_active) == 0) {
+ ctc_buffer_swap(&privptr->channel[WRITE].free_anchor,&privptr->channel[WRITE].proc_anchor);
+ privptr->channel[WRITE].ccw[1].count = privptr->channel[WRITE].proc_anchor->block->length;
+ privptr->channel[WRITE].ccw[1].cda = (char *)virt_to_phys(privptr->channel[WRITE].proc_anchor->block);
+ parm = (__u32) &privptr->channel[WRITE];
+ rc2 = do_IO (privptr->channel[WRITE].irq, &privptr->channel[WRITE].ccw[0], parm, 0xff, flags );
+ if (rc2 != 0)
+ ccw_check_return_code(dev, rc2);
+ dev->trans_start = jiffies;
+ }
+ if (privptr->channel[WRITE].free_anchor == NULL)
+ ctc_setbit_busy(TB_NOBUFFER,dev);
+Done2:
+ ctc_clearbit_busy(TB_TX,dev);
+Done:
+ s390irq_spin_unlock_irqrestore(privptr->channel[WRITE].irq, saveflags);
+ return(rc);
+}
+
+
+/*
+ * ctc_change_mtu
+ *
+ * S/390 can handle MTU sizes from 576 to 32760 for VM, VSE
+ * 576 to 65527 for OS/390
+ *
+ */
+static int ctc_change_mtu(net_device *dev, int new_mtu)
+{
+ if ((new_mtu < 576) || (new_mtu > 65528))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+
+/*
+ * ctc_stats
+ *
+ */
+struct net_device_stats *ctc_stats(net_device *dev)
+{
+ struct ctc_priv *privptr;
+
+ privptr = dev->priv;
+ return &privptr->stats;
+}
+
+
+/* Module code goes here */
+
+/*
+ free_irq(privptr->channel[i].irq, privptr->channel[i].devstat);
+ kfree(privptr->channel[i].devstat);
+
+*/
+/* --- This is the END my friend --- */
diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c
new file mode 100644
index 000000000..b8b365753
--- /dev/null
+++ b/drivers/s390/net/iucv.c
@@ -0,0 +1,1178 @@
+/*
+ * drivers/s390/net/iucv.c
+ * Network driver for VM using iucv
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Stefan Hegewald <hegewald@de.ibm.com>
+ * Hartmut Penner <hpenner@de.ibm.com>
+ *
+ * 2.3 Updates Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
+ * Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *
+
+ */
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/kernel.h> /* printk() */
+#include <linux/malloc.h> /* kmalloc() */
+#include <linux/errno.h> /* error codes */
+#include <linux/types.h> /* size_t */
+#include <linux/interrupt.h> /* mark_bh */
+#include <linux/netdevice.h> /* struct net_device, and other headers */
+#include <linux/inetdevice.h> /* struct net_device, and other headers */
+#include <linux/if_arp.h>
+#include <linux/rtnetlink.h>
+#include <linux/ip.h> /* struct iphdr */
+#include <linux/tcp.h> /* struct tcphdr */
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/checksum.h>
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include "iucv.h"
+
+
+
+
+#define DEBUG123
+#define MAX_DEVICES 10
+
+extern char _ascebc[];
+
+/*
+ * global structures
+ */
+static char iucv_userid[MAX_DEVICES][8];
+static char iucv_ascii_userid[MAX_DEVICES][8];
+static int iucv_pathid[MAX_DEVICES] = {0};
+static unsigned char iucv_ext_int_buffer[40] __attribute__((aligned (8))) ={0};
+static unsigned char glob_command_buffer[40] __attribute__((aligned (8)));
+
+#if LINUX_VERSION_CODE>=0x20300
+typedef struct net_device net_device;
+#else
+typedef struct device net_device;
+#endif
+net_device iucv_devs[];
+
+
+/* This structure is private to each device. It is used to pass */
+/* packets in and out, so there is place for a packet */
+struct iucv_priv {
+ struct net_device_stats stats;
+ int packetlen;
+ int status;
+ u8 *packetdata;
+ int pathid; /* used device */
+ unsigned char command_buffer[40] __attribute__((aligned (8)));
+ unsigned char ext_int_buffer[40] __attribute__((aligned (8)));
+ u8* receive_buffer;
+ int receive_buffer_len;
+ u8* send_buffer;
+ int send_buffer_len;
+ char * new_send_buf; /* send buffer ptr */
+ unsigned char recv_buf[2048]; /* size is just a guess */
+ unsigned char userid[8];
+};
+
+struct iucv_header {
+ short len;
+};
+
+
+
+static __inline__ int netif_is_busy(net_device *dev)
+{
+#if LINUX_VERSION_CODE<0x02032D
+ return(dev->tbusy);
+#else
+ return(test_bit(__LINK_STATE_XOFF,&dev->flags));
+#endif
+}
+
+
+
+#if LINUX_VERSION_CODE<0x02032D
+#define netif_enter_interrupt(dev) dev->interrupt=1
+#define netif_exit_interrupt(dev) dev->interrupt=0
+#define netif_start(dev) dev->start=1
+#define netif_stop(dev) dev->start=0
+
+static __inline__ void netif_stop_queue(net_device *dev)
+{
+ dev->tbusy=1;
+}
+
+static __inline__ void netif_start_queue(net_device *dev)
+{
+ dev->tbusy=0;
+}
+
+static __inline__ void netif_wake_queue(net_device *dev)
+{
+ dev->tbusy=0;
+ mark_bh(NET_BH);
+}
+
+#else
+#define netif_enter_interrupt(dev)
+#define netif_exit_interrupt(dev)
+#define netif_start(dev)
+#define netif_stop(dev)
+#endif
+
+
+
+/*
+ * Following the iucv primitives
+ */
+
+
+extern inline void b2f0(int code,void* parm)
+{
+ asm volatile ("LR 1,%1\n\tLR 0,%0\n\t.long 0xb2f01000" ::
+ "d" (code) ,"a" (parm) :"0", "1");
+}
+
+int iucv_enable(void *parms)
+{
+ MASK_T *parm = parms;
+ memset(parms,0,sizeof(parm));
+ parm->ipmask = 0xF8;
+ b2f0(SETMASK,parm);
+ memset(parms,0,sizeof(parm));
+ parm->ipmask = 0xF8;
+ b2f0(SETCMASK,parm);
+ return parm->iprcode;
+}
+
+
+int iucv_declare_buffer(void *parms, DCLBFR_T *buffer)
+{
+ DCLBFR_T *parm = parms;
+ memset(parms,0,sizeof(parm));
+ parm->ipflags1= 0x00;
+ parm->ipbfadr1 = virt_to_phys(buffer);
+ b2f0(DECLARE_BUFFER, parm);
+ return parm->iprcode;
+}
+
+
+int iucv_retrieve_buffer(void *parms)
+{
+ DCLBFR_T *parm = parms;
+ memset(parms,0x0,sizeof(parm));
+ parm->iprcode = 0x0;
+ b2f0(RETRIEVE_BUFFER, parm);
+ return parm->iprcode;
+}
+
+
+int iucv_connect(void *parms,
+ const char *userid,
+ const char *host,
+ const char *ipusr,
+ unsigned short * used_pathid)
+{
+ CONNECT_T *parm = parms; /* ipflags was 0x60*/
+ memset(parms,0x0,sizeof(parm));
+ parm->ipflags1 = 0x80;
+ parm->ipmsglim = 0x0a;
+ memcpy(parm->ipvmid,userid,8);
+ if (ipusr)
+ memcpy(parm->ipuser,ipusr,16);
+ memcpy(parm->iptarget,host,8);
+ b2f0(CONNECT, parm);
+ *used_pathid = parm->ippathid;
+ return parm->iprcode;
+}
+
+
+
+int iucv_accept(void *parms,int pathid)
+{
+#ifdef DEBUG
+ int i=0;
+#endif
+ ACCEPT_T *parm = parms;
+ memset(parms,0,sizeof(parm));
+ parm->ippathid = pathid;
+ parm->ipflags1 = 0x80;
+ parm->ipmsglim = 0x0a;
+#ifdef DEBUG
+ printk("iucv: iucv_accept input.\n");
+ for (i=0;i<40; i++)
+ {
+ printk("%02x ",((char *)parms)[i]);
+ }
+ printk("\n");
+#endif
+ b2f0(ACCEPT, parm);
+ return parm->iprcode;
+}
+
+
+
+int iucv_receive(void *parms,void *bufferarray,int len)
+{
+#ifdef DEBUG
+ int i=0;
+#endif
+ RECEIVE_T *parm = parms;
+ memset(parms,0x0,sizeof(parm));
+ /*parm->ipflags1 = 0x42;*/
+ parm->ipflags1 = 0x0;
+ parm->ipmsgid = 0x0;
+ parm->iptrgcls = 0x0;
+ parm->ipbfadr1 = (ULONG) virt_to_phys(bufferarray);
+ parm->ipbfln1f = len;
+ parm->ipbfln2f = 0x0;
+ b2f0(RECEIVE, parm);
+ if (parm->iprcode == 0)
+ len = parm->ipbfln1f;
+// len = len-parm->ipbfln1f;
+#ifdef DEBUG
+ printk("iucv: iucv_receive command input:\n");
+ for (i=0;i<40;i++) /* show iucv buffer before send */
+ {
+ printk("%02x ",((char *)parms)[i]);
+ }
+ printk("\n");
+
+ printk("iucv: iucv_receive data buffer:\n");
+ for (i=0;i<len;i++) /* show data received */
+ {
+ printk("%02x ",((char *)bufferarray)[i]);
+ }
+ printk("\n");
+ printk("received length: %02x ",len);
+
+#endif
+ return parm->iprcode;
+}
+
+
+int iucv_send(void *parms,int pathid,void *bufferarray,int len,
+ void *recv_buf, int recv_len)
+{
+#ifdef DEBUG
+ int i=0;
+#endif
+ SEND_T *parm = parms;
+ memset(parms,0x0,sizeof(parm));
+ /* parm->ipflags1 = 0x48; ??*/
+ parm->ippathid = pathid;
+ parm->ipflags1 = 0x14; /* any options ?? */
+ parm->ipmsgid = 0x0;
+ parm->iptrgcls = 0x0;
+ parm->ipbfadr1 = virt_to_phys(bufferarray);
+ parm->ipbfln1f = len;
+ parm->ipsrccls = 0x0;
+ parm->ipmsgtag = 0x0;
+ parm->ipbfadr2 = virt_to_phys(recv_buf);
+ parm->ipbfln2f = recv_len;
+
+
+#ifdef DEBUG
+ printk("iucv: iucv_send command input:\n");
+ for (i=0;i<40;i++) /* show iucv buffer before send */
+ {
+ printk("%02x ",((char *)parms)[i]);
+ }
+ printk("\n");
+
+ printk("iucv: iucv_send data buffer:\n");
+ for (i=0;i<len;i++) /* show send data before send */
+ {
+ printk("%02x ",((char *)bufferarray)[i]);
+ }
+ printk("\n");
+#endif
+
+ b2f0(SEND, parm);
+
+#ifdef DEBUGXX
+ printk("iucv: iucv_send buffer after send:\n");
+ for (i=0;i<len;i++) /* show send buffer after send */
+ {
+ printk("%1x",((char *)bufferarray)[i]);
+ }
+ printk("\n");
+#endif
+
+ return parm->iprcode;
+}
+
+
+
+int iucv_sever(void *parms)
+{
+ SEVER_T *parm = parms;
+ memset(parms,0x0,sizeof(parm));
+ parm->ippathid = 0x0;
+ parm->ipflags1 = 0x0;
+ parm->iprcode = 0xF;
+ memset(parm->ipuser,0,16);
+ b2f0(SEVER, parm);
+ return parm->iprcode;
+}
+
+
+#ifdef DEBUG
+/*--------------------------*/
+/* Dump buffer formatted */
+/*--------------------------*/
+static void dumpit(char* buf, int len)
+{
+ int i;
+ for (i=0;i<len;i++) {
+ if (!(i%16)&&i!=0)
+ printk("\n");
+ else if (!(i%4)&&i!=0)
+ printk(" ");
+ printk( "%02X",buf[i]);
+ }
+ if (len%16)
+ printk( "\n");
+}
+#endif
+
+
+
+/*--------------------------*/
+/* Get device from pathid */
+/*--------------------------*/
+net_device * get_device_from_pathid(int pathid)
+{
+ int i;
+ for (i=0;i<=MAX_DEVICES;i++)
+ {
+ if (iucv_pathid[i] == pathid)
+ return &iucv_devs[i];
+ }
+ printk("iucv: get_device_from_pathid: no device for pathid %X\n",pathid);
+ return 0;
+}
+
+
+
+/*--------------------------*/
+/* Get device from userid */
+/*--------------------------*/
+net_device * get_device_from_userid(char * userid)
+{
+ int i;
+ net_device * dev;
+ struct iucv_priv *privptr;
+ for (i=0;i<=MAX_DEVICES;i++)
+ {
+ dev = &iucv_devs[i];
+ privptr = (struct iucv_priv *)(dev->priv);
+ if (memcmp(privptr->userid,userid,8)==0)
+ return &iucv_devs[i];
+ }
+ printk("iucv: get_device_from_uid: no device for userid %s\n",userid);
+ return 0;
+}
+
+
+/*--------------------------*/
+/* Open iucv Device Driver */
+/*--------------------------*/
+int iucv_open(net_device *dev)
+{
+ int rc;
+ unsigned short iucv_used_pathid;
+ struct iucv_priv *privptr;
+ char iucv_host[8] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+ char vmident[16] ={0xf0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
+ 0xf0,0x40,0x40,0x40,0x40,0x40,0x40,0x40};
+
+#ifdef DEBUG
+ printk( "iucv: iucv_open, device: %s\n",dev->name);
+#endif
+
+ privptr = (struct iucv_priv *)(dev->priv);
+ if(privptr->pathid != -1) {
+ netif_start(dev);
+ netif_start_queue(dev);
+ return 0;
+ }
+ if ((rc = iucv_connect(privptr->command_buffer,
+ privptr->userid,
+ iucv_host,
+ vmident,
+ &iucv_used_pathid))!=0) {
+ printk( "iucv: iucv connect failed with rc %X\n",rc);
+ iucv_retrieve_buffer(privptr->command_buffer);
+ return -ENODEV;
+ }
+
+ privptr->pathid = iucv_used_pathid;
+ iucv_pathid[dev-iucv_devs]=privptr->pathid;
+
+#ifdef DEBUG
+ printk( "iucv: iucv_connect ended with rc: %X\n",rc);
+ printk( "iucv[%d] pathid %X \n",(int)(dev-iucv_devs),privptr->pathid);
+#endif
+ netif_start(dev);
+ netif_start_queue(dev);
+ return 0;
+}
+
+
+
+/*-----------------------------------------------------------------------*/
+/* Receive a packet: retrieve, encapsulate and pass over to upper levels */
+/*-----------------------------------------------------------------------*/
+void iucv_rx(net_device *dev, int len, unsigned char *buf)
+{
+
+ struct sk_buff *skb;
+ struct iucv_priv *privptr = (struct iucv_priv *)dev->priv;
+
+#ifdef DEBUG
+ printk( "iucv: iucv_rx len: %X, device %s\n",len,dev->name);
+ printk( "iucv rx: received orig:\n");
+ dumpit(buf,len);
+#endif
+
+ /* strip iucv header now */
+ len = len - 2; /* short header */
+ buf = buf + 2; /* short header */
+
+ skb = dev_alloc_skb(len+2); /* why +2 ? alignment ? */
+ if (!skb) {
+ printk( "iucv rx: low on mem, returning...\n");
+ return;
+ }
+ skb_reserve(skb, 2); /* align IP on 16B boundary*/
+ memcpy(skb_put(skb, len), buf, len);
+#ifdef DEBUG
+ printk( "iucv rx: data before netif_rx()\n");
+ dumpit(buf,len);
+#endif
+
+ /* Write metadata, and then pass to the receive level */
+ skb->mac.raw = skb->data;
+ skb->pkt_type = PACKET_HOST;
+ skb->dev = dev;
+ skb->protocol = htons(ETH_P_IP);
+ skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it*/
+ privptr->stats.rx_packets++;
+ netif_rx(skb);
+
+ return;
+} /* end iucv_rx() */
+
+
+
+
+/*----------------------------*/
+/* handle interrupts */
+/*----------------------------*/
+void do_iucv_interrupt(void)
+{
+ int rc;
+ struct in_device *indev;
+ struct in_ifaddr *inaddr;
+ unsigned long len=0;
+ net_device *dev=0;
+ struct iucv_priv *privptr;
+ INTERRUPT_T * extern_int_buffer;
+ unsigned short iucv_data_len=0;
+ unsigned short iucv_next=0;
+ unsigned char * rcvptr;
+
+ /* get own buffer: */
+ extern_int_buffer = (INTERRUPT_T*) iucv_ext_int_buffer;
+
+ netif_enter_interrupt(dev); /* lock ! */
+
+#ifdef DEBUG
+ printk( "iucv: do_iucv_interrupt %x received; pathid: %02X\n",
+ extern_int_buffer->iptype,extern_int_buffer->ippathid);
+ printk( "iucv: extern_int_buffer:\n");
+ dumpit((char *)&extern_int_buffer[0],40);
+#endif
+
+ switch (extern_int_buffer->iptype)
+ {
+ case 0x01: /* connection pending ext interrrupt */
+#ifdef DEBUG
+ printk( "iucv: connection pending IRQ.\n");
+#endif
+
+ rc = iucv_accept(glob_command_buffer,
+ extern_int_buffer->ippathid);
+ if (rc != 0) {
+ printk( "iucv: iucv_accept failed with rc: %X\n",rc);
+ iucv_retrieve_buffer(glob_command_buffer);
+ break;
+ }
+#ifdef DEBUG
+ dumpit(&((char *)extern_int_buffer)[8],8);
+#endif
+ dev = get_device_from_userid(&((char*)extern_int_buffer)[8]);
+ privptr = (struct iucv_priv *)(dev->priv);
+ privptr->pathid = extern_int_buffer->ippathid;
+
+#ifdef DEBUG
+ printk( "iucv: iucv_accept ended with rc: %X\n",rc);
+ printk( "iucv: device %s found.\n",dev->name);
+#endif
+ break;
+
+ case 0x02: /* connection completed ext interrrupt */
+ /* set own global IP address */
+ /* & set global routing addr */
+#ifdef DEBUG
+ printk( "connection completed.\n");
+#endif
+
+ if( extern_int_buffer->ipmsgtag !=0)
+ {
+ /* get ptr's to kernel struct with local & broadcast address */
+ dev = get_device_from_pathid(extern_int_buffer->ippathid);
+ privptr = (struct iucv_priv *)(dev->priv);
+ indev = dev->ip_ptr;
+ inaddr = (struct in_ifaddr*) indev->ifa_list;
+ }
+ break;
+
+
+ case 0x03: /* connection severed ext interrrupt */
+ /* we do not handle this one at this time */
+#ifdef DEBUG
+ printk( "connection severed.\n");
+#endif
+ break;
+
+
+ case 0x04: /* connection quiesced ext interrrupt */
+ /* we do not handle this one at this time */
+#ifdef DEBUG
+ printk( "connection quiesced.\n");
+#endif
+ break;
+
+
+ case 0x05: /* connection resumed ext interrrupt */
+ /* we do not handle this one at this time */
+#ifdef DEBUG
+ printk( "connection resumed.\n");
+#endif
+ break;
+
+
+ case 0x06: /* priority message complete ext interrupt */
+ case 0x07: /* non priority message complete ext interrupt */
+ /* send it to iucv_rx for handling */
+#ifdef DEBUG
+ printk( "message completed.\n");
+#endif
+
+ if (extern_int_buffer->ipaudit ==0) /* ok case */
+ {
+#ifdef DEBUG
+ printk( "iucv: msg complete interrupt successful, rc: %X\n",
+ (unsigned int)extern_int_buffer->ipaudit);
+#endif
+ ;
+ }
+ else
+ {
+ printk( "iucv: msg complete interrupt error, rc: %X\n",
+ (unsigned int)extern_int_buffer->ipaudit);
+ }
+ /* a transmission is over: tell we are no more busy */
+ dev = get_device_from_pathid(extern_int_buffer->ippathid);
+ privptr = (struct iucv_priv *)(dev->priv);
+ privptr->stats.tx_packets++;
+ netif_wake_queue(dev); /* transmission is no longer busy*/
+ break;
+
+
+ case 0x08: /* priority message pending */
+ case 0x09: /* non priority message pending */
+#ifdef DEBUG
+ printk( "message pending.\n");
+#endif
+ dev = get_device_from_pathid(extern_int_buffer->ippathid);
+ privptr = (struct iucv_priv *)(dev->priv);
+ rcvptr = &privptr->receive_buffer[0];
+
+ /* re-set receive buffer */
+ memset(privptr->receive_buffer,0,privptr->receive_buffer_len);
+ len = privptr->receive_buffer_len;
+
+ /* get data now */
+ if (extern_int_buffer->ipflags1 & 0x80)
+ { /* data is in the message */
+#ifdef DEBUG
+ printk( "iucv: iucv_receive data is in header!\n");
+#endif
+ memcpy(privptr->receive_buffer,
+ (char *)extern_int_buffer->iprmmsg1,
+ (unsigned long)(extern_int_buffer->iprmmsg2));
+ }
+ else /* data is in buffer, do a receive */
+ {
+ rc = iucv_receive(privptr->command_buffer,rcvptr,len);
+ if (rc != 0 || len == 0)
+ {
+ printk( "iucv: iucv_receive failed with rc: %X, length: %lX\n",rc,len);
+ iucv_retrieve_buffer(privptr->command_buffer);
+ break;
+ }
+ } /* end else */
+
+ iucv_next = 0;
+ /* get next packet offset */
+ iucv_data_len= *((unsigned short*)rcvptr);
+ do{ /* until receive buffer is empty, i.e. iucv_next == 0 ! */
+
+ /* get data length: */
+ iucv_data_len= iucv_data_len - iucv_next;
+
+#ifdef DEBUG
+ printk( "iucv: iucv_receive: len is %02X, last: %02X\n",
+ iucv_data_len,iucv_next);
+#endif
+ /* transmit upstairs */
+ iucv_rx(dev,(iucv_data_len),rcvptr);
+
+#ifdef DEBUG
+ printk( "iucv: transaction complete now.\n");
+#endif
+ iucv_next = *((unsigned short*)rcvptr);
+ rcvptr = rcvptr + iucv_data_len;
+ /* get next packet offset */
+ iucv_data_len= *((unsigned short*)rcvptr);
+
+ } while (iucv_data_len != 0);
+ netif_start_queue(dev); /* transmission is no longer busy*/
+ break;
+
+ default:
+ printk( "unknown iucv interrupt \n");
+ break;
+
+ } /* end switch */
+ netif_exit_interrupt(dev); /* release lock*/
+
+#ifdef DEBUG
+ printk( "iucv: leaving do_iucv_interrupt.\n");
+#endif
+
+} /* end do_iucv_interrupt() */
+
+
+
+/*-------------------------------------------*/
+/* Transmit a packet (low level interface) */
+/*-------------------------------------------*/
+int iucv_hw_tx(char *send_buf, int len,net_device *dev)
+{
+ /* This function deals with hw details. */
+ /* This interface strips off the ethernet header details. */
+ /* In other words, this function implements the iucv behaviour,*/
+ /* while all other procedures are rather device-independent */
+ struct iucv_priv *privptr;
+ int rc, recv_len=2000;
+
+ privptr = (struct iucv_priv *)(dev->priv);
+
+#ifdef DEBUG
+ printk( "iucv: iucv_hw_tx, device %s\n",dev->name);
+ printk( "iucv: hw_TX_data len: %X\n",len);
+ dumpit(send_buf,len);
+#endif
+
+ /* I am paranoid. Ain't I? */
+ if (len < sizeof(struct iphdr))
+ {
+ printk( "iucv: Hmm... packet too short (%i octets)\n",len);
+ return -EINVAL;
+ }
+
+ /*
+ * build IUCV header (preceeding halfword offset)
+ * works as follows: Each packet is preceded by the
+ * halfword offset to the next one.
+ * The last packet is followed by an offset of zero.
+ * E.g., AL2(12),10-byte packet, AL2(34), 32-byte packet, AL2(0)
+ */
+
+ memcpy(&privptr->send_buffer[2],send_buf,len+2);
+ privptr->send_buffer[len+2] = 0;
+ privptr->send_buffer[len+3] = 0;
+ *((unsigned short*) &privptr->send_buffer[0]) = len + 2;
+
+#ifdef DEBUG
+ printk( "iucv: iucv_hw_tx, device %s\n",dev->name);
+ printk( "iucv: send len: %X\n",len+4);
+ dumpit(privptr->send_buffer,len+4);
+#endif
+ *((unsigned short*) &privptr->send_buffer[0]) = len + 2;
+
+ /* Ok, now the packet is ready for transmission: send it. */
+ if ((rc = iucv_send(privptr->command_buffer,
+ privptr->pathid,
+ &privptr->send_buffer[0],len+4,
+ privptr->recv_buf,recv_len))!=0) {
+ printk( "iucv: send_iucv failed, rc: %X\n",rc);
+ iucv_retrieve_buffer(privptr->command_buffer);
+ }
+#ifdef DEBUG
+ printk( "iucv: send_iucv ended, rc: %X\n",rc);
+#endif
+ return rc;
+} /* end iucv_hw_tx() */
+
+
+
+
+
+
+/*------------------------------------------*/
+/* Transmit a packet (called by the kernel) */
+/*------------------------------------------*/
+int iucv_tx(struct sk_buff *skb, net_device *dev)
+{
+ int retval=0;
+
+ struct iucv_priv *privptr;
+
+ if (dev == NULL)
+ {
+ printk("iucv: NULL dev passed\n");
+ return 0;
+ }
+
+ privptr = (struct iucv_priv *) (dev->priv);
+
+ if (skb == NULL)
+ {
+ printk("iucv: %s: NULL buffer passed\n", dev->name);
+ privptr->stats.tx_errors++;
+ return 0;
+ }
+
+#ifdef DEBUG
+ printk( "iucv: enter iucv_tx, using %s\n",dev->name);
+#endif
+
+ if (netif_is_busy(dev)) /* shouldn't happen */
+ {
+ privptr->stats.tx_errors++;
+ dev_kfree_skb(skb);
+ printk("iucv: %s: transmit access conflict ! leaving iucv_tx.\n", dev->name);
+ }
+
+ netif_stop_queue(dev); /* transmission is busy*/
+ dev->trans_start = jiffies; /* save the timestamp*/
+
+ /* actual deliver of data is device-specific, and not shown here */
+ retval = iucv_hw_tx(skb->data, skb->len, dev);
+
+ dev_kfree_skb(skb); /* release it*/
+
+#ifdef DEBUG
+ printk( "iucv:leaving iucv_tx, device %s\n",dev->name);
+#endif
+
+ return retval; /* zero == done; nonzero == fail*/
+} /* end iucv_tx( struct sk_buff *skb, struct device *dev) */
+
+
+
+
+
+
+/*---------------*/
+/* iucv_release */
+/*---------------*/
+int iucv_release(net_device *dev)
+{
+ int rc =0;
+ struct iucv_priv *privptr;
+ privptr = (struct iucv_priv *) (dev->priv);
+
+ netif_stop(dev);
+ netif_stop_queue(dev); /* can't transmit any more*/
+ rc = iucv_sever(privptr->command_buffer);
+ if (rc!=0)
+ {
+ printk("iucv: %s: iucv_release pending...rc:%02x\n",dev->name,rc);
+ }
+
+#ifdef DEBUG
+ printk("iucv: iucv_sever ended with rc: %X\n",rc);
+#endif
+
+ return rc;
+} /* end iucv_release() */
+
+
+
+
+
+/*-----------------------------------------------*/
+/* Configuration changes (passed on by ifconfig) */
+/*-----------------------------------------------*/
+int iucv_config(net_device *dev, struct ifmap *map)
+{
+ if (dev->flags & IFF_UP) /* can't act on a running interface*/
+ return -EBUSY;
+
+ /* ignore other fields */
+ return 0;
+}
+/* end iucv_config() */
+
+
+
+
+
+/*----------------*/
+/* Ioctl commands */
+/*----------------*/
+int iucv_ioctl(net_device *dev, struct ifreq *rq, int cmd)
+{
+#ifdef DEBUG
+ printk( "iucv: device %s; iucv_ioctl\n",dev->name);
+#endif
+ return 0;
+}
+
+/*---------------------------------*/
+/* Return statistics to the caller */
+/*---------------------------------*/
+struct net_device_stats *iucv_stats(net_device *dev)
+{
+ struct iucv_priv *priv = (struct iucv_priv *)dev->priv;
+#ifdef DEBUG
+ printk( "iucv: device %s; iucv_stats\n",dev->name);
+#endif
+ return &priv->stats;
+}
+
+
+/*
+ * iucv_change_mtu
+ * IUCV can handle MTU sizes from 576 to approx. 32000
+ */
+
+static int iucv_change_mtu(net_device *dev, int new_mtu)
+{
+#ifdef DEBUG
+ printk( "iucv: device %s; iucv_change_mtu\n",dev->name);
+#endif
+ if ((new_mtu < 64) || (new_mtu > 32000))
+ return -EINVAL;
+ dev->mtu = new_mtu;
+ return 0;
+}
+
+
+
+
+/*--------------------------------------------*/
+/* The init function (sometimes called probe).*/
+/* It is invoked by register_netdev() */
+/*--------------------------------------------*/
+int iucv_init(net_device *dev)
+{
+ int rc;
+ struct iucv_priv *privptr;
+
+#ifdef DEBUG
+ printk( "iucv: iucv_init, device: %s\n",dev->name);
+#endif
+
+ dev->open = iucv_open;
+ dev->stop = iucv_release;
+ dev->set_config = iucv_config;
+ dev->hard_start_xmit = iucv_tx;
+ dev->do_ioctl = iucv_ioctl;
+ dev->get_stats = iucv_stats;
+ dev->change_mtu = iucv_change_mtu;
+
+ /* keep the default flags, just add NOARP */
+
+ dev->hard_header_len = 0;
+ dev->addr_len = 0;
+ dev->type = ARPHRD_SLIP;
+ dev->tx_queue_len = 100;
+ dev->flags = IFF_NOARP|IFF_POINTOPOINT;
+ dev->mtu = 4092;
+
+ dev_init_buffers(dev);
+
+ /* Then, allocate the priv field. This encloses the statistics */
+ /* and a few private fields.*/
+ dev->priv = kmalloc(sizeof(struct iucv_priv), GFP_KERNEL);
+ if (dev->priv == NULL){
+ printk( "iucv: no memory for dev->priv.\n");
+ return -ENOMEM;
+ }
+ memset(dev->priv, 0, sizeof(struct iucv_priv));
+ privptr = (struct iucv_priv *)(dev->priv);
+
+
+ privptr->send_buffer = (u8*) __get_free_pages(GFP_KERNEL+GFP_DMA,8);
+ if (privptr->send_buffer == NULL) {
+ printk(KERN_INFO "%s: could not get pages for send buffer\n",
+ dev->name);
+ return -ENOMEM;
+ }
+ memset(privptr->send_buffer, 0, 8*PAGE_SIZE);
+ privptr->send_buffer_len=8*PAGE_SIZE;
+
+ privptr->receive_buffer = (u8*) __get_free_pages(GFP_KERNEL+GFP_DMA,8);
+ if (privptr->receive_buffer == NULL) {
+ printk(KERN_INFO "%s: could not get pages for receive buffer\n",
+ dev->name);
+ return -ENOMEM;
+ }
+ memset(privptr->receive_buffer, 0, 8*PAGE_SIZE);
+ privptr->receive_buffer_len=8*PAGE_SIZE;
+
+ /* now use the private fields ... */
+ /* init pathid */
+ privptr->pathid = -1;
+
+ /* init private userid from global userid */
+ memcpy(privptr->userid,iucv_userid[dev-iucv_devs],8);
+
+
+ /* we can use only ONE buffer for external interrupt ! */
+ rc=iucv_declare_buffer(privptr->command_buffer,
+ (DCLBFR_T *)iucv_ext_int_buffer);
+ if (rc!=0 && rc!=19) /* ignore existing buffer */
+ {
+ printk( "iucv:iucv_declare failed, rc: %X\n",rc);
+ return -ENODEV;
+ }
+
+ rc = iucv_enable(privptr->command_buffer);
+ if (rc!=0)
+ {
+ printk( "iucv:iucv_enable failed, rc: %x\n",rc);
+ iucv_retrieve_buffer(privptr->command_buffer);
+ return -ENODEV;
+ }
+#ifdef DEBUG
+ printk( "iucv: iucv_init endend OK for device %s.\n",dev->name);
+#endif
+ return 0;
+}
+
+
+/*
+ * setup iucv devices
+ *
+ * string passed: iucv=userid1,...,useridn
+ */
+#if LINUX_VERSION_CODE>=0x020300
+static int __init iucv_setup(char *str)
+#else
+__initfunc(void iucv_setup(char *str,int *ints))
+#endif
+{
+ int result=0, i=0,j=0, k=0, device_present=0;
+ char *s = str;
+ net_device * dev ={0};
+
+#ifdef DEBUG
+ printk( "iucv: start registering device(s)... \n");
+#endif
+
+ /*
+ * scan device userids
+ */
+
+ while(*s != 0x20 && *s != '\0'){
+ if(*s == ','){
+ /* fill userid up to 8 chars */
+ for(k=i;k<8;k++){
+ iucv_userid[j][k] = 0x40;
+ } /* end for */
+ /* new device */
+ j++;
+ s++; /* ignore current char */
+ i=0;
+ if (j>MAX_DEVICES) {
+ printk("iucv: setup devices: max devices %d reached.\n",
+ MAX_DEVICES);
+ break;
+ } /* end if */
+ continue;
+ } /* end if */
+ iucv_ascii_userid[j][i] = (int)*s;
+ iucv_userid[j][i] = _ascebc[(int)*s++];
+ i++;
+ } /* end while */
+
+ /*
+ * fill last userid up to 8 chars
+ */
+ for(k=i;k<8;k++) {
+ iucv_userid[j][k] = 0x40;
+ }
+
+ /*
+ * set device name and register
+ */
+
+ for (k=0;k<=j;k++) {
+ memcpy(iucv_devs[k].name, "iucv0", 4);
+ dev = &iucv_devs[k];
+ dev->name[4] = k + '0';
+
+#ifdef DEBUGX
+ printk("iucv: (ASCII- )Userid:%s\n",&iucv_ascii_userid[k][0]);
+ printk("iucv: (ASCII-)Userid: ");
+ for (i=0;i<8;i++) {
+ printk( "%02X ",(int)iucv_ascii_userid[k][i]);
+ }
+ printk("\n");
+ printk("iucv: (EBCDIC-)Userid: ");
+ for (i=0;i<8;i++) {
+ printk( "%02X ",(int)iucv_userid[k][i]);
+ }
+ printk("\n");
+ printk("iucv: device name :%s\n",iucv_devs[k].name);
+#endif
+
+ if ( (result = register_netdev(iucv_devs + k)) )
+ printk("iucv: error %i registering device \"%s\"\n",
+ result, iucv_devs[k].name);
+ else
+ {
+ device_present++;
+ }
+ } /* end for */
+
+#ifdef DEBUG
+ printk( "iucv: end register devices, %d devices present\n",device_present);
+#endif
+ /* return device_present ? 0 : -ENODEV; */
+#if LINUX_VERSION_CODE>=0x020300
+ return 1;
+#else
+ return;
+#endif
+}
+
+#if LINUX_VERSION_CODE>=0x020300
+__setup("iucv=", iucv_setup);
+#endif
+
+
+/*-------------*/
+/* The devices */
+/*-------------*/
+char iucv_names[MAX_DEVICES*8]; /* MAX_DEVICES eight-byte buffers */
+net_device iucv_devs[MAX_DEVICES] = {
+ {
+ iucv_names, /* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+8,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+16,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+24,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+32,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+40,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+48,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+56,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+64,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ },
+ {
+ iucv_names+72,/* name -- set at load time */
+ 0, 0, 0, 0, /* shmem addresses */
+ 0x000, /* ioport */
+ 0, /* irq line */
+ 0, 0, 0, /* various flags: init to 0 */
+ NULL, /* next ptr */
+ iucv_init, /* init function, fill other fields with NULL's */
+ }
+};
+
diff --git a/drivers/s390/net/iucv.h b/drivers/s390/net/iucv.h
new file mode 100644
index 000000000..7905fb49a
--- /dev/null
+++ b/drivers/s390/net/iucv.h
@@ -0,0 +1,146 @@
+/*
+ * drivers/s390/net/iucv.h
+ * Network driver for VM using iucv
+ *
+ * S390 version
+ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
+ * Author(s): Stefan Hegewald <hegewald@de.ibm.com>
+ * Hartmut Penner <hpenner@de.ibm.com>
+ */
+
+#ifndef _IUCV_H
+#define _IUCV_H
+
+
+#define UCHAR unsigned char
+#define USHORT unsigned short
+#define ULONG unsigned long
+
+#define DEFAULT_BUFFERSIZE 2048
+#define DEFAULT_FN_LENGTH 27
+#define TRANSFERLENGTH 10
+
+
+
+/* function ID's */
+#define RETRIEVE_BUFFER 2
+#define REPLY 3
+#define SEND 4
+#define RECEIVE 5
+#define ACCEPT 10
+#define CONNECT 11
+#define DECLARE_BUFFER 12
+#define SEVER 15
+#define SETMASK 16
+#define SETCMASK 17
+#define PURGE 9999
+
+/* structures */
+typedef struct {
+ USHORT res0;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ ULONG res1;
+ ULONG res2;
+ ULONG ipbfadr1;
+ ULONG res[6];
+} DCLBFR_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ USHORT ipmsglim;
+ USHORT res1;
+ UCHAR ipvmid[8];
+ UCHAR ipuser[16];
+ UCHAR iptarget[8];
+} CONNECT_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ USHORT ipmsglim;
+ USHORT res1;
+ UCHAR res2[8];
+ UCHAR ipuser[16];
+ UCHAR res3[8];
+} ACCEPT_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ ULONG ipmsgid;
+ ULONG iptrgcls;
+ ULONG ipbfadr1;
+ ULONG ipbfln1f;
+ ULONG ipsrccls;
+ ULONG ipmsgtag;
+ ULONG ipbfadr2;
+ ULONG ipbfln2f;
+ ULONG res;
+} SEND_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ ULONG ipmsgid;
+ ULONG iptrgcls;
+ ULONG iprmmsg1;
+ ULONG iprmmsg2;
+ ULONG res1[2];
+ ULONG ipbfadr2;
+ ULONG ipbfln2f;
+ ULONG res2;
+} REPLY_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ ULONG ipmsgid;
+ ULONG iptrgcls;
+ ULONG ipbfadr1;
+ ULONG ipbfln1f;
+ ULONG res1[3];
+ ULONG ipbfln2f;
+ ULONG res2;
+} RECEIVE_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iprcode;
+ ULONG res1[3];
+ UCHAR ipuser[16];
+ ULONG res2[2];
+} SEVER_T;
+
+typedef struct {
+ UCHAR ipmask;
+ UCHAR res1[2];
+ UCHAR iprcode;
+ ULONG res2[9];
+} MASK_T;
+
+typedef struct {
+ USHORT ippathid;
+ UCHAR ipflags1;
+ UCHAR iptype;
+ ULONG ipmsgid;
+ ULONG ipaudit;
+ ULONG iprmmsg1;
+ ULONG iprmmsg2;
+ ULONG ipsrccls;
+ ULONG ipmsgtag;
+ ULONG ipbfadr2;
+ ULONG ipbfln2f;
+ UCHAR ippollfg;
+ UCHAR res2[3];
+} INTERRUPT_T;
+
+
+#endif
diff --git a/drivers/sound/maestro.c b/drivers/sound/maestro.c
index 12da6bbc0..81a7d21d2 100644
--- a/drivers/sound/maestro.c
+++ b/drivers/sound/maestro.c
@@ -2381,8 +2381,20 @@ static unsigned int ess_poll(struct file *file, struct poll_table_struct *wait)
struct ess_state *s = (struct ess_state *)file->private_data;
unsigned long flags;
unsigned int mask = 0;
+ int ret;
VALIDATE_STATE(s);
+
+/* In 0.14 prog_dmabuf always returns success anyway ... */
+ if (file->f_mode & FMODE_WRITE) {
+ if (!s->dma_dac.ready && (ret = prog_dmabuf(s, 0)))
+ return POLLERR;
+ }
+ if (file->f_mode & FMODE_READ) {
+ if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))
+ return POLLERR;
+ }
+
if (file->f_mode & FMODE_WRITE)
poll_wait(file, &s->dma_dac.wait, wait);
if (file->f_mode & FMODE_READ)
diff --git a/drivers/sound/via82cxxx_audio.c b/drivers/sound/via82cxxx_audio.c
index 1807e3db6..47bac97d8 100644
--- a/drivers/sound/via82cxxx_audio.c
+++ b/drivers/sound/via82cxxx_audio.c
@@ -11,7 +11,7 @@
*/
-#define VIA_VERSION "1.1.5"
+#define VIA_VERSION "1.1.6"
#include <linux/config.h>
@@ -23,6 +23,7 @@
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/sound.h>
+#include <linux/poll.h>
#include <linux/soundcard.h>
#include <linux/ac97_codec.h>
#include <asm/io.h>
@@ -30,8 +31,9 @@
#include <asm/uaccess.h>
#include <asm/hardirq.h>
-#include "sound_config.h"
-#include "soundmodule.h"
+/* much better to duplicate this value than include
+ * drivers/sound/sound_config.h just for this definition */
+#define SND_DEV_DSP16 5
#undef VIA_DEBUG /* define to enable debugging output and checks */
@@ -286,7 +288,6 @@ static int via_dsp_release(struct inode *inode, struct file *file);
static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg);
static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value);
static u8 via_ac97_wait_idle (struct via_info *card);
-static u32 via_ac97_wait_valid (struct via_info *card);
static void via_chan_free (struct via_info *card, struct via_channel *chan);
static void via_chan_clear (struct via_channel *chan);
@@ -403,11 +404,6 @@ static void via_stop_everything (struct via_info *card)
static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply)
{
-#if 0
- unsigned long flags;
- u32 status;
- u8 status8;
-#endif
DPRINTK ("ENTER, rate = %d, inhale = %s\n",
rate, inhale_deeply ? "yes" : "no");
@@ -415,37 +411,12 @@ static int via_set_rate (struct via_info *card, unsigned rate, int inhale_deeply
if (rate > 48000) rate = 48000;
if (rate < 4000) rate = 4000;
-#if 0
- status8 = via_ac97_wait_idle (card);
- if (status8 & VIA_CR83_BUSY) {
- DPRINTK ("EXIT, status=0x%X, returning -EIO\n", status);
- return -EIO;
- }
-
- if (inhale_deeply) {
- card->ch_in.rate = rate;
-
- spin_lock_irqsave (&card->lock, flags);
- outl (VIA_SET_RATE_IN + rate,
- card->baseaddr + VIA_BASE0_AC97_CTRL);
- spin_unlock_irqrestore (&card->lock, flags);
- } else {
- card->ch_out.rate = rate;
-
- spin_lock_irqsave (&card->lock, flags);
- outl (VIA_SET_RATE_OUT + rate,
- card->baseaddr + VIA_BASE0_AC97_CTRL);
- spin_unlock_irqrestore (&card->lock, flags);
- }
-
-#else
via_ac97_write_reg (&card->ac97, AC97_POWER_CONTROL,
(via_ac97_read_reg (&card->ac97, AC97_POWER_CONTROL) & ~0x0200) |
0x0200);
via_ac97_write_reg (&card->ac97, AC97_PCM_FRONT_DAC_RATE, rate);
via_ac97_write_reg (&card->ac97, AC97_POWER_CONTROL,
via_ac97_read_reg (&card->ac97, AC97_POWER_CONTROL) & ~0x0200);
-#endif
DPRINTK ("EXIT, returning 0\n");
return rate;
@@ -769,38 +740,6 @@ static u8 via_ac97_wait_idle (struct via_info *card)
}
-static u32 via_ac97_wait_valid (struct via_info *card)
-{
- u32 tmp;
- int counter = VIA_COUNTER_LIMIT;
-
- DPRINTK ("ENTER\n");
-
- assert (card != NULL);
- assert (card->pdev != NULL);
-
- do {
- if (current->need_resched)
- schedule ();
-
- spin_lock_irq (&card->lock);
- tmp = inl (card->baseaddr + VIA_BASE0_AC97_CTRL);
- spin_unlock_irq (&card->lock);
-
- udelay (10);
-
- if (tmp & VIA_CR80_FIRST_CODEC_VALID) {
- DPRINTK ("EXIT valid, tmp=0x%X, cnt=%d\n", tmp, counter);
- return tmp;
- }
- } while ((tmp & VIA_CR80_BUSY) && (counter-- > 0));
-
- DPRINTK ("EXIT, tmp=0x%X, cnt=%d%s\n", tmp, counter,
- counter > 0 ? "" : ", counter limit reached");
- return tmp;
-}
-
-
static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg)
{
u32 data;
@@ -957,6 +896,7 @@ static struct file_operations via_mixer_fops = {
};
+#if 0 /* values reasoned from debugging dumps of via's driver */
static struct {
u8 reg;
u16 data;
@@ -976,6 +916,7 @@ static struct {
{ 0x2, 0x808 },
{ 0x18, 0x808 },
};
+#endif
static int __init via_ac97_reset (struct via_info *card)
@@ -983,7 +924,6 @@ static int __init via_ac97_reset (struct via_info *card)
struct pci_dev *pdev = card->pdev;
u8 tmp8;
u16 tmp16;
- size_t idx;
DPRINTK ("ENTER\n");
@@ -1015,8 +955,6 @@ static int __init via_ac97_reset (struct via_info *card)
}
#endif
-#if 1
-
/*
* reset AC97 controller: enable, disable, enable
* pause after each command for good luck
@@ -1032,35 +970,6 @@ static int __init via_ac97_reset (struct via_info *card)
VIA_CR41_AC97_ENABLE | VIA_CR41_PCM_ENABLE |
VIA_CR41_VRA | VIA_CR41_AC97_RESET);
udelay (100);
-#endif
-
-#if 0
- /*
- * reset AC97 controller
- */
- pci_read_config_byte(pdev, 0x08, &tmp8);
- if ((tmp8 & 0xff) >= 0x20 ) {
- pci_read_config_byte(pdev, 0x42, &tmp8);
- pci_write_config_byte(pdev, 0x42,(tmp8 & 0x3f));
- }
- udelay (100);
-
- /* init other mixer defaults */
- for (idx = 0; idx < arraysize(mixer_init_vals); idx++) {
- via_ac97_write_reg (&card->ac97,
- mixer_init_vals[idx].reg,
- mixer_init_vals[idx].data);
- udelay (20);
- }
-
- pci_write_config_byte (pdev, 0x41, 0xc0);
- udelay (10);
- pci_read_config_byte (pdev, 0x41, &tmp8);
- udelay (10);
- pci_write_config_byte (pdev, 0x41, tmp8 | 0x0f);
- udelay (10);
-
-#endif
/* disable legacy stuff */
pci_write_config_byte (pdev, 0x42, 0x00);
@@ -1073,16 +982,6 @@ static int __init via_ac97_reset (struct via_info *card)
/* disable all codec GPI interrupts */
outl (0, pci_resource_start (pdev, 0) + 0x8C);
-#if 0 /* ALSA */
- via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS, 0x0009);
-#if 0
- via_ac97_write_reg (&card->ac97, AC97_POWER_CONTROL,
- via_ac97_read_reg (&card->ac97, AC97_POWER_CONTROL) | 0x0300);
-#endif
- via_ac97_write_reg (&card->ac97, AC97_EXTENDED_STATUS,
- via_ac97_read_reg (&card->ac97, AC97_EXTENDED_STATUS) | 0xe800);
-#endif
-
/* enable variable rate */
tmp16 = via_ac97_read_reg (&card->ac97, 0x2A);
via_ac97_write_reg (&card->ac97, 0x2A, tmp16 | 0x01);
@@ -1836,24 +1735,24 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
return -EINVAL;
if (val > 0) {
rc = 0;
- spin_lock_irqsave (&card->lock, flags);
+ spin_lock_irq (&card->lock);
if (rc == 0 && rd)
rc = via_chan_set_speed (card, &card->ch_in, val);
if (rc == 0 && wr)
rc = via_chan_set_speed (card, &card->ch_out, val);
- spin_unlock_irqrestore (&card->lock, flags);
+ spin_unlock_irq (&card->lock);
if (rc <= 0)
return rc ? rc : -EINVAL;
val = rc;
} else {
- spin_lock_irqsave (&card->lock, flags);
+ spin_lock_irq (&card->lock);
if (rd)
val = card->ch_in.rate;
else if (wr)
val = card->ch_out.rate;
else
val = 0;
- spin_unlock_irqrestore (&card->lock, flags);
+ spin_unlock_irq (&card->lock);
}
DPRINTK("SPEED EXIT, returning %d\n", val);
return put_user (val, (int *)arg);
@@ -1868,18 +1767,16 @@ static int via_dsp_ioctl (struct inode *inode, struct file *file,
/* stop recording/playback immediately */
case SNDCTL_DSP_RESET:
+ spin_lock_irq (&card->lock);
if (rd) {
- spin_lock_irqsave (&card->lock, flags);
via_chan_clear (&card->ch_in);
via_chan_pcm_fmt (card, &card->ch_in, 1);
- spin_unlock_irqrestore (&card->lock, flags);
}
if (wr) {
- spin_lock_irqsave (&card->lock, flags);
via_chan_clear (&card->ch_out);
via_chan_pcm_fmt (card, &card->ch_out, 1);
- spin_unlock_irqrestore (&card->lock, flags);
}
+ spin_unlock_irq (&card->lock);
DPRINTK("RESET EXIT, returning 0\n");
return 0;
@@ -2109,7 +2006,6 @@ static int via_info_read_proc (char *page, char **start, off_t off,
int len = 0;
u8 r40, r41, r42, r44;
struct via_info *card = data;
- u16 tmp16;
DPRINTK ("ENTER\n");
@@ -2306,41 +2202,11 @@ static int __init via_init_one (struct pci_dev *pdev, const struct pci_device_id
goto err_out;
}
-#if 0
- /* chipset init copied from via */
- pci_write_config_byte(pdev, 0x41,(0xc0));
- udelay(10);
- pci_read_config_byte(pdev, 0x41, &tmp);
- udelay(10);
- pci_write_config_byte(pdev, 0x41,(tmp | 0x0f));
- udelay(10);
- pci_read_config_byte(pdev, 0x42, &tmp);
- udelay(10);
- pci_write_config_byte(pdev, 0x42,(tmp | 0x3f));
-#endif
-
if (pci_enable_device (pdev)) {
rc = -EIO;
goto err_out_none;
}
-#if 0
- /* chipset init copied from ALSA */
- pci_write_config_byte(pdev, 0x42, 0);
- pci_write_config_byte(pdev, 0x41, 0x40);
- udelay(100);
- pci_write_config_byte(pdev, 0x41, 0x60);
- udelay(10);
- pci_write_config_byte(pdev, 0x41, 0xCC);
- udelay(10);
-
- {
- u32 data = ((AC97_POWER_CONTROL & 0x7F) << 16) | 0x0000;
- udelay(100);
- outl (data, pci_resource_start (pdev, 0) + VIA_BASE0_AC97_CTRL);
- }
-#endif
-
card = kmalloc (sizeof (*card), GFP_KERNEL);
if (!card) {
printk (KERN_ERR PFX "out of memory, aborting\n");
diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in
index 38efbb118..3b376c365 100644
--- a/drivers/usb/Config.in
+++ b/drivers/usb/Config.in
@@ -43,7 +43,7 @@ comment 'USB Devices'
dep_tristate ' USB Kodak DC-2xx Camera support' CONFIG_USB_DC2XX $CONFIG_USB
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' USB Mustek MDC800 Digital Camera support (EXPERIMENTAL)' CONFIG_USB_MDC800 $CONFIG_USB
- dep_tristate ' USB Mass Storage support (EXPERIMENTAL)' CONFIG_USB_STORAGE $CONFIG_USB m
+ dep_tristate ' USB Mass Storage support (EXPERIMENTAL)' CONFIG_USB_STORAGE $CONFIG_USB
if [ "$CONFIG_USB_STORAGE" != "n" ]; then
bool ' USB Mass Storage verbose debug' CONFIG_USB_STORAGE_DEBUG
fi
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index 9ce5c07ec..2eaab47ef 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -289,10 +289,10 @@ static void uhci_free_td(struct uhci_td *td)
if (!list_empty(&td->list))
dbg("td is still in URB list!");
- kmem_cache_free(uhci_td_cachep, td);
-
if (td->dev)
usb_dec_dev_use(td->dev);
+
+ kmem_cache_free(uhci_td_cachep, td);
}
static struct uhci_qh *uhci_alloc_qh(struct usb_device *dev)
@@ -318,10 +318,10 @@ static struct uhci_qh *uhci_alloc_qh(struct usb_device *dev)
static void uhci_free_qh(struct uhci_qh *qh)
{
- kmem_cache_free(uhci_qh_cachep, qh);
-
if (qh->dev)
usb_dec_dev_use(qh->dev);
+
+ kmem_cache_free(uhci_qh_cachep, qh);
}
static void uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct uhci_qh *qh)
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 6d4c91409..22ef65c26 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/video/acornfb.c
*
- * Copyright (C) 1998,1999 Russell King
+ * Copyright (C) 1998-2000 Russell King
*
* Frame buffer code for Acorn platforms
*
@@ -958,9 +958,6 @@ acornfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
else
display = &global_disp;
- if (!current_par.allow_modeset && con != -1)
- return -EINVAL;
-
err = acornfb_decode_var(var, con, &visual);
if (err)
return err;
@@ -1088,9 +1085,7 @@ acornfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
outl(control, IOMD_VIDCR);
#endif
acornfb_update_dma(var);
-
- if (current_par.allow_modeset)
- acornfb_set_timing(var);
+ acornfb_set_timing(var);
if (display->cmap.len)
cmap = &display->cmap;
@@ -1375,37 +1370,49 @@ acornfb_parse_font(char *opt)
static void __init
acornfb_parse_mon(char *opt)
{
+ char *p = opt;
+
current_par.montype = -2;
- fb_info.monspecs.hfmin = simple_strtoul(opt, &opt, 0);
- if (*opt == '-')
- fb_info.monspecs.hfmax = simple_strtoul(opt + 1, &opt, 0);
+ fb_info.monspecs.hfmin = simple_strtoul(p, &p, 0);
+ if (*p == '-')
+ fb_info.monspecs.hfmax = simple_strtoul(p + 1, &p, 0);
else
fb_info.monspecs.hfmax = fb_info.monspecs.hfmin;
- if (*opt != ':')
- return;
+ if (*p != ':')
+ goto bad;
- fb_info.monspecs.vfmin = simple_strtoul(opt + 1, &opt, 0);
- if (*opt == '-')
- fb_info.monspecs.vfmax = simple_strtoul(opt + 1, &opt, 0);
+ fb_info.monspecs.vfmin = simple_strtoul(p + 1, &p, 0);
+ if (*p == '-')
+ fb_info.monspecs.vfmax = simple_strtoul(p + 1, &p, 0);
else
fb_info.monspecs.vfmax = fb_info.monspecs.vfmin;
- if (*opt != ':')
- return;
+ if (*p != ':')
+ goto check_values;
- fb_info.monspecs.dpms = simple_strtoul(opt + 1, &opt, 0);
+ fb_info.monspecs.dpms = simple_strtoul(p + 1, &p, 0);
- if (*opt != ':')
- return;
+ if (*p != ':')
+ goto check_values;
- init_var.width = simple_strtoul(opt + 1, &opt, 0);
+ init_var.width = simple_strtoul(p + 1, &p, 0);
- if (*opt != ':')
- return;
+ if (*p != ':')
+ goto check_values;
+
+ init_var.height = simple_strtoul(p + 1, NULL, 0);
- init_var.height = simple_strtoul(opt + 1, NULL, 0);
+check_values:
+ if (fb_info.monspecs.hfmax < fb_info.monspecs.hfmin ||
+ fb_info.monspecs.vfmax < fb_info.monspecs.vfmin)
+ goto bad;
+ return;
+
+bad:
+ printk(KERN_ERR "Acornfb: bad monitor settings: %s\n", opt);
+ current_par.montype = -1;
}
static void __init
@@ -1574,9 +1581,10 @@ acornfb_init(void)
if (current_par.montype == -1 || current_par.montype > NR_MONTYPES)
current_par.montype = 4;
- if (current_par.montype > 0)
+ if (current_par.montype > 0) {
fb_info.monspecs = monspecs[current_par.montype];
- fb_info.monspecs.dpms = current_par.dpms;
+ fb_info.monspecs.dpms = current_par.dpms;
+ }
/*
* Try to select a suitable default mode
@@ -1667,7 +1675,6 @@ acornfb_init(void)
current_par.screen_size = size;
current_par.palette_size = VIDC_PALETTE_SIZE;
- current_par.allow_modeset = 1;
/*
* Lookup the timing for this resolution. If we can't
@@ -1683,13 +1690,6 @@ acornfb_init(void)
printk("Acornfb: no valid mode found\n");
}
- /*
- * Again, if this does not succeed, then we disallow
- * changes to the resolution parameters.
- */
- if (acornfb_set_var(&init_var, -1, &fb_info))
- current_par.allow_modeset = 0;
-
h_sync = 1953125000 / init_var.pixclock;
h_sync = h_sync * 512 / (init_var.xres + init_var.left_margin +
init_var.right_margin + init_var.hsync_len);
@@ -1703,6 +1703,15 @@ acornfb_init(void)
VIDC_NAME, init_var.xres, init_var.yres,
h_sync / 1000, h_sync % 1000, v_sync);
+ printk(KERN_INFO "Acornfb: Monitor: %d.%03d-%d.%03dkHz, %d-%dHz%s\n",
+ fb_info.monspecs.hfmin / 1000, fb_info.monspecs.hfmin % 1000,
+ fb_info.monspecs.hfmax / 1000, fb_info.monspecs.hfmax % 1000,
+ fb_info.monspecs.vfmin, fb_info.monspecs.vfmax,
+ fb_info.monspecs.dpms ? ", DPMS" : "");
+
+ if (acornfb_set_var(&init_var, -1, &fb_info))
+ printk(KERN_ERR "Acornfb: unable to set display parameters\n");
+
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
return 0;
diff --git a/drivers/video/acornfb.h b/drivers/video/acornfb.h
index fdd7d1b02..aca7eb344 100644
--- a/drivers/video/acornfb.h
+++ b/drivers/video/acornfb.h
@@ -52,7 +52,6 @@ struct acornfb_par {
unsigned int palette_size;
signed int montype;
signed int currcon;
- unsigned int allow_modeset : 1;
unsigned int using_vram : 1;
unsigned int dpms : 1;
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index d43884936..2e87c79d7 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -1,11 +1,19 @@
/*
- * linux/drivers/video/cyber2000fb.c
+ * Linux/drivers/video/cyber2000fb.c
*
* Copyright (C) 1998-2000 Russell King
*
- * Integraphics Cyber2000 frame buffer device
+ * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
*
- * Based on cyberfb.c
+ * Based on cyberfb.c.
+ *
+ * Note that we now use the new fbcon fix, var and cmap scheme. We do still
+ * have to check which console is the currently displayed one however, since
+ * especially for the colourmap stuff. Once fbcon has been fully migrated,
+ * we can kill the last 5 references to cfb->currcon.
+ *
+ * We also use the new hotplug PCI subsystem. This doesn't work fully in
+ * the case of multiple CyberPro cards yet however.
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -31,34 +39,41 @@
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
-#define MMIO_SIZE 0x000c0000
+/*
+ * Define this if you don't want RGB565, but RGB555 for 16bpp displays.
+ */
/*#define CFB16_IS_CFB15*/
+/*
+ * This is the offset of the PCI space in physical memory
+ */
+#ifdef CONFIG_ARCH_FOOTBRIDGE
+#define PCI_PHYS_OFFSET 0x80000000
+#else
+#define PCI_PHYS_OFFSET 0x00000000
+#endif
+
static char *CyberRegs;
#include "cyber2000fb.h"
-static struct display global_disp;
-static struct fb_info fb_info;
-static struct cyber2000fb_par current_par;
-static struct display_switch *dispsw;
-static struct fb_var_screeninfo __initdata init_var = {};
+struct cfb_info {
+ struct fb_info fb;
+ struct display_switch *dispsw;
+ struct pci_dev *dev;
+ signed int currcon;
-#if defined(DEBUG) && defined(CONFIG_DEBUG_LL)
-static void debug_printf(char *fmt, ...)
-{
- char buffer[128];
- va_list ap;
+ /*
+ * Clock divisors
+ */
+ u_int divisors[4];
- va_start(ap, fmt);
- vsprintf(buffer, fmt, ap);
- va_end(ap);
+ struct {
+ u8 red, green, blue;
+ } palette[NR_PALETTE];
- printascii(buffer);
-}
-#else
-#define debug_printf(x...) do { } while (0)
-#endif
+ u_char mem_ctl2;
+};
/* -------------------- Hardware specific routines ------------------------- */
@@ -67,7 +82,7 @@ static void debug_printf(char *fmt, ...)
*/
static void cyber2000_accel_wait(void)
{
- int count = 10000;
+ int count = 100000;
while (cyber2000_inb(CO_REG_CONTROL) & 0x80) {
if (!count--) {
@@ -75,22 +90,24 @@ static void cyber2000_accel_wait(void)
cyber2000_outb(0, CO_REG_CONTROL);
return;
}
- udelay(10);
+ udelay(1);
}
}
-static void
-cyber2000_accel_setup(struct display *p)
+static void cyber2000_accel_setup(struct display *p)
{
- dispsw->setup(p);
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
+
+ cfb->dispsw->setup(p);
}
static void
cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
+ int height, int width)
{
- unsigned long src, dst;
- unsigned int fh, fw;
+ struct fb_var_screeninfo *var = &p->fb_info->var;
+ u_long src, dst;
+ u_int fh, fw;
int cmd = CO_CMD_L_PATTERN_FGCOL;
fw = fontwidth(p);
@@ -117,15 +134,15 @@ cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
cmd |= CO_CMD_L_INC_UP;
}
- src = sx + sy * p->var.xres_virtual;
- dst = dx + dy * p->var.xres_virtual;
+ src = sx + sy * var->xres_virtual;
+ dst = dx + dy * var->xres_virtual;
cyber2000_accel_wait();
cyber2000_outb(0x00, CO_REG_CONTROL);
cyber2000_outb(0x03, CO_REG_FORE_MIX);
cyber2000_outw(width, CO_REG_WIDTH);
- if (p->var.bits_per_pixel != 24) {
+ if (var->bits_per_pixel != 24) {
cyber2000_outl(dst, CO_REG_DEST_PTR);
cyber2000_outl(src, CO_REG_SRC_PTR);
} else {
@@ -141,16 +158,17 @@ cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
static void
cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
- int height, int width)
+ int height, int width)
{
- unsigned long dst;
- unsigned int fw, fh;
+ struct fb_var_screeninfo *var = &p->fb_info->var;
+ u_long dst;
+ u_int fw, fh;
u32 bgx = attr_bgcol_ec(p, conp);
fw = fontwidth(p);
fh = fontheight(p);
- dst = sx * fw + sy * p->var.xres_virtual * fh;
+ dst = sx * fw + sy * var->xres_virtual * fh;
width = width * fw - 1;
height = height * fh - 1;
@@ -160,7 +178,7 @@ cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
cyber2000_outw(width, CO_REG_WIDTH);
cyber2000_outw(height, CO_REG_HEIGHT);
- switch (p->var.bits_per_pixel) {
+ switch (var->bits_per_pixel) {
case 15:
case 16:
bgx = ((u16 *)p->dispsw_data)[bgx];
@@ -181,31 +199,40 @@ cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
}
static void
-cyber2000_accel_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
+cyber2000_accel_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx)
{
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
+
cyber2000_accel_wait();
- dispsw->putc(conp, p, c, yy, xx);
+ cfb->dispsw->putc(conp, p, c, yy, xx);
}
static void
cyber2000_accel_putcs(struct vc_data *conp, struct display *p,
- const unsigned short *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy, int xx)
{
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
+
cyber2000_accel_wait();
- dispsw->putcs(conp, p, s, count, yy, xx);
+ cfb->dispsw->putcs(conp, p, s, count, yy, xx);
}
-static void
-cyber2000_accel_revc(struct display *p, int xx, int yy)
+static void cyber2000_accel_revc(struct display *p, int xx, int yy)
{
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
+
cyber2000_accel_wait();
- dispsw->revc(p, xx, yy);
+ cfb->dispsw->revc(p, xx, yy);
}
static void
-cyber2000_accel_clear_margins(struct vc_data *conp, struct display *p, int bottom_only)
+cyber2000_accel_clear_margins(struct vc_data *conp, struct display *p,
+ int bottom_only)
{
- dispsw->clear_margins(conp, p, bottom_only);
+ struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
+
+ cfb->dispsw->clear_margins(conp, p, bottom_only);
}
static struct display_switch fbcon_cyber_accel = {
@@ -222,50 +249,26 @@ static struct display_switch fbcon_cyber_accel = {
};
/*
- * Palette
- */
-static int
-cyber2000_getcolreg(u_int regno, u_int * red, u_int * green, u_int * blue,
- u_int * transp, struct fb_info *fb_info)
-{
- int t;
-
- if (regno >= 256)
- return 1;
-
- t = current_par.palette[regno].red;
- *red = t << 10 | t << 4 | t >> 2;
-
- t = current_par.palette[regno].green;
- *green = t << 10 | t << 4 | t >> 2;
-
- t = current_par.palette[regno].blue;
- *blue = t << 10 | t << 4 | t >> 2;
-
- *transp = 0;
-
- return 0;
-}
-
-/*
* Set a single color register. Return != 0 for invalid regno.
*/
static int
cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *fb_info)
+ u_int transp, struct fb_info *info)
{
- if (regno > 255)
+ struct cfb_info *cfb = (struct cfb_info *)info;
+
+ if (regno >= NR_PALETTE)
return 1;
red >>= 10;
green >>= 10;
blue >>= 10;
- current_par.palette[regno].red = red;
- current_par.palette[regno].green = green;
- current_par.palette[regno].blue = blue;
+ cfb->palette[regno].red = red;
+ cfb->palette[regno].green = green;
+ cfb->palette[regno].blue = blue;
- switch (fb_display[current_par.currcon].var.bits_per_pixel) {
+ switch (cfb->fb.var.bits_per_pixel) {
#ifdef FBCON_HAS_CFB8
case 8:
cyber2000_outb(regno, 0x3c8);
@@ -281,21 +284,22 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
if (regno < 64) {
/* write green */
cyber2000_outb(regno << 2, 0x3c8);
- cyber2000_outb(current_par.palette[regno >> 1].red, 0x3c9);
+ cyber2000_outb(cfb->palette[regno >> 1].red, 0x3c9);
cyber2000_outb(green, 0x3c9);
- cyber2000_outb(current_par.palette[regno >> 1].blue, 0x3c9);
+ cyber2000_outb(cfb->palette[regno >> 1].blue, 0x3c9);
}
if (regno < 32) {
/* write red,blue */
cyber2000_outb(regno << 3, 0x3c8);
cyber2000_outb(red, 0x3c9);
- cyber2000_outb(current_par.palette[regno << 1].green, 0x3c9);
+ cyber2000_outb(cfb->palette[regno << 1].green, 0x3c9);
cyber2000_outb(blue, 0x3c9);
}
if (regno < 16)
- current_par.c_table.cfb16[regno] = regno | regno << 5 | regno << 11;
+ ((u16 *)cfb->fb.pseudo_palette)[regno] =
+ regno | regno << 5 | regno << 11;
break;
#endif
@@ -307,7 +311,8 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
cyber2000_outb(blue, 0x3c9);
}
if (regno < 16)
- current_par.c_table.cfb16[regno] = regno | regno << 5 | regno << 10;
+ ((u16 *)cfb->fb.pseudo_palette)[regno] =
+ regno | regno << 5 | regno << 10;
break;
#endif
@@ -320,7 +325,8 @@ cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
cyber2000_outb(blue, 0x3c9);
if (regno < 16)
- current_par.c_table.cfb24[regno] = regno | regno << 8 | regno << 16;
+ ((u32 *)cfb->fb.pseudo_palette)[regno] =
+ regno | regno << 8 | regno << 16;
break;
#endif
@@ -335,24 +341,23 @@ struct par_info {
/*
* Hardware
*/
- unsigned char clock_mult;
- unsigned char clock_div;
- unsigned char visualid;
- unsigned char pixformat;
- unsigned char crtc_ofl;
- unsigned char crtc[19];
- unsigned int width;
- unsigned int pitch;
- unsigned int fetch;
+ u_char clock_mult;
+ u_char clock_div;
+ u_char visualid;
+ u_char pixformat;
+ u_char crtc_ofl;
+ u_char crtc[19];
+ u_int width;
+ u_int pitch;
+ u_int fetch;
/*
* Other
*/
- unsigned int visual;
- unsigned char palette_ctrl;
+ u_char palette_ctrl;
};
-static const char crtc_idx[] = {
+static const u_char crtc_idx[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
@@ -360,12 +365,12 @@ static const char crtc_idx[] = {
static void cyber2000fb_set_timing(struct par_info *hw)
{
- unsigned int i;
+ u_int i;
/*
* Blank palette
*/
- for (i = 0; i < 256; i++) {
+ for (i = 0; i < NR_PALETTE; i++) {
cyber2000_outb(i, 0x3c8);
cyber2000_outb(0, 0x3c9);
cyber2000_outb(0, 0x3c9);
@@ -430,7 +435,8 @@ static void cyber2000fb_set_timing(struct par_info *hw)
cyber2000_outb(0xff, 0x3c6);
cyber2000_grphw(0x14, hw->fetch);
- cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) | ((hw->pitch >> 4) & 0x30));
+ cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
+ ((hw->pitch >> 4) & 0x30));
cyber2000_grphw(0x77, hw->visualid);
cyber2000_grphw(0x33, 0x0c);
@@ -443,9 +449,9 @@ static void cyber2000fb_set_timing(struct par_info *hw)
}
static inline int
-cyber2000fb_update_start(struct fb_var_screeninfo *var)
+cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var)
{
- unsigned int base;
+ u_int base;
base = var->yoffset * var->xres_virtual + var->xoffset;
@@ -454,9 +460,6 @@ cyber2000fb_update_start(struct fb_var_screeninfo *var)
if (base >= 1 << 20)
return -EINVAL;
- /*
- * FIXME: need the upper bits of the start offset
- */
cyber2000_grphw(0x10, base >> 16 | 0x10);
cyber2000_crtcw(0x0c, base >> 8);
cyber2000_crtcw(0x0d, base);
@@ -480,60 +483,49 @@ static int cyber2000fb_release(struct fb_info *info, int user)
}
/*
- * Get the Colormap
- */
-static int
-cyber2000fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info)
-{
- int err = 0;
-
- if (con == current_par.currcon) /* current console? */
- err = fb_get_cmap(cmap, kspc, cyber2000_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 err;
-}
-
-
-/*
- * Set the Colormap
+ * Set the Colormap
*/
static int
cyber2000fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
- struct display *disp = &fb_display[con];
+ struct cfb_info *cfb = (struct cfb_info *)info;
+ struct fb_cmap *dcmap = &fb_display[con].cmap;
int err = 0;
- if (!disp->cmap.len) { /* no colormap allocated? */
+ /* no colormap allocated? */
+ if (!dcmap->len) {
int size;
- if (disp->var.bits_per_pixel == 16)
+ if (cfb->fb.var.bits_per_pixel == 16)
size = 32;
else
size = 256;
- err = fb_alloc_cmap(&disp->cmap, size, 0);
+ err = fb_alloc_cmap(dcmap, size, 0);
}
- if (!err) {
- if (con == current_par.currcon) /* current console? */
- err = fb_set_cmap(cmap, kspc, cyber2000_setcolreg,
- info);
- else
- fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
+
+ /*
+ * we should be able to remove this test once fbcon has been
+ * "improved" --rmk
+ */
+ if (!err && con == cfb->currcon) {
+ err = fb_set_cmap(cmap, kspc, cyber2000_setcolreg, &cfb->fb);
+ dcmap = &cfb->fb.cmap;
}
+ if (!err)
+ fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
+
return err;
}
-static int cyber2000fb_decode_crtc(struct par_info *hw, struct fb_var_screeninfo *var)
+static int
+cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb,
+ struct fb_var_screeninfo *var)
{
- unsigned int Htotal, Hblankend, Hsyncend;
- unsigned int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
+ u_int Htotal, Hblankend, Hsyncend;
+ u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend;
#define BIT(v,b1,m,b2) (((v >> b1) & m) << b2)
hw->crtc[13] = hw->pitch;
@@ -541,29 +533,31 @@ static int cyber2000fb_decode_crtc(struct par_info *hw, struct fb_var_screeninfo
hw->crtc[14] = 0;
hw->crtc[8] = 0;
- Htotal = var->xres + var->right_margin + var->hsync_len + var->left_margin;
+ Htotal = var->xres + var->right_margin +
+ var->hsync_len + var->left_margin;
if (Htotal > 2080)
return -EINVAL;
- hw->crtc[0] = (Htotal >> 3) - 5; /* Htotal */
- hw->crtc[1] = (var->xres >> 3) - 1; /* Hdispend */
- hw->crtc[2] = var->xres >> 3; /* Hblankstart */
- hw->crtc[4] = (var->xres + var->right_margin) >> 3; /* Hsyncstart */
+ hw->crtc[0] = (Htotal >> 3) - 5;
+ hw->crtc[1] = (var->xres >> 3) - 1;
+ hw->crtc[2] = var->xres >> 3;
+ hw->crtc[4] = (var->xres + var->right_margin) >> 3;
Hblankend = (Htotal - 4*8) >> 3;
- hw->crtc[3] = BIT(Hblankend, 0, 0x1f, 0) | /* Hblankend */
+ hw->crtc[3] = BIT(Hblankend, 0, 0x1f, 0) |
BIT(1, 0, 0x01, 7);
Hsyncend = (var->xres + var->right_margin + var->hsync_len) >> 3;
- hw->crtc[5] = BIT(Hsyncend, 0, 0x1f, 0) | /* Hsyncend */
+ hw->crtc[5] = BIT(Hsyncend, 0, 0x1f, 0) |
BIT(Hblankend, 5, 0x01, 7);
Vdispend = var->yres - 1;
Vsyncstart = var->yres + var->lower_margin;
Vsyncend = var->yres + var->lower_margin + var->vsync_len;
- Vtotal = var->yres + var->lower_margin + var->vsync_len + var->upper_margin - 2;
+ Vtotal = var->yres + var->lower_margin + var->vsync_len +
+ var->upper_margin - 2;
if (Vtotal > 2047)
return -EINVAL;
@@ -592,7 +586,9 @@ static int cyber2000fb_decode_crtc(struct par_info *hw, struct fb_var_screeninfo
hw->crtc[18] = 0xff;
/* overflow - graphics reg 0x11 */
-/* 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10 4=LINECOMP:10 5-IVIDEO 6=FIXCNT */
+ /* 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10
+ * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
+ */
hw->crtc_ofl =
BIT(Vtotal, 10, 0x01, 0) |
BIT(Vdispend, 10, 0x01, 1) |
@@ -604,9 +600,8 @@ static int cyber2000fb_decode_crtc(struct par_info *hw, struct fb_var_screeninfo
}
/*
- * The following was discovered by a good monitor,
- * bit twiddling, theorising and but mostly luck.
- * Strangely, it looks like everyone elses' PLL!
+ * The following was discovered by a good monitor, bit twiddling, theorising
+ * and but mostly luck. Strangely, it looks like everyone elses' PLL!
*
* Clock registers:
* fclock = fpll / div2
@@ -620,29 +615,23 @@ static int cyber2000fb_decode_crtc(struct par_info *hw, struct fb_var_screeninfo
* (8696ps and 3846ps)
*/
static int
-cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
+cyber2000fb_decode_clock(struct par_info *hw, struct cfb_info *cfb,
+ struct fb_var_screeninfo *var)
{
- static unsigned int divisors_2000[] = { 1, 2, 4, 8 };
- static unsigned int divisors_2010[] = { 1, 2, 4, 6 };
- unsigned long pll_ps = var->pixclock;
- unsigned long ref_ps = 69842;
- unsigned int *divisors;
- int div2, div1, mult;
+ u_long pll_ps = var->pixclock;
+ const u_long ref_ps = 69842;
+ u_int div2, t_div1, best_div1, best_mult;
+ int best_diff;
/*
* Step 1:
* find div2 such that 115MHz < fpll < 260MHz
* and 0 <= div2 < 4
*/
- if (current_par.dev_id == PCI_DEVICE_ID_INTERG_2010)
- divisors = divisors_2010;
- else
- divisors = divisors_2000;
-
for (div2 = 0; div2 < 4; div2++) {
- unsigned long new_pll;
+ u_long new_pll;
- new_pll = pll_ps / divisors[div2];
+ new_pll = pll_ps / cfb->divisors[div2];
if (8696 > new_pll && new_pll > 3846) {
pll_ps = new_pll;
break;
@@ -652,26 +641,56 @@ cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
if (div2 == 4)
return -EINVAL;
-#if 0
+#if 1
/*
* Step 2:
* Given pll_ps and ref_ps, find:
* pll_ps * 0.995 < pll_ps_calc < pll_ps * 1.005
- * where { 0 < div1 < 32, 0 < mult < 256 }
- * pll_ps_calc = div1 / (ref_ps * mult)
- *
- * Note! This just picks any old values at the moment,
- * and as such I don't trust it. It certainly doesn't
- * come out with the values below, so the PLL may become
- * unstable under some circumstances (you don't want an
- * FM dot clock)
+ * where { 1 < best_div1 < 32, 1 < best_mult < 256 }
+ * pll_ps_calc = best_div1 / (ref_ps * best_mult)
*/
- for (div1 = 32; div1 > 1; div1 -= 1) {
- mult = (ref_ps * div1 + pll_ps / 2) / pll_ps;
- if (mult < 256)
+ best_diff = 0x7fffffff;
+ best_mult = 32;
+ best_div1 = 255;
+ for (t_div1 = 32; t_div1 > 1; t_div1 -= 1) {
+ u_int rr, t_mult, t_pll_ps;
+ int diff;
+
+ /*
+ * Find the multiplier for this divisor
+ */
+ rr = ref_ps * t_div1;
+ t_mult = (rr + pll_ps / 2) / pll_ps;
+
+ /*
+ * Is the multiplier within the correct range?
+ */
+ if (t_mult > 256 || t_mult < 2)
+ continue;
+
+ /*
+ * Calculate the actual clock period from this multiplier
+ * and divisor, and estimate the error.
+ */
+ t_pll_ps = (rr + t_mult / 2) / t_mult;
+ diff = pll_ps - t_pll_ps;
+ if (diff < 0)
+ diff = -diff;
+
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_mult = t_mult;
+ best_div1 = t_div1;
+ }
+
+ /*
+ * If we hit an exact value, there is no point in continuing.
+ */
+ if (diff == 0)
break;
}
#else
+ /* Note! This table will be killed shortly. --rmk */
/*
* 1600x1200 1280x1024 1152x864 1024x768 800x600 640x480
* 5051 5051 yes 76*
@@ -708,66 +727,62 @@ cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
/* /1 /2 /4 /6 /8 */
/* (2010) (2000) */
if (pll_ps >= 4543 && pll_ps <= 4549) {
- mult = 169; /*u220.0 110.0 54.99 36.663 27.497 */
- div1 = 11; /* 4546 9092 18184 27276 36367 */
+ best_mult = 169; /*u220.0 110.0 54.99 36.663 27.497 */
+ best_div1 = 11; /* 4546 9092 18184 27276 36367 */
} else if (pll_ps >= 4596 && pll_ps <= 4602) {
- mult = 243; /* 217.5 108.7 54.36 36.243 27.181 */
- div1 = 16; /* 4599 9197 18395 27592 36789 */
+ best_mult = 243; /* 217.5 108.7 54.36 36.243 27.181 */
+ best_div1 = 16; /* 4599 9197 18395 27592 36789 */
} else if (pll_ps >= 4627 && pll_ps <= 4633) {
- mult = 181; /*u216.0, 108.0, 54.00, 36.000 27.000 */
- div1 = 12; /* 4630 9260 18520 27780 37040 */
+ best_mult = 181; /*u216.0, 108.0, 54.00, 36.000 27.000 */
+ best_div1 = 12; /* 4630 9260 18520 27780 37040 */
} else if (pll_ps >= 4962 && pll_ps <= 4968) {
- mult = 211; /*u201.0, 100.5, 50.25, 33.500 25.125 */
- div1 = 15; /* 4965 9930 19860 29790 39720 */
+ best_mult = 211; /*u201.0, 100.5, 50.25, 33.500 25.125 */
+ best_div1 = 15; /* 4965 9930 19860 29790 39720 */
} else if (pll_ps >= 5005 && pll_ps <= 5011) {
- mult = 251; /* 200.0 99.8 49.92 33.280 24.960 */
- div1 = 18; /* 5008 10016 20032 30048 40064 */
+ best_mult = 251; /* 200.0 99.8 49.92 33.280 24.960 */
+ best_div1 = 18; /* 5008 10016 20032 30048 40064 */
} else if (pll_ps >= 5047 && pll_ps <= 5053) {
- mult = 83; /*u198.0, 99.0, 49.50, 33.000 24.750 */
- div1 = 6; /* 5050 10100 20200 30300 40400 */
+ best_mult = 83; /*u198.0, 99.0, 49.50, 33.000 24.750 */
+ best_div1 = 6; /* 5050 10100 20200 30300 40400 */
} else if (pll_ps >= 5490 && pll_ps <= 5496) {
- mult = 89; /* 182.0 91.0 45.51 30.342 22.756 */
- div1 = 7; /* 5493 10986 21972 32958 43944 */
+ best_mult = 89; /* 182.0 91.0 45.51 30.342 22.756 */
+ best_div1 = 7; /* 5493 10986 21972 32958 43944 */
} else if (pll_ps >= 5567 && pll_ps <= 5573) {
- mult = 163; /*u179.5 89.8 44.88 29.921 22.441 */
- div1 = 13; /* 5570 11140 22281 33421 44562 */
+ best_mult = 163; /*u179.5 89.8 44.88 29.921 22.441 */
+ best_div1 = 13; /* 5570 11140 22281 33421 44562 */
} else if (pll_ps >= 6246 && pll_ps <= 6252) {
- mult = 190; /*u160.0, 80.0, 40.00, 26.671 20.003 */
- div1 = 17; /* 6249 12498 24996 37494 49992 */
+ best_mult = 190; /*u160.0, 80.0, 40.00, 26.671 20.003 */
+ best_div1 = 17; /* 6249 12498 24996 37494 49992 */
} else if (pll_ps >= 6346 && pll_ps <= 6352) {
- mult = 209; /*u158.0, 79.0, 39.50, 26.333 19.750 */
- div1 = 19; /* 6349 12698 25396 38094 50792 */
+ best_mult = 209; /*u158.0, 79.0, 39.50, 26.333 19.750 */
+ best_div1 = 19; /* 6349 12698 25396 38094 50792 */
} else if (pll_ps >= 6648 && pll_ps <= 6655) {
- mult = 210; /*u150.3 75.2 37.58 25.057 18.792 */
- div1 = 20; /* 6652 13303 26606 39909 53213 */
+ best_mult = 210; /*u150.3 75.2 37.58 25.057 18.792 */
+ best_div1 = 20; /* 6652 13303 26606 39909 53213 */
} else if (pll_ps >= 6943 && pll_ps <= 6949) {
- mult = 181; /*u144.0 72.0 36.00 23.996 17.997 */
- div1 = 18; /* 6946 13891 27782 41674 55565 */
+ best_mult = 181; /*u144.0 72.0 36.00 23.996 17.997 */
+ best_div1 = 18; /* 6946 13891 27782 41674 55565 */
} else if (pll_ps >= 7404 && pll_ps <= 7410) {
- mult = 198; /*u134.0 67.5 33.75 22.500 16.875 */
- div1 = 21; /* 7407 14815 29630 44445 59260 */
+ best_mult = 198; /*u134.0 67.5 33.75 22.500 16.875 */
+ best_div1 = 21; /* 7407 14815 29630 44445 59260 */
} else if (pll_ps >= 7689 && pll_ps <= 7695) {
- mult = 227; /*u130.0 65.0 32.50 21.667 16.251 */
- div1 = 25; /* 7692 15384 30768 46152 61536 */
+ best_mult = 227; /*u130.0 65.0 32.50 21.667 16.251 */
+ best_div1 = 25; /* 7692 15384 30768 46152 61536 */
} else if (pll_ps >= 7808 && pll_ps <= 7814) {
- mult = 152; /* 128.0 64.0 32.00 21.337 16.003 */
- div1 = 17; /* 7811 15623 31245 46868 62490 */
+ best_mult = 152; /* 128.0 64.0 32.00 21.337 16.003 */
+ best_div1 = 17; /* 7811 15623 31245 46868 62490 */
} else if (pll_ps >= 7934 && pll_ps <= 7940) {
- mult = 44; /*u126.0 63.0 31.498 20.999 15.749 */
- div1 = 5; /* 7937 15874 31748 47622 63494 */
+ best_mult = 44; /*u126.0 63.0 31.498 20.999 15.749 */
+ best_div1 = 5; /* 7937 15874 31748 47622 63494 */
} else
return -EINVAL;
- /* 187 13 -> 4855 */
- /* 181 18 -> 6946 */
- /* 163 13 -> 5570 */
- /* 169 11 -> 4545 */
#endif
/*
* Step 3:
* combine values
*/
- hw->clock_mult = mult - 1;
- hw->clock_div = div2 << 6 | (div1 - 1);
+ hw->clock_mult = best_mult - 1;
+ hw->clock_div = div2 << 6 | (best_div1 - 1);
return 0;
}
@@ -778,27 +793,16 @@ cyber2000fb_decode_clock(struct par_info *hw, struct fb_var_screeninfo *var)
* CRTC registers, and accelerator settings.
*/
static int
-cyber2000fb_decode_var(struct fb_var_screeninfo *var, int con, struct par_info *hw)
+cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
+ struct par_info *hw)
{
int err;
hw->width = var->xres_virtual;
- var->red.msb_right = 0;
- var->green.msb_right = 0;
- var->blue.msb_right = 0;
-
switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_CFB8
case 8: /* PSEUDOCOLOUR, 256 */
- var->bits_per_pixel = 8;
- var->red.offset = 0;
- var->red.length = 8;
- var->green.offset = 0;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- hw->visual = FB_VISUAL_PSEUDOCOLOR;
hw->pixformat = PIXFORMAT_8BPP;
hw->visualid = VISUALID_256;
hw->pitch = hw->width >> 3;
@@ -808,14 +812,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, int con, struct par_info *
#ifdef FBCON_HAS_CFB16
case 16:/* DIRECTCOLOUR, 64k */
#ifndef CFB16_IS_CFB15
- var->bits_per_pixel = 16;
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- hw->visual = FB_VISUAL_DIRECTCOLOR;
hw->pixformat = PIXFORMAT_16BPP;
hw->visualid = VISUALID_64K;
hw->pitch = hw->width >> 2;
@@ -823,14 +819,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, int con, struct par_info *
break;
#endif
case 15:/* DIRECTCOLOUR, 32k */
- var->bits_per_pixel = 15;
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- hw->visual = FB_VISUAL_DIRECTCOLOR;
hw->pixformat = PIXFORMAT_16BPP;
hw->visualid = VISUALID_32K;
hw->pitch = hw->width >> 2;
@@ -840,14 +828,6 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, int con, struct par_info *
#endif
#ifdef FBCON_HAS_CFB24
case 24:/* TRUECOLOUR, 16m */
- var->bits_per_pixel = 24;
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- hw->visual = FB_VISUAL_TRUECOLOR;
hw->pixformat = PIXFORMAT_24BPP;
hw->visualid = VISUALID_16M;
hw->width *= 3;
@@ -859,29 +839,17 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, int con, struct par_info *
return -EINVAL;
}
- err = cyber2000fb_decode_clock(hw, var);
+ err = cyber2000fb_decode_clock(hw, cfb, var);
if (err)
return err;
- err = cyber2000fb_decode_crtc(hw, var);
+ err = cyber2000fb_decode_crtc(hw, cfb, var);
if (err)
return err;
- debug_printf("Clock: %02X %02X\n",
- hw->clock_mult, hw->clock_div);
- {
- int i;
-
- for (i = 0; i < 19; i++)
- debug_printf("%2d ", i);
- debug_printf("\n");
- for (i = 0; i < 18; i++)
- debug_printf("%02X ", hw->crtc[i]);
- debug_printf("%02X\n", hw->crtc_ofl);
- }
hw->width -= 1;
hw->fetch = hw->pitch;
- if (current_par.bus_64bit == 0)
+ if (!(cfb->mem_ctl2 & MEM_CTL2_64BIT))
hw->fetch <<= 1;
hw->fetch += 1;
@@ -889,173 +857,170 @@ cyber2000fb_decode_var(struct fb_var_screeninfo *var, int con, struct par_info *
}
/*
- * Get the Fixed Part of the Display
- */
-static int
-cyber2000fb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *fb_info)
-{
- struct display *display;
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, current_par.dev_name);
-
- if (con >= 0)
- display = fb_display + con;
- else
- display = &global_disp;
-
- fix->smem_start = current_par.screen_base_p;
- fix->smem_len = current_par.screen_size;
- fix->mmio_start = current_par.regs_base_p;
- fix->mmio_len = MMIO_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 = 22; /*FB_ACCEL_IGS_CYBER2000*/
-
- return 0;
-}
-
-
-/*
- * Get the User Defined Part of the Display
- */
-static int
-cyber2000fb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *fb_info)
-{
- if (con == -1)
- *var = global_disp.var;
- else
- *var = fb_display[con].var;
-
- return 0;
-}
-
-/*
* Set the User Defined Part of the Display
*/
static int
-cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+cyber2000fb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
{
+ struct cfb_info *cfb = (struct cfb_info *)info;
struct display *display;
struct par_info hw;
int err, chgvar = 0;
- if (con >= 0)
- display = fb_display + con;
- else
- display = &global_disp;
+ /*
+ * CONUPDATE and SMOOTH_XPAN are equal. However,
+ * SMOOTH_XPAN is only used internally by fbcon.
+ */
+ if (var->vmode & FB_VMODE_CONUPDATE) {
+ var->vmode |= FB_VMODE_YWRAP;
+ var->xoffset = cfb->fb.var.xoffset;
+ var->yoffset = cfb->fb.var.yoffset;
+ }
- err = cyber2000fb_decode_var(var, con, &hw);
+ err = cyber2000fb_decode_var(var, (struct cfb_info *)info, &hw);
if (err)
return err;
- switch (var->activate & FB_ACTIVATE_MASK) {
- case FB_ACTIVATE_TEST:
+ if (var->activate & FB_ACTIVATE_TEST)
return 0;
- case FB_ACTIVATE_NXTOPEN:
- case FB_ACTIVATE_NOW:
- break;
-
- default:
+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
return -EINVAL;
- }
- if (con >= 0) {
- if (display->var.xres != var->xres)
- chgvar = 1;
- if (display->var.yres != var->yres)
- chgvar = 1;
- if (display->var.xres_virtual != var->xres_virtual)
- chgvar = 1;
- if (display->var.yres_virtual != var->yres_virtual)
- chgvar = 1;
- if (display->var.accel_flags != var->accel_flags)
- chgvar = 1;
- if (memcmp(&display->var.red, &var->red, sizeof(var->red)))
- chgvar = 1;
- if (memcmp(&display->var.green, &var->green, sizeof(var->green)))
- chgvar = 1;
- if (memcmp(&display->var.blue, &var->blue, sizeof(var->green)))
- chgvar = 1;
+ if (cfb->fb.var.xres != var->xres)
+ chgvar = 1;
+ if (cfb->fb.var.yres != var->yres)
+ chgvar = 1;
+ if (cfb->fb.var.xres_virtual != var->xres_virtual)
+ chgvar = 1;
+ if (cfb->fb.var.yres_virtual != var->yres_virtual)
+ chgvar = 1;
+ if (cfb->fb.var.bits_per_pixel != var->bits_per_pixel)
+ chgvar = 1;
+
+ if (con < 0) {
+ display = cfb->fb.disp;
+ chgvar = 0;
+ } else {
+ display = fb_display + con;
}
- display->var = *var;
- display->var.activate &= ~FB_ACTIVATE_ALL;
-
- if (var->activate & FB_ACTIVATE_ALL)
- global_disp.var = display->var;
-
- display->screen_base = current_par.screen_base;
- display->visual = hw.visual;
- display->type = FB_TYPE_PACKED_PIXELS;
- display->type_aux = 0;
- display->ypanstep = 1;
- display->ywrapstep = 0;
- display->can_soft_blank = 1;
- display->inverse = 0;
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
- switch (display->var.bits_per_pixel) {
+ switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_CFB8
- case 8:
- dispsw = &fbcon_cfb8;
- display->dispsw_data = NULL;
- display->next_line = var->xres_virtual;
+ case 8: /* PSEUDOCOLOUR, 256 */
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+
+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ cfb->dispsw = &fbcon_cfb8;
+ display->dispsw_data = NULL;
+ display->next_line = var->xres_virtual;
break;
#endif
#ifdef FBCON_HAS_CFB16
- case 15:
- case 16:
- dispsw = &fbcon_cfb16;
- display->dispsw_data = current_par.c_table.cfb16;
- display->next_line = var->xres_virtual * 2;
+ case 16:/* DIRECTCOLOUR, 64k */
+#ifndef CFB16_IS_CFB15
+ var->bits_per_pixel = 15;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
+ cfb->dispsw = &fbcon_cfb16;
+ display->dispsw_data = cfb->fb.pseudo_palette;
+ display->next_line = var->xres_virtual * 2;
+ break;
+#endif
+ case 15:/* DIRECTCOLOUR, 32k */
+ var->bits_per_pixel = 15;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+
+ cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
+ cfb->dispsw = &fbcon_cfb16;
+ display->dispsw_data = cfb->fb.pseudo_palette;
+ display->next_line = var->xres_virtual * 2;
break;
#endif
#ifdef FBCON_HAS_CFB24
- case 24:
- dispsw = &fbcon_cfb24;
- display->dispsw_data = current_par.c_table.cfb24;
- display->next_line = var->xres_virtual * 3;
+ case 24:/* TRUECOLOUR, 16m */
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+
+ cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+ cfb->dispsw = &fbcon_cfb24;
+ display->dispsw_data = cfb->fb.pseudo_palette;
+ display->next_line = var->xres_virtual * 3;
break;
#endif
- default:
+ default:/* in theory this should never happen */
printk(KERN_WARNING "%s: no support for %dbpp\n",
- current_par.dev_name, display->var.bits_per_pixel);
- dispsw = &fbcon_dummy;
+ cfb->fb.fix.id, var->bits_per_pixel);
+ cfb->dispsw = &fbcon_dummy;
break;
}
- display->line_length = display->next_line;
-
- if (display->var.accel_flags & FB_ACCELF_TEXT &&
- dispsw != &fbcon_dummy)
+ if (var->accel_flags & FB_ACCELF_TEXT && cfb->dispsw != &fbcon_dummy)
display->dispsw = &fbcon_cyber_accel;
else
- display->dispsw = dispsw;
+ display->dispsw = cfb->dispsw;
+
+ cfb->fb.fix.line_length = display->next_line;
+
+ display->screen_base = cfb->fb.screen_base;
+ display->line_length = cfb->fb.fix.line_length;
+ display->visual = cfb->fb.fix.visual;
+ display->type = cfb->fb.fix.type;
+ display->type_aux = cfb->fb.fix.type_aux;
+ display->ypanstep = cfb->fb.fix.ypanstep;
+ display->ywrapstep = cfb->fb.fix.ywrapstep;
+ display->can_soft_blank = 1;
+ display->inverse = 0;
+
+ cfb->fb.var = *var;
+ cfb->fb.var.activate &= ~FB_ACTIVATE_ALL;
- if (chgvar && info && info->changevar)
- info->changevar(con);
+ /*
+ * Update the old var. The fbcon drivers still use this.
+ * Once they are using cfb->fb.var, this can be dropped.
+ * --rmk
+ */
+ display->var = cfb->fb.var;
- if (con == current_par.currcon) {
- struct fb_cmap *cmap;
+ /*
+ * If we are setting all the virtual consoles, also set the
+ * defaults used to create new consoles.
+ */
+ if (var->activate & FB_ACTIVATE_ALL)
+ cfb->fb.disp->var = cfb->fb.var;
- cyber2000fb_update_start(var);
- cyber2000fb_set_timing(&hw);
+ if (chgvar && info && cfb->fb.changevar)
+ cfb->fb.changevar(con);
- if (display->cmap.len)
- cmap = &display->cmap;
- else
- cmap = fb_default_cmap(current_par.palette_size);
+ cyber2000fb_update_start(cfb, var);
+ cyber2000fb_set_timing(&hw);
+ fb_set_cmap(&cfb->fb.cmap, 1, cyber2000_setcolreg, &cfb->fb);
- fb_set_cmap(cmap, 1, cyber2000_setcolreg, info);
- }
return 0;
}
@@ -1063,9 +1028,11 @@ cyber2000fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info
/*
* Pan or Wrap the Display
*/
-static int cyber2000fb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+static int
+cyber2000fb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
{
+ struct cfb_info *cfb = (struct cfb_info *)info;
u_int y_bottom;
y_bottom = var->yoffset;
@@ -1075,25 +1042,27 @@ static int cyber2000fb_pan_display(struct fb_var_screeninfo *var, int con,
if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
- if (y_bottom > fb_display[con].var.yres_virtual)
+ if (y_bottom > cfb->fb.var.yres_virtual)
return -EINVAL;
- if (cyber2000fb_update_start(var))
+ if (cyber2000fb_update_start(cfb, var))
return -EINVAL;
- fb_display[con].var.xoffset = var->xoffset;
- fb_display[con].var.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- fb_display[con].var.vmode |= FB_VMODE_YWRAP;
- else
- fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
+ cfb->fb.var.xoffset = var->xoffset;
+ cfb->fb.var.yoffset = var->yoffset;
+ if (var->vmode & FB_VMODE_YWRAP) {
+ cfb->fb.var.vmode |= FB_VMODE_YWRAP;
+ } else {
+ cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
+ }
return 0;
}
-static int cyber2000fb_ioctl(struct inode *inode, struct file *file,
- u_int cmd, u_long arg, int con, struct fb_info *info)
+static int
+cyber2000fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
{
return -EINVAL;
}
@@ -1105,34 +1074,53 @@ static int cyber2000fb_ioctl(struct inode *inode, struct file *file,
* This call looks only at yoffset and the FB_VMODE_YWRAP flag in `var'.
* Since it's called by a kernel driver, no range checking is done.
*/
-static int
-cyber2000fb_updatevar(int con, struct fb_info *info)
+static int cyber2000fb_updatevar(int con, struct fb_info *info)
{
- int ret = 0;
-
- if (con == current_par.currcon)
- ret = cyber2000fb_update_start(&fb_display[con].var);
+ struct cfb_info *cfb = (struct cfb_info *)info;
- return ret;
+ return cyber2000fb_update_start(cfb, &fb_display[con].var);
}
-static int
-cyber2000fb_switch(int con, struct fb_info *info)
+static int cyber2000fb_switch(int con, struct fb_info *info)
{
+ struct cfb_info *cfb = (struct cfb_info *)info;
+ struct display *disp;
struct fb_cmap *cmap;
- if (current_par.currcon >= 0) {
- cmap = &fb_display[current_par.currcon].cmap;
+ if (cfb->currcon >= 0) {
+ disp = fb_display + cfb->currcon;
- if (cmap->len)
- fb_get_cmap(cmap, 1, cyber2000_getcolreg, info);
+ /*
+ * Save the old colormap and video mode.
+ */
+ disp->var = cfb->fb.var;
+ if (disp->cmap.len)
+ fb_copy_cmap(&cfb->fb.cmap, &disp->cmap, 0);
}
- current_par.currcon = con;
+ cfb->currcon = con;
+ disp = fb_display + con;
+
+ /*
+ * Install the new colormap and change the video mode. By default,
+ * fbcon sets all the colormaps and video modes to the default
+ * values at bootup.
+ *
+ * Really, we want to set the colourmap size depending on the
+ * depth of the new video mode. For now, we leave it at its
+ * default 256 entry.
+ */
+ if (disp->cmap.len)
+ cmap = &disp->cmap;
+ else
+ cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
+
+ fb_copy_cmap(cmap, &cfb->fb.cmap, 0);
- fb_display[con].var.activate = FB_ACTIVATE_NOW;
+ cfb->fb.var = disp->var;
+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
- cyber2000fb_set_var(&fb_display[con].var, con, info);
+ cyber2000fb_set_var(&cfb->fb.var, con, &cfb->fb);
return 0;
}
@@ -1140,38 +1128,69 @@ cyber2000fb_switch(int con, struct fb_info *info)
/*
* (Un)Blank the display.
*/
-static void cyber2000fb_blank(int blank, struct fb_info *fb_info)
+static void cyber2000fb_blank(int blank, struct fb_info *info)
{
+ struct cfb_info *cfb = (struct cfb_info *)info;
int i;
if (blank) {
- for (i = 0; i < 256; i++) {
+ for (i = 0; i < NR_PALETTE; i++) {
cyber2000_outb(i, 0x3c8);
cyber2000_outb(0, 0x3c9);
cyber2000_outb(0, 0x3c9);
cyber2000_outb(0, 0x3c9);
}
} else {
- for (i = 0; i < 256; i++) {
+ for (i = 0; i < NR_PALETTE; i++) {
cyber2000_outb(i, 0x3c8);
- cyber2000_outb(current_par.palette[i].red, 0x3c9);
- cyber2000_outb(current_par.palette[i].green, 0x3c9);
- cyber2000_outb(current_par.palette[i].blue, 0x3c9);
+ cyber2000_outb(cfb->palette[i].red, 0x3c9);
+ cyber2000_outb(cfb->palette[i].green, 0x3c9);
+ cyber2000_outb(cfb->palette[i].blue, 0x3c9);
}
}
}
+/*
+ * Get the currently displayed virtual consoles colormap.
+ */
+static int
+gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
+{
+ fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+/*
+ * Get the currently displayed virtual consoles fixed part of the display.
+ */
+static int
+gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+ *fix = info->fix;
+ return 0;
+}
+
+/*
+ * Get the current user defined part of the display.
+ */
+static int
+gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+ *var = info->var;
+ return 0;
+}
+
static struct fb_ops cyber2000fb_ops =
{
- cyber2000fb_open,
- cyber2000fb_release,
- cyber2000fb_get_fix,
- cyber2000fb_get_var,
- cyber2000fb_set_var,
- cyber2000fb_get_cmap,
- cyber2000fb_set_cmap,
- cyber2000fb_pan_display,
- cyber2000fb_ioctl
+ fb_open: cyber2000fb_open,
+ fb_release: cyber2000fb_release,
+ fb_set_var: cyber2000fb_set_var,
+ fb_set_cmap: cyber2000fb_set_cmap,
+ fb_pan_display: cyber2000fb_pan_display,
+ fb_ioctl: cyber2000fb_ioctl,
+ fb_get_fix: gen_get_fix,
+ fb_get_var: gen_get_var,
+ fb_get_cmap: gen_get_cmap,
};
/*
@@ -1199,24 +1218,31 @@ static void cyber2000fb_disable_extregs(void)
}
/*
+ * This is the only "static" reference to the internal data structures
+ * of this driver. It is here solely at the moment to support the other
+ * CyberPro modules external to this driver.
+ */
+static struct cfb_info *int_cfb_info;
+
+/*
* Attach a capture/tv driver to the core CyberX0X0 driver.
*/
int cyber2000fb_attach(struct cyberpro_info *info)
{
- if (current_par.initialised) {
- info->dev = current_par.dev;
+ if (int_cfb_info != NULL) {
+ info->dev = int_cfb_info->dev;
info->regs = CyberRegs;
- info->fb = current_par.screen_base;
- info->fb_size = current_par.screen_size;
+ info->fb = int_cfb_info->fb.screen_base;
+ info->fb_size = int_cfb_info->fb.fix.smem_len;
info->enable_extregs = cyber2000fb_enable_extregs;
info->disable_extregs = cyber2000fb_disable_extregs;
- strncpy(info->dev_name, current_par.dev_name, sizeof(info->dev_name));
+ strncpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
MOD_INC_USE_COUNT;
}
- return current_par.initialised;
+ return int_cfb_info != NULL;
}
/*
@@ -1234,9 +1260,7 @@ EXPORT_SYMBOL(cyber2000fb_detach);
* These parameters give
* 640x480, hsync 31.5kHz, vsync 60Hz
*/
-static struct fb_videomode __initdata
-cyber2000fb_default_mode = {
- name: NULL,
+static struct fb_videomode __devinitdata cyber2000fb_default_mode = {
refresh: 60,
xres: 640,
yres: 480,
@@ -1251,336 +1275,364 @@ cyber2000fb_default_mode = {
vmode: FB_VMODE_NONINTERLACED
};
-static void __init
-cyber2000fb_init_fbinfo(void)
+int __init cyber2000fb_setup(char *options)
{
- static int first = 1;
+ return 0;
+}
- if (!first)
- return;
- first = 0;
+static char igs_regs[] __devinitdata = {
+ 0x10, 0x10, 0x12, 0x00, 0x13, 0x00,
+ 0x31, 0x00, 0x32, 0x00, 0x33, 0x01,
+ 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00,
+ 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x01,
+ 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00,
+ 0x70, 0x0b, 0x73, 0x30,
+ 0x74, 0x0b, 0x75, 0x17, 0x76, 0x00, 0x7a, 0xc8
+};
- strcpy(fb_info.modename, "Cyber2000");
- strcpy(fb_info.fontname, "Acorn8x8");
+static inline void cyberpro_init_hw(struct cfb_info *cfb)
+{
+ int i;
- fb_info.node = -1;
- fb_info.fbops = &cyber2000fb_ops;
- fb_info.disp = &global_disp;
- fb_info.changevar = NULL;
- fb_info.switch_con = cyber2000fb_switch;
- fb_info.updatevar = cyber2000fb_updatevar;
- fb_info.blank = cyber2000fb_blank;
- fb_info.flags = FBINFO_FLAG_DEFAULT;
+ /*
+ * Wake up the CyberPro
+ */
+ cyber2000_outb(0x18, 0x46e8);
+ cyber2000_outb(0x01, 0x102);
+ cyber2000_outb(0x08, 0x46e8);
/*
- * setup initial parameters
+ * Initialise the CyberPro
*/
- memset(&init_var, 0, sizeof(init_var));
+ for (i = 0; i < sizeof(igs_regs); i += 2)
+ cyber2000_grphw(igs_regs[i], igs_regs[i+1]);
+}
- init_var.red.msb_right = 0;
- init_var.green.msb_right = 0;
- init_var.blue.msb_right = 0;
+static struct cfb_info * __devinit
+cyberpro_alloc_fb_info(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct cfb_info *cfb;
- switch(init_var.bits_per_pixel) {
- default:
- init_var.bits_per_pixel = 8;
- case 8: /* PSEUDOCOLOUR */
- init_var.bits_per_pixel = 8;
- init_var.red.offset = 0;
- init_var.red.length = 8;
- init_var.green.offset = 0;
- init_var.green.length = 8;
- init_var.blue.offset = 0;
- init_var.blue.length = 8;
- break;
+ cfb = kmalloc(sizeof(struct cfb_info) + sizeof(struct display) +
+ sizeof(u32) * 16, GFP_KERNEL);
- case 15: /* RGB555 */
- init_var.bits_per_pixel = 15;
- init_var.red.offset = 10;
- init_var.red.length = 5;
- init_var.green.offset = 5;
- init_var.green.length = 5;
- init_var.blue.offset = 0;
- init_var.blue.length = 5;
- break;
+ if (!cfb)
+ return NULL;
- case 16: /* RGB565 */
- init_var.bits_per_pixel = 16;
- init_var.red.offset = 11;
- init_var.red.length = 5;
- init_var.green.offset = 5;
- init_var.green.length = 6;
- init_var.blue.offset = 0;
- init_var.blue.length = 5;
- break;
+ memset(cfb, 0, sizeof(struct cfb_info) + sizeof(struct display));
- case 24: /* RGB888 */
- init_var.bits_per_pixel = 24;
- init_var.red.offset = 16;
- init_var.red.length = 8;
- init_var.green.offset = 8;
- init_var.green.length = 8;
- init_var.blue.offset = 0;
- init_var.blue.length = 8;
- break;
- }
+ cfb->currcon = -1;
+ cfb->dev = dev;
+ cfb->divisors[0] = 1;
+ cfb->divisors[1] = 2;
+ cfb->divisors[2] = 4;
- init_var.nonstd = 0;
- init_var.activate = FB_ACTIVATE_NOW;
- init_var.height = -1;
- init_var.width = -1;
- init_var.accel_flags = FB_ACCELF_TEXT;
+ if (id->driver_data == FB_ACCEL_IGS_CYBER2010)
+ cfb->divisors[3] = 6;
+ else
+ cfb->divisors[3] = 8;
+
+ sprintf(cfb->fb.fix.id, "CyberPro%4X", id->device);
+
+ cfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
+ cfb->fb.fix.type_aux = 0;
+ cfb->fb.fix.xpanstep = 0;
+ cfb->fb.fix.ypanstep = 1;
+ cfb->fb.fix.ywrapstep = 0;
+ cfb->fb.fix.accel = id->driver_data;
+
+ cfb->fb.var.nonstd = 0;
+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
+ cfb->fb.var.height = -1;
+ cfb->fb.var.width = -1;
+ cfb->fb.var.accel_flags = FB_ACCELF_TEXT;
+
+ strcpy(cfb->fb.modename, cfb->fb.fix.id);
+ strcpy(cfb->fb.fontname, "Acorn8x8");
+
+ cfb->fb.fbops = &cyber2000fb_ops;
+ cfb->fb.changevar = NULL;
+ cfb->fb.switch_con = cyber2000fb_switch;
+ cfb->fb.updatevar = cyber2000fb_updatevar;
+ cfb->fb.blank = cyber2000fb_blank;
+ cfb->fb.flags = FBINFO_FLAG_DEFAULT;
+ cfb->fb.disp = (struct display *)(cfb + 1);
+ cfb->fb.pseudo_palette = (void *)(cfb->fb.disp + 1);
+
+ fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
+
+ return cfb;
}
-/*
- * Cyber2000 options:
- *
- * font:fontname
- * Set the fontname
- *
- * res:XxY
- * Set the default display resolution
- */
-static void __init
-cyber2000fb_parse_font(char *opt)
+static void __devinit
+cyberpro_free_fb_info(struct cfb_info *cfb)
{
- strcpy(fb_info.fontname, opt);
-}
+ if (cfb) {
+ /*
+ * Free the colourmap
+ */
+ fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
-static struct options {
- char *name;
- void (*parse)(char *opt);
-} opt_table[] __initdata = {
- { "font", cyber2000fb_parse_font },
- { NULL, NULL }
-};
+ kfree(cfb);
+ }
+}
-int __init
-cyber2000fb_setup(char *options)
+/*
+ * Map in the registers
+ */
+static int __devinit
+cyberpro_map_mmio(struct cfb_info *cfb, struct pci_dev *dev)
{
- struct options *optp;
- char *opt;
+ u_long mmio_base;
- if (!options || !*options)
- return 0;
+ mmio_base = pci_resource_start(dev, 0) + MMIO_OFFSET;
- cyber2000fb_init_fbinfo();
+ cfb->fb.fix.mmio_start = mmio_base + PCI_PHYS_OFFSET;
+ cfb->fb.fix.mmio_len = MMIO_SIZE;
- for (opt = strtok(options, ","); opt; opt = strtok(NULL, ",")) {
- if (!*opt)
- continue;
-
- for (optp = opt_table; optp->name; optp++) {
- int optlen;
-
- optlen = strlen(optp->name);
-
- if (strncmp(opt, optp->name, optlen) == 0 &&
- opt[optlen] == ':') {
- optp->parse(opt + optlen + 1);
- break;
- }
- }
+ if (!request_mem_region(mmio_base, MMIO_SIZE, "memory mapped I/O")) {
+ printk("%s: memory mapped IO in use\n", cfb->fb.fix.id);
+ return -EBUSY;
+ }
- if (!optp->name)
- printk(KERN_ERR "CyberPro20x0: unknown parameter: %s\n",
- opt);
+ CyberRegs = ioremap(mmio_base, MMIO_SIZE);
+ if (!CyberRegs) {
+ printk("%s: unable to map memory mapped IO\n",
+ cfb->fb.fix.id);
+ return -ENOMEM;
}
return 0;
}
-static char igs_regs[] __initdata = {
- 0x10, 0x10, 0x12, 0x00, 0x13, 0x00,
- 0x31, 0x00, 0x32, 0x00, 0x33, 0x01,
- 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00,
- 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x01,
- 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00,
- 0x70, 0x0b, 0x73, 0x30,
- 0x74, 0x0b, 0x75, 0x17, 0x76, 0x00, 0x7a, 0xc8
-};
-
-static void __init cyber2000fb_hw_init(void)
+/*
+ * Unmap registers
+ */
+static void __devinit cyberpro_unmap_mmio(struct cfb_info *cfb)
{
- int i;
+ if (cfb && CyberRegs) {
+ iounmap(CyberRegs);
+ CyberRegs = NULL;
- for (i = 0; i < sizeof(igs_regs); i += 2)
- cyber2000_grphw(igs_regs[i], igs_regs[i+1]);
+ release_mem_region(cfb->fb.fix.mmio_start - PCI_PHYS_OFFSET,
+ cfb->fb.fix.mmio_len);
+ }
}
-static unsigned short device_ids[] __initdata = {
- PCI_DEVICE_ID_INTERG_2000,
- PCI_DEVICE_ID_INTERG_2010,
- PCI_DEVICE_ID_INTERG_5000
-};
-
/*
- * Initialization
+ * Map in screen memory
*/
-int __init cyber2000fb_init(void)
+static int __devinit
+cyberpro_map_smem(struct cfb_info *cfb, struct pci_dev *dev, u_long smem_len)
{
- struct pci_dev *dev;
- u_int h_sync, v_sync;
- u_long mmio_base, smem_base, smem_size;
- int err = 0, i;
+ u_long smem_base;
- for (i = 0; i < sizeof(device_ids) / sizeof(device_ids[0]); i++) {
- dev = pci_find_device(PCI_VENDOR_ID_INTERG,
- device_ids[i], NULL);
- if (dev)
- break;
+ smem_base = pci_resource_start(dev, 0);
+
+ cfb->fb.fix.smem_start = smem_base + PCI_PHYS_OFFSET;
+ cfb->fb.fix.smem_len = smem_len;
+
+ if (!request_mem_region(smem_base, smem_len, "frame buffer")) {
+ printk("%s: frame buffer in use\n",
+ cfb->fb.fix.id);
+ return -EBUSY;
}
- if (!dev)
- return -ENXIO;
+ cfb->fb.screen_base = ioremap(smem_base, smem_len);
+ if (!cfb->fb.screen_base) {
+ printk("%s: unable to map screen memory\n",
+ cfb->fb.fix.id);
+ return -ENOMEM;
+ }
- sprintf(current_par.dev_name, "CyberPro%4X", dev->device);
+ return 0;
+}
- smem_base = dev->resource[0].start;
- mmio_base = dev->resource[0].start + 0x00800000;
- current_par.dev = dev;
- current_par.dev_id = dev->device;
+static void __devinit cyberpro_unmap_smem(struct cfb_info *cfb)
+{
+ if (cfb && cfb->fb.screen_base) {
+ iounmap(cfb->fb.screen_base);
+ cfb->fb.screen_base = NULL;
- err = pci_enable_device(dev);
- if (err) {
- printk("%s: unable to enable device: %d\n",
- current_par.dev_name, err);
- return err;
+ release_mem_region(cfb->fb.fix.smem_start - PCI_PHYS_OFFSET,
+ cfb->fb.fix.smem_len);
}
+}
+
+static int __devinit
+cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct cfb_info *cfb;
+ u_int h_sync, v_sync;
+ u_long smem_size;
+ int err;
/*
- * Map in the registers
+ * We can only accept one CyberPro device at the moment. We can
+ * kill this once int_cfb_info and CyberRegs have been killed.
*/
- if (!request_mem_region(mmio_base, MMIO_SIZE, "memory mapped I/O")) {
- printk("%s: memory mapped IO in use\n",
- current_par.dev_name);
+ if (int_cfb_info)
return -EBUSY;
- }
- CyberRegs = ioremap(mmio_base, MMIO_SIZE);
- if (!CyberRegs) {
- printk("%s: unable to map memory mapped IO\n",
- current_par.dev_name);
- err = -ENOMEM;
- goto release_mmio_resource;
- }
+ err = pci_enable_device(dev);
+ if (err)
+ return err;
- cyber2000_outb(0x18, 0x46e8);
- cyber2000_outb(0x01, 0x102);
- cyber2000_outb(0x08, 0x46e8);
+ err = -ENOMEM;
+ cfb = cyberpro_alloc_fb_info(dev, id);
+ if (!cfb)
+ goto failed;
+
+ err = cyberpro_map_mmio(cfb, dev);
+ if (err)
+ goto failed;
+
+ cyberpro_init_hw(cfb);
/*
* get the video RAM size and width from the VGA register.
* This should have been already initialised by the BIOS,
* but if it's garbage, claim default 1MB VRAM (woody)
*/
- cyber2000_outb(0x72, 0x3ce);
- i = cyber2000_inb(0x3cf);
- current_par.bus_64bit = i & 4;
+ cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2);
- switch (i & 3) {
- case 2: smem_size = 0x00400000; break;
- case 1: smem_size = 0x00200000; break;
- default: smem_size = 0x00100000; break;
+ switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
+ case MEM_CTL2_SIZE_4MB: smem_size = 0x00400000; break;
+ case MEM_CTL2_SIZE_2MB: smem_size = 0x00200000; break;
+ default: smem_size = 0x00100000; break;
}
- /*
- * Map in screen memory
- */
- if (!request_mem_region(smem_base, smem_size, "frame buffer")) {
- printk("%s: frame buffer in use\n",
- current_par.dev_name);
- err = -EBUSY;
- goto release_mmio;
- }
+ err = cyberpro_map_smem(cfb, dev, smem_size);
+ if (err)
+ goto failed;
- current_par.screen_base = ioremap(smem_base, smem_size);
- if (!current_par.screen_base) {
- printk("%s: unable to map screen memory\n",
- current_par.dev_name);
- err = -ENOMEM;
- goto release_smem_resource;
+ if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
+ &cyber2000fb_default_mode, 8)) {
+ printk("%s: no valid mode found\n", cfb->fb.fix.id);
+ goto failed;
}
- current_par.screen_size = smem_size;
- current_par.screen_base_p = smem_base + 0x80000000;
- current_par.regs_base_p = mmio_base + 0x80000000;
- current_par.currcon = -1;
+ cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 /
+ (cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual);
- cyber2000fb_init_fbinfo();
+ if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
+ cfb->fb.var.yres_virtual = cfb->fb.var.yres;
- if (!fb_find_mode(&init_var, &fb_info, NULL,
- NULL, 0, &cyber2000fb_default_mode, 8)) {
- printk("%s: no valid mode found\n",
- current_par.dev_name);
- goto release_smem_resource;
- }
+ cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
+
+ h_sync = 1953125000 / cfb->fb.var.pixclock;
+ h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin +
+ cfb->fb.var.right_margin + cfb->fb.var.hsync_len);
+ v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +
+ cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);
- init_var.yres_virtual = smem_size * 8 /
- (init_var.bits_per_pixel * init_var.xres_virtual);
-
- if (init_var.yres_virtual < init_var.yres)
- init_var.yres_virtual = init_var.yres;
-
- cyber2000fb_hw_init();
- cyber2000fb_set_var(&init_var, -1, &fb_info);
-
- h_sync = 1953125000 / init_var.pixclock;
- h_sync = h_sync * 512 / (init_var.xres + init_var.left_margin +
- init_var.right_margin + init_var.hsync_len);
- v_sync = h_sync / (init_var.yres + init_var.upper_margin +
- init_var.lower_margin + init_var.vsync_len);
-
- printk(KERN_INFO "%s: %ldkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
- current_par.dev_name,
- current_par.screen_size >> 10,
- init_var.xres, init_var.yres,
+ printk(KERN_INFO "%s: %dkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
+ cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,
+ cfb->fb.var.xres, cfb->fb.var.yres,
h_sync / 1000, h_sync % 1000, v_sync);
- if (register_framebuffer(&fb_info) < 0) {
- err = -EINVAL;
- goto release_smem;
- }
+ err = register_framebuffer(&cfb->fb);
+ if (err < 0)
+ goto failed;
- current_par.initialised = 1;
+ /*
+ * Our driver data
+ */
+ dev->driver_data = cfb;
+ int_cfb_info = cfb;
- MOD_INC_USE_COUNT; /* TODO: This driver cannot be unloaded yet */
return 0;
-release_smem:
- iounmap(current_par.screen_base);
-release_smem_resource:
- release_mem_region(smem_base, smem_size);
-release_mmio:
- iounmap(CyberRegs);
-release_mmio_resource:
- release_mem_region(mmio_base, MMIO_SIZE);
+failed:
+ cyberpro_unmap_smem(cfb);
+ cyberpro_unmap_mmio(cfb);
+ cyberpro_free_fb_info(cfb);
return err;
}
-#ifdef MODULE
-int __init init_module(void)
+static void __devexit cyberpro_remove(struct pci_dev *dev)
{
- int ret;
-
- ret = cyber2000fb_init();
- if (ret)
- return ret;
+ struct cfb_info *cfb = (struct cfb_info *)dev->driver_data;
+
+ if (cfb) {
+ unregister_framebuffer(&cfb->fb);
+ cyberpro_unmap_smem(cfb);
+ cyberpro_unmap_mmio(cfb);
+ cyberpro_free_fb_info(cfb);
+
+ /*
+ * Ensure that the driver data is no longer
+ * valid.
+ */
+ dev->driver_data = NULL;
+ int_cfb_info = NULL;
+ }
+}
- return 0;
+static void cyberpro_suspend(struct pci_dev *dev)
+{
}
-void cleanup_module(void)
+/*
+ * Re-initialise the CyberPro hardware
+ */
+static void cyberpro_resume(struct pci_dev *dev)
{
- /* Not reached because the usecount will never be
- decremented to zero */
- unregister_framebuffer(&fb_info);
+ struct cfb_info *cfb = (struct cfb_info *)dev->driver_data;
+
+ if (cfb) {
+ cyberpro_init_hw(cfb);
+
+ /*
+ * Reprogram the MEM_CTL2 register
+ */
+ cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2);
+
+ /*
+ * Restore the old video mode and the palette.
+ * We also need to tell fbcon to redraw the console.
+ */
+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
+ cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
+ }
+}
+
+static struct pci_device_id cyberpro_pci_table[] __devinitdata = {
+ { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_IGS_CYBER2000 },
+ { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_IGS_CYBER2010 },
+ { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_IGS_CYBER5000 },
+ { 0, }
+};
- iounmap(current_par.screen_base);
- iounmap(CyberRegs);
+MODULE_DEVICE_TABLE(pci, cyberpro_pci_table);
- release_mem_region(smem_base, current_par.screen_size);
- release_mem_region(mmio_base, MMIO_SIZE);
+static struct pci_driver cyberpro_driver = {
+ name: "CyberPro",
+ probe: cyberpro_probe,
+ remove: cyberpro_remove,
+ suspend: cyberpro_suspend,
+ resume: cyberpro_resume,
+ id_table: cyberpro_pci_table
+};
+
+/*
+ * I don't think we can use the "module_init" stuff here because
+ * the fbcon stuff may not be initialised yet.
+ */
+int __init cyber2000fb_init(void)
+{
+ return pci_module_init(&cyberpro_driver);
}
-#endif /* MODULE */
+static void __exit cyberpro_exit(void)
+{
+ pci_unregister_driver(&cyberpro_driver);
+}
+
+#ifdef MODULE
+module_init(cyber2000fb_init);
+#endif
+module_exit(cyberpro_exit);
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/cyber2000fb.h
index 734e7e7af..eefc038da 100644
--- a/drivers/video/cyber2000fb.h
+++ b/drivers/video/cyber2000fb.h
@@ -4,8 +4,6 @@
* Integraphics Cyber2000 frame buffer device
*/
-#define arraysize(x) (sizeof(x)/sizeof(*(x)))
-
#define cyber2000_outb(dat,reg) writeb(dat, CyberRegs + reg)
#define cyber2000_outw(dat,reg) writew(dat, CyberRegs + reg)
#define cyber2000_outl(dat,reg) writel(dat, CyberRegs + reg)
@@ -14,6 +12,30 @@
#define cyber2000_inw(reg) readw(CyberRegs + reg)
#define cyber2000_inl(reg) readl(CyberRegs + reg)
+/*
+ * Internal CyberPro sizes and offsets.
+ */
+#define MMIO_OFFSET 0x00800000
+#define MMIO_SIZE 0x000c0000
+
+#define NR_PALETTE 256
+
+#if defined(DEBUG) && defined(CONFIG_DEBUG_LL)
+static void debug_printf(char *fmt, ...)
+{
+ char buffer[128];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buffer, fmt, ap);
+ va_end(ap);
+
+ printascii(buffer);
+}
+#else
+#define debug_printf(x...) do { } while (0)
+#endif
+
static inline void cyber2000_crtcw(int reg, int val)
{
cyber2000_outb(reg, 0x3d4);
@@ -46,42 +68,6 @@ static inline void cyber2000_seqw(int reg, int val)
cyber2000_outb(val, 0x3c5);
}
-struct cyber2000fb_par {
- char * screen_base;
- unsigned long screen_base_p;
- unsigned long regs_base;
- unsigned long regs_base_p;
- unsigned long screen_end;
- unsigned long screen_size;
- unsigned int palette_size;
- signed int currcon;
- char dev_name[32];
- struct pci_dev *dev;
- unsigned int dev_id;
- unsigned int initialised:1;
- unsigned int bus_64bit:1;
-
- /*
- * palette
- */
- struct {
- u8 red;
- u8 green;
- u8 blue;
- } palette[256];
- /*
- * colour mapping table
- */
- union {
-#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
- u32 cfb24[16];
-#endif
- } c_table;
-};
-
#define PIXFORMAT_8BPP 0
#define PIXFORMAT_16BPP 1
#define PIXFORMAT_24BPP 2
@@ -140,6 +126,12 @@ struct cyber2000fb_par {
#define CAP_DDA_Y_INIT 0x6c
#define CAP_DDA_Y_INC 0x6e
+#define MEM_CTL2 0x72
+#define MEM_CTL2_SIZE_2MB 0x01
+#define MEM_CTL2_SIZE_4MB 0x02
+#define MEM_CTL2_SIZE_MASK 0x03
+#define MEM_CTL2_64BIT 0x04
+
#define EXT_FIFO_CTL 0x74
#define CAP_PIP_X_START 0x80